Skip to content

Commit

Permalink
Change call syntax for static functions
Browse files Browse the repository at this point in the history
  • Loading branch information
cburgdorf committed May 3, 2022
1 parent 4aa56e2 commit 48c0f67
Show file tree
Hide file tree
Showing 18 changed files with 253 additions and 79 deletions.
25 changes: 24 additions & 1 deletion crates/analyzer/src/namespace/items.rs
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ impl Item {
match self {
Item::Ingot(ingot) => ingot.items(db),
Item::Module(module) => module.items(db),
Item::Type(_) => todo!("cannot access items in types yet"),
Item::Type(val) => val.items(db),
Item::GenericType(_)
| Item::Event(_)
| Item::Function(_)
Expand Down Expand Up @@ -826,6 +826,29 @@ pub enum TypeDef {
Primitive(types::Base),
}
impl TypeDef {
pub fn items(&self, db: &dyn AnalyzerDb) -> Rc<IndexMap<SmolStr, Item>> {
match self {
TypeDef::Struct(val) => {
Rc::new(
val.functions(db)
.iter()
.filter_map(|(name, field)| {
if field.takes_self(db) {
// In the future we probably want to resolve instance methods as well. But this would require
// the caller to pass an instance as the first argument e.g. `Rectangle::can_hold(self_instance, other)`.
// This isn't yet supported so for now path access to functions is limited to static functions only.
None
} else {
Some((name.to_owned(), Item::Function(*field)))
}
})
.collect(),
)
}
_ => todo!("cannot access items in types yet"),
}
}

pub fn name(&self, db: &dyn AnalyzerDb) -> SmolStr {
match self {
TypeDef::Alias(id) => id.name(db),
Expand Down
13 changes: 12 additions & 1 deletion crates/analyzer/src/traversal/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,6 @@ fn expr_path(
fe::Expr::Path(path) => path,
_ => unreachable!(),
};

let named_thing = context.resolve_path(path, exp.span);
expr_named_thing(context, exp, named_thing, expected_type)
}
Expand Down Expand Up @@ -1731,6 +1730,18 @@ fn expr_call_type_attribute(
)],
vec![],
)));
} else {
context.fancy_error(
"Static functions need to be called with `::` not `.`",
vec![Label::primary(
field.span,
"This is a static function (doesn't take a `self` parameter)",
)],
vec![format!(
"Try `{}::{}(...)` instead",
&class_name, &field.kind
)],
);
}

