Skip to content

Commit b3f2850

Browse files
committed
Change call syntax for static functions
Fixes argotorg#241, argotorg#675
1 parent 4aa56e2 commit b3f2850

18 files changed

Lines changed: 253 additions & 78 deletions

crates/analyzer/src/namespace/items.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ impl Item {
122122
match self {
123123
Item::Ingot(ingot) => ingot.items(db),
124124
Item::Module(module) => module.items(db),
125-
Item::Type(_) => todo!("cannot access items in types yet"),
125+
Item::Type(val) => val.items(db),
126126
Item::GenericType(_)
127127
| Item::Event(_)
128128
| Item::Function(_)
@@ -826,6 +826,29 @@ pub enum TypeDef {
826826
Primitive(types::Base),
827827
}
828828
impl TypeDef {
829+
pub fn items(&self, db: &dyn AnalyzerDb) -> Rc<IndexMap<SmolStr, Item>> {
830+
match self {
831+
TypeDef::Struct(val) => {
832+
Rc::new(
833+
val.functions(db)
834+
.iter()
835+
.filter_map(|(name, field)| {
836+
if field.takes_self(db) {
837+
// In the future we probably want to resolve instance methods as well. But this would require
838+
// the caller to pass an instance as the first argument e.g. `Rectangle::can_hold(self_instance, other)`.
839+
// This isn't yet supported so for now path access to functions is limited to static functions only.
840+
None
841+
} else {
842+
Some((name.to_owned(), Item::Function(*field)))
843+
}
844+
})
845+
.collect(),
846+
)
847+
}
848+
_ => todo!("cannot access items in types yet"),
849+
}
850+
}
851+
829852
pub fn name(&self, db: &dyn AnalyzerDb) -> SmolStr {
830853
match self {
831854
TypeDef::Alias(id) => id.name(db),

crates/analyzer/src/traversal/expressions.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1731,6 +1731,18 @@ fn expr_call_type_attribute(
17311731
)],
17321732
vec![],
17331733
)));
1734+
} else {
1735+
context.fancy_error(
1736+
"Static functions need to be called with `::` not `.`",
1737+
vec![Label::primary(
1738+
field.span,
1739+
"This is a static function (doesn't take a `self` parameter)",
1740+
)],
1741+
vec![format!(
1742+
"Try `{}::{}(...)` instead",
1743+
&class_name, &field.kind
1744+
)],
1745+
);
17341746
}
17351747

17361748
// Returns `true` if the current contract belongs to the same class as an input

crates/analyzer/tests/errors.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ test_file! { call_builtin_object }
238238
test_file! { call_create_with_wrong_type }
239239
test_file! { call_create2_with_wrong_type }
240240
test_file! { call_event_with_wrong_types }
241+
test_file! { call_static_function_without_double_colon }
241242
test_file! { call_undefined_function_on_external_contract }
242243
test_file! { call_undefined_function_on_memory_struct }
243244
test_file! { call_undefined_function_on_storage_struct }

crates/analyzer/tests/snapshots/analysis__associated_fns.snap

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -110,9 +110,9 @@ note:
110110
┌─ associated_fns.fe:14:3
111111
112112
14 │ ╭ pub fn bar(self, val: u256) -> u256:
113-
15 │ │ self.my_struct = MyStruct.new(val)
114-
16 │ │ return Lib.square(self.my_struct.x)
115-
│ ╰───────────────────────────────────────^ attributes hash: 2950430758151367369
113+
15 │ │ self.my_struct = MyStruct::new(x: val)
114+
16 │ │ return Lib::square(x: self.my_struct.x)
115+
│ ╰───────────────────────────────────────────^ attributes hash: 2950430758151367369
116116
117117
= FunctionSignature {
118118
self_decl: Some(
@@ -144,41 +144,41 @@ note:
144144
note:
145145
┌─ associated_fns.fe:15:5
146146
147-
15self.my_struct = MyStruct.new(val)
147+
15self.my_struct = MyStruct::new(x: val)
148148
^^^^ Foo: Value
149149

150150
note:
151151
┌─ associated_fns.fe:15:5
152152
153-
15self.my_struct = MyStruct.new(val)
154-
^^^^^^^^^^^^^^ ^^^ u256: Value
155-
│ │
153+
15self.my_struct = MyStruct::new(x: val)
154+
^^^^^^^^^^^^^^ ^^^ u256: Value
155+
│ │
156156
MyStruct: Storage { nonce: Some(0) }
157157

158158
note:
159159
┌─ associated_fns.fe:15:22
160160
161-
15self.my_struct = MyStruct.new(val)
162-
^^^^^^^^^^^^^^^^^ MyStruct: Memory
163-
16return Lib.square(self.my_struct.x)
164-
^^^^ Foo: Value
161+
15self.my_struct = MyStruct::new(x: val)
162+
^^^^^^^^^^^^^^^^^^^^^ MyStruct: Memory
163+
16return Lib::square(x: self.my_struct.x)
164+
^^^^ Foo: Value
165165

166166
note:
167-
┌─ associated_fns.fe:16:23
167+
┌─ associated_fns.fe:16:27
168168
169-
16return Lib.square(self.my_struct.x)
170-
^^^^^^^^^^^^^^ MyStruct: Storage { nonce: Some(0) }
169+
16return Lib::square(x: self.my_struct.x)
170+
^^^^^^^^^^^^^^ MyStruct: Storage { nonce: Some(0) }
171171

172172
note:
173-
┌─ associated_fns.fe:16:23
173+
┌─ associated_fns.fe:16:27
174174
175-
16return Lib.square(self.my_struct.x)
176-
^^^^^^^^^^^^^^^^ u256: Storage { nonce: Some(0) } => Value
175+
16return Lib::square(x: self.my_struct.x)
176+
^^^^^^^^^^^^^^^^ u256: Storage { nonce: Some(0) } => Value
177177

178178
note:
179179
┌─ associated_fns.fe:16:12
180180
181-
16return Lib.square(self.my_struct.x)
182-
^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u256: Value
181+
16return Lib::square(x: self.my_struct.x)
182+
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ u256: Value
183183

184184

crates/analyzer/tests/snapshots/analysis__basic_ingot.snap

Lines changed: 137 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,61 @@ note:
143143
note:
144144
┌─ ingots/basic_ingot/src/main.fe:23:5
145145
146-
23 │ ╭ pub fn get_my_dyng() -> dong::Dyng:
147-
24 │ │ return dong::Dyng(
148-
25 │ │ my_address: address(8),
149-
26 │ │ my_u256: 42,
150-
27 │ │ my_i8: -1
151-
28 │ │ )
146+
23 │ ╭ pub fn call_on_path():
147+
24 │ │ assert bar::mee::Mee::kawum() == 1
148+
25 │ │ assert bar::mee::Mee().rums() == 1
149+
│ ╰──────────────────────────────────────────^ attributes hash: 8319796915330632390
150+
151+
= FunctionSignature {
152+
self_decl: None,
153+
ctx_decl: None,
154+
params: [],
155+
return_type: Ok(
156+
Base(
157+
Unit,
158+
),
159+
),
160+
}
161+
162+
note:
163+
┌─ ingots/basic_ingot/src/main.fe:24:16
164+
165+
24assert bar::mee::Mee::kawum() == 1
166+
^^^^^^^^^^^^^^^^^^^^^^ ^ u256: Value
167+
│ │
168+
u256: Value
169+
170+
note:
171+
┌─ ingots/basic_ingot/src/main.fe:24:16
172+
173+
24assert bar::mee::Mee::kawum() == 1
174+
^^^^^^^^^^^^^^^^^^^^^^^^^^^ bool: Value
175+
25assert bar::mee::Mee().rums() == 1
176+
^^^^^^^^^^^^^^^ Mee: Memory
177+
178+
note:
179+
┌─ ingots/basic_ingot/src/main.fe:25:16
180+
181+
25assert bar::mee::Mee().rums() == 1
182+
^^^^^^^^^^^^^^^^^^^^^^ ^ u256: Value
183+
│ │
184+
u256: Value
185+
186+
note:
187+
┌─ ingots/basic_ingot/src/main.fe:25:16
188+
189+
25assert bar::mee::Mee().rums() == 1
190+
^^^^^^^^^^^^^^^^^^^^^^^^^^^ bool: Value
191+
192+
note:
193+
┌─ ingots/basic_ingot/src/main.fe:27:5
194+
195+
27 │ ╭ pub fn get_my_dyng() -> dong::Dyng:
196+
28 │ │ return dong::Dyng(
197+
29 │ │ my_address: address(8),
198+
30 │ │ my_u256: 42,
199+
31 │ │ my_i8: -1
200+
32 │ │ )
152201
│ ╰─────────^ attributes hash: 13186223862505072309
153202
154203
= FunctionSignature {
@@ -166,44 +215,44 @@ note:
166215
}
167216

168217
note:
169-
┌─ ingots/basic_ingot/src/main.fe:25:33
218+
┌─ ingots/basic_ingot/src/main.fe:29:33
170219
171-
25my_address: address(8),
220+
29my_address: address(8),
172221
^ u256: Value
173222

174223
note:
175-
┌─ ingots/basic_ingot/src/main.fe:25:25
224+
┌─ ingots/basic_ingot/src/main.fe:29:25
176225
177-
25my_address: address(8),
226+
29my_address: address(8),
178227
^^^^^^^^^^ address: Value
179-
26my_u256: 42,
228+
30my_u256: 42,
180229
^^ u256: Value
181-
27my_i8: -1
230+
31my_i8: -1
182231
^ u256: Value
183232

184233
note:
185-
┌─ ingots/basic_ingot/src/main.fe:27:20
234+
┌─ ingots/basic_ingot/src/main.fe:31:20
186235
187-
27my_i8: -1
236+
31my_i8: -1
188237
^^ i8: Value
189238

190239
note:
191-
┌─ ingots/basic_ingot/src/main.fe:24:16
240+
┌─ ingots/basic_ingot/src/main.fe:28:16
192241
193-
24return dong::Dyng(
242+
28return dong::Dyng(
194243
│ ╭────────────────^
195-
25 │ │ my_address: address(8),
196-
26 │ │ my_u256: 42,
197-
27 │ │ my_i8: -1
198-
28 │ │ )
244+
29 │ │ my_address: address(8),
245+
30 │ │ my_u256: 42,
246+
31 │ │ my_i8: -1
247+
32 │ │ )
199248
│ ╰─────────^ Dyng: Memory
200249

201250
note:
202-
┌─ ingots/basic_ingot/src/main.fe:30:5
251+
┌─ ingots/basic_ingot/src/main.fe:34:5
203252
204-
30 │ ╭ pub fn create_bing_contract(ctx: Context) -> u256:
205-
31 │ │ let bing_contract: BingContract = BingContract.create(ctx, 0)
206-
32 │ │ return bing_contract.add(40, 50)
253+
34 │ ╭ pub fn create_bing_contract(ctx: Context) -> u256:
254+
35 │ │ let bing_contract: BingContract = BingContract.create(ctx, 0)
255+
36 │ │ return bing_contract.add(40, 50)
207256
│ ╰────────────────────────────────────────^ attributes hash: 10526263819290319263
208257
209258
= FunctionSignature {
@@ -235,34 +284,34 @@ note:
235284
}
236285

237286
note:
238-
┌─ ingots/basic_ingot/src/main.fe:31:28
287+
┌─ ingots/basic_ingot/src/main.fe:35:28
239288
240-
31let bing_contract: BingContract = BingContract.create(ctx, 0)
289+
35let bing_contract: BingContract = BingContract.create(ctx, 0)
241290
^^^^^^^^^^^^ BingContract
242291

243292
note:
244-
┌─ ingots/basic_ingot/src/main.fe:31:63
293+
┌─ ingots/basic_ingot/src/main.fe:35:63
245294
246-
31let bing_contract: BingContract = BingContract.create(ctx, 0)
295+
35let bing_contract: BingContract = BingContract.create(ctx, 0)
247296
^^^ ^ u256: Value
248297
│ │
249298
Context: Memory
250299

251300
note:
252-
┌─ ingots/basic_ingot/src/main.fe:31:43
301+
┌─ ingots/basic_ingot/src/main.fe:35:43
253302
254-
31let bing_contract: BingContract = BingContract.create(ctx, 0)
303+
35let bing_contract: BingContract = BingContract.create(ctx, 0)
255304
^^^^^^^^^^^^^^^^^^^^^^^^^^^ BingContract: Value
256-
32return bing_contract.add(40, 50)
305+
36return bing_contract.add(40, 50)
257306
^^^^^^^^^^^^^ ^^ ^^ u256: Value
258307
│ │ │
259308
│ │ u256: Value
260309
BingContract: Value
261310

262311
note:
263-
┌─ ingots/basic_ingot/src/main.fe:32:16
312+
┌─ ingots/basic_ingot/src/main.fe:36:16
264313
265-
32return bing_contract.add(40, 50)
314+
36return bing_contract.add(40, 50)
266315
^^^^^^^^^^^^^^^^^^^^^^^^^ u256: Value
267316

268317

@@ -403,6 +452,61 @@ note:
403452
^^^^^^^^^^^^^^^^^ u256
404453

405454

455+
note:
456+
┌─ ingots/basic_ingot/src/bar/mee.fe:2:5
457+
458+
2 │ ╭ pub fn kawum() -> u256:
459+
3 │ │ return 1
460+
│ ╰────────────────^ attributes hash: 6115314201970082834
461+
462+
= FunctionSignature {
463+
self_decl: None,
464+
ctx_decl: None,
465+
params: [],
466+
return_type: Ok(
467+
Base(
468+
Numeric(
469+
U256,
470+
),
471+
),
472+
),
473+
}
474+
475+
note:
476+
┌─ ingots/basic_ingot/src/bar/mee.fe:3:16
477+
478+
3return 1
479+
^ u256: Value
480+
481+
note:
482+
┌─ ingots/basic_ingot/src/bar/mee.fe:5:5
483+
484+
5 │ ╭ pub fn rums(self) -> u256:
485+
6 │ │ return 1
486+
│ ╰────────────────^ attributes hash: 11773348765973600208
487+
488+
= FunctionSignature {
489+
self_decl: Some(
490+
Mutable,
491+
),
492+
ctx_decl: None,
493+
params: [],
494+
return_type: Ok(
495+
Base(
496+
Numeric(
497+
U256,
498+
),
499+
),
500+
),
501+
}
502+
503+
note:
504+
┌─ ingots/basic_ingot/src/bar/mee.fe:6:16
505+
506+
6return 1
507+
^ u256: Value
508+
509+
406510
note:
407511
┌─ ingots/basic_ingot/src/ding/dang.fe:1:1
408512

0 commit comments

Comments
 (0)