// Returns `true` if the current contract belongs to the same class as an input
Expand Down
1 change: 1 addition & 0 deletions crates/analyzer/tests/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ test_file! { call_builtin_object }
test_file! { call_create_with_wrong_type }
test_file! { call_create2_with_wrong_type }
test_file! { call_event_with_wrong_types }
test_file! { call_static_function_without_double_colon }
test_file! { call_undefined_function_on_external_contract }
test_file! { call_undefined_function_on_memory_struct }
test_file! { call_undefined_function_on_storage_struct }
Expand Down
38 changes: 19 additions & 19 deletions crates/analyzer/tests/snapshots/analysis__associated_fns.snap
Original file line number Diff line number Diff line change
Expand Up @@ -110,9 +110,9 @@ note:
┌─ associated_fns.fe:14:3
14 │ ╭ pub fn bar(self, val: u256) -> u256:
15 │ │ self.my_struct = MyStruct.new(val)
16 │ │ return Lib.square(self.my_struct.x)
│ ╰───────────────────────────────────────^ attributes hash: 2950430758151367369
15 │ │ self.my_struct = MyStruct::new(x: val)
16 │ │ return Lib::square(x: self.my_struct.x)
│ ╰───────────────────────────────────────────^ attributes hash: 2950430758151367369
= FunctionSignature {
self_decl: Some(
Expand Down Expand Up @@ -144,41 +144,41 @@ note:
note:
┌─ associated_fns.fe:15:5
15self.my_struct = MyStruct.new(val)
15self.my_struct = MyStruct::new(x: val)
^^^^ Foo: Value

note:
┌─ associated_fns.fe:15:5
15self.my_struct = MyStruct.new(val)
^^^^^^^^^^^^^^ ^^^ u256: Value
│ │
15self.my_struct = MyStruct::new(x: val)
^^^^^^^^^^^^^^ ^^^ u256: Value
│ │
MyStruct: Storage { nonce: Some(0) }

note:
┌─ associated_fns.fe:15:22
15self.my_struct = MyStruct.new(val)
^^^^^^^^^^^^^^^^^ MyStruct: Memory
16return Lib.square(self.my_struct.x)
^^^^ Foo: Value
15self.my_struct = MyStruct::new(x: val)
^^^^^^^^^^^^^^^^^^^^^ MyStruct: Memory
16return Lib::square(x: self.my_struct.x)
^^^^ Foo: Value

note:
┌─ associated_fns.fe:16:23
┌─ associated_fns.fe:16:27
16return Lib.square(self.my_struct.x)
^^^^^^^^^^^^^^ MyStruct: Storage { nonce: Some(0) }
16return Lib::square(x: self.my_struct.x)
^^^^^^^^^^^^^^ MyStruct: Storage { nonce: Some(0) }

note:
┌─ associated_fns.fe:16:23
┌─ associated_fns.fe:16:27
16return Lib.square(self.my_struct.x)
^^^^^^^^^^^^^^^^ u256: Storage { nonce: Some(0) } => Value
16return Lib::square(x: self.my_struct.x)
^^^^^^^^^^^^^^^^ u256: Storage { nonce: Some(0) } => Value

note:
┌─ associated_fns.fe:16:12
16return Lib.square(self.my_struct.x)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u256: Value
16return Lib::square(x: self.my_struct.x)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u256: Value


170 changes: 137 additions & 33 deletions crates/analyzer/tests/snapshots/analysis__basic_ingot.snap
Original file line number Diff line number Diff line change
Expand Up @@ -143,12 +143,61 @@ note:
note:
┌─ ingots/basic_ingot/src/main.fe:23:5
23 │ ╭ pub fn get_my_dyng() -> dong::Dyng:
24 │ │ return dong::Dyng(
25 │ │ my_address: address(8),
26 │ │ my_u256: 42,
27 │ │ my_i8: -1
28 │ │ )
23 │ ╭ pub fn call_on_path():
24 │ │ assert bar::mee::Mee::kawum() == 1
25 │ │ assert bar::mee::Mee().rums() == 1
│ ╰──────────────────────────────────────────^ attributes hash: 8319796915330632390
= FunctionSignature {
self_decl: None,
ctx_decl: None,
params: [],
return_type: Ok(
Base(
Unit,
),
),
}

note:
┌─ ingots/basic_ingot/src/main.fe:24:16
24assert bar::mee::Mee::kawum() == 1
^^^^^^^^^^^^^^^^^^^^^^ ^ u256: Value
│ │
u256: Value

note:
┌─ ingots/basic_ingot/src/main.fe:24:16
24assert bar::mee::Mee::kawum() == 1
^^^^^^^^^^^^^^^^^^^^^^^^^^^ bool: Value
25assert bar::mee::Mee().rums() == 1
^^^^^^^^^^^^^^^ Mee: Memory

note:
┌─ ingots/basic_ingot/src/main.fe:25:16
25assert bar::mee::Mee().rums() == 1
^^^^^^^^^^^^^^^^^^^^^^ ^ u256: Value
│ │
u256: Value

note:
┌─ ingots/basic_ingot/src/main.fe:25:16
25assert bar::mee::Mee().rums() == 1
^^^^^^^^^^^^^^^^^^^^^^^^^^^ bool: Value

note:
┌─ ingots/basic_ingot/src/main.fe:27:5
27 │ ╭ pub fn get_my_dyng() -> dong::Dyng:
28 │ │ return dong::Dyng(
29 │ │ my_address: address(8),
30 │ │ my_u256: 42,
31 │ │ my_i8: -1
32 │ │ )
│ ╰─────────^ attributes hash: 13186223862505072309
= FunctionSignature {
Expand All @@ -166,44 +215,44 @@ note:
}

note:
┌─ ingots/basic_ingot/src/main.fe:25:33
┌─ ingots/basic_ingot/src/main.fe:29:33
25my_address: address(8),
29my_address: address(8),
^ u256: Value

note:
┌─ ingots/basic_ingot/src/main.fe:25:25
┌─ ingots/basic_ingot/src/main.fe:29:25
25my_address: address(8),
29my_address: address(8),
^^^^^^^^^^ address: Value
26my_u256: 42,
30my_u256: 42,
^^ u256: Value
27my_i8: -1
31my_i8: -1
^ u256: Value

note:
┌─ ingots/basic_ingot/src/main.fe:27:20
┌─ ingots/basic_ingot/src/main.fe:31:20
27my_i8: -1
31my_i8: -1
^^ i8: Value

note:
┌─ ingots/basic_ingot/src/main.fe:24:16
┌─ ingots/basic_ingot/src/main.fe:28:16
24return dong::Dyng(
28return dong::Dyng(
│ ╭────────────────^
25 │ │ my_address: address(8),
26 │ │ my_u256: 42,
27 │ │ my_i8: -1
28 │ │ )
29 │ │ my_address: address(8),
30 │ │ my_u256: 42,
31 │ │ my_i8: -1
32 │ │ )
│ ╰─────────^ Dyng: Memory

note:
┌─ ingots/basic_ingot/src/main.fe:30:5
┌─ ingots/basic_ingot/src/main.fe:34:5
30 │ ╭ pub fn create_bing_contract(ctx: Context) -> u256:
31 │ │ let bing_contract: BingContract = BingContract.create(ctx, 0)
32 │ │ return bing_contract.add(40, 50)
34 │ ╭ pub fn create_bing_contract(ctx: Context) -> u256:
35 │ │ let bing_contract: BingContract = BingContract.create(ctx, 0)
36 │ │ return bing_contract.add(40, 50)
│ ╰────────────────────────────────────────^ attributes hash: 10526263819290319263
= FunctionSignature {
Expand Down Expand Up @@ -235,34 +284,34 @@ note:
}

note:
┌─ ingots/basic_ingot/src/main.fe:31:28
┌─ ingots/basic_ingot/src/main.fe:35:28
31let bing_contract: BingContract = BingContract.create(ctx, 0)
35let bing_contract: BingContract = BingContract.create(ctx, 0)
^^^^^^^^^^^^ BingContract

note:
┌─ ingots/basic_ingot/src/main.fe:31:63
┌─ ingots/basic_ingot/src/main.fe:35:63
31let bing_contract: BingContract = BingContract.create(ctx, 0)
35let bing_contract: BingContract = BingContract.create(ctx, 0)
^^^ ^ u256: Value
│ │
Context: Memory

note:
┌─ ingots/basic_ingot/src/main.fe:31:43
┌─ ingots/basic_ingot/src/main.fe:35:43
31let bing_contract: BingContract = BingContract.create(ctx, 0)
35let bing_contract: BingContract = BingContract.create(ctx, 0)
^^^^^^^^^^^^^^^^^^^^^^^^^^^ BingContract: Value
32return bing_contract.add(40, 50)
36return bing_contract.add(40, 50)
^^^^^^^^^^^^^ ^^ ^^ u256: Value
│ │ │
│ │ u256: Value
BingContract: Value

note:
┌─ ingots/basic_ingot/src/main.fe:32:16
┌─ ingots/basic_ingot/src/main.fe:36:16
32return bing_contract.add(40, 50)
36return bing_contract.add(40, 50)
^^^^^^^^^^^^^^^^^^^^^^^^^ u256: Value


Expand Down Expand Up @@ -403,6 +452,61 @@ note:
^^^^^^^^^^^^^^^^^ u256


note:
┌─ ingots/basic_ingot/src/bar/mee.fe:2:5
2 │ ╭ pub fn kawum() -> u256:
3 │ │ return 1
│ ╰────────────────^ attributes hash: 6115314201970082834
= FunctionSignature {
self_decl: None,
ctx_decl: None,
params: [],
return_type: Ok(
Base(
Numeric(
U256,
),
),
),
}

note:
┌─ ingots/basic_ingot/src/bar/mee.fe:3:16
3return 1
^ u256: Value

note:
┌─ ingots/basic_ingot/src/bar/mee.fe:5:5
5 │ ╭ pub fn rums(self) -> u256:
6 │ │ return 1
│ ╰────────────────^ attributes hash: 11773348765973600208
= FunctionSignature {
self_decl: Some(
Mutable,
),
ctx_decl: None,
params: [],
return_type: Ok(
Base(
Numeric(
U256,
),
),
),
}

note:
┌─ ingots/basic_ingot/src/bar/mee.fe:6:16
6return 1
^ u256: Value


note:
┌─ ingots/basic_ingot/src/ding/dang.fe:1:1
Expand Down
Loading

0 comments on commit 48c0f67

Please sign in to comment.