Skip to content

Commit

Permalink
Resolve output types in function calls and new expressions
Browse files Browse the repository at this point in the history
  • Loading branch information
ggiraldez committed Aug 31, 2024
1 parent 8e84b6b commit c3c45ff
Show file tree
Hide file tree
Showing 8 changed files with 218 additions and 34 deletions.
56 changes: 39 additions & 17 deletions crates/solidity/inputs/language/bindings/rules.msgb
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,21 @@ attribute symbol_reference = symbol => type = "push_symbol", symbol = symbol, i
edge @contract.def -> def

;; "instance" like access path
node type_def
attr (type_def) pop_symbol = "@typeof"
;; we have two distinct paths: @typeof -> . for accesses to variables of the contract's type
;; and () -> . for accesses through a `new` invocation
node member
attr (member) pop_symbol = "."
edge member -> @contract.members

node type_def
attr (type_def) pop_symbol = "@typeof"
edge def -> type_def
edge type_def -> member
edge member -> @contract.members

node call
attr (call) pop_symbol = "()"
edge def -> call
edge call -> member

;; "namespace" like access path
node type_member
Expand Down Expand Up @@ -522,27 +530,22 @@ attribute symbol_reference = symbol => type = "push_symbol", symbol = symbol, i
;;; Function, parameter declarations and modifiers
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@param [Parameter] {
@param [Parameter @type_name [TypeName]] {
node @param.lexical_scope
node @param.def
}

@param [Parameter @type_name [TypeName]] {
edge @type_name.type_ref -> @param.lexical_scope
}

@param [Parameter @type_name [TypeName] @name [Identifier]] {
node def
attr (def) node_definition = @name
attr (def) definiens_node = @param

edge @param.def -> def
node @param.typeof
attr (@param.typeof) push_symbol = "@typeof"
edge @param.typeof -> @type_name.output
}

node typeof
attr (typeof) push_symbol = "@typeof"
@param [Parameter @name [Identifier]] {
attr (@param.def) node_definition = @name
attr (@param.def) definiens_node = @param

edge def -> typeof
edge typeof -> @type_name.output
edge @param.def -> @param.typeof
}

@params [ParametersDeclaration] {
Expand Down Expand Up @@ -591,6 +594,18 @@ attribute symbol_reference = symbol => type = "push_symbol", symbol = symbol, i
attr (@function.lexical_scope -> @return_params.defs) precedence = 1
}

;; Only functions that return a single value have an actual return type
;; since tuples are not actual types in Solidity
@function [FunctionDefinition returns: [ReturnsDeclaration
[ParametersDeclaration [Parameters . @param [Parameter] .]]
]] {
node call
attr (call) pop_symbol = "()"

edge @function.def -> call
edge call -> @param.typeof
}

;; Connect the function body's block lexical scope to the function
@function [FunctionDefinition [FunctionBody @block [Block]]] {
edge @block.lexical_scope -> @function.lexical_scope
Expand Down Expand Up @@ -1341,6 +1356,13 @@ attribute symbol_reference = symbol => type = "push_symbol", symbol = symbol, i
edge @type.type_ref -> @type_expr.lexical_scope
}

;; New expressions

@new_expr [Expression [NewExpression @type [TypeName]]] {
edge @type.type_ref -> @new_expr.lexical_scope
edge @new_expr.output -> @type.output
}


;;; Function call expressions

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
contract Test {
struct Resource {
uint value;
// ^def:1
}

function test_call_output() public returns (uint) {
return get_resource().value;
// ^ref:1
// ^ref:2
}

function get_resource() internal returns (Resource memory) {
// ^def:2
return Resource(1);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
contract Test {
function test_new_output() public returns (uint) {
return new Container().cell().value;
// ^ref:2
// ^ref:3
// ^ref:1
}
}

contract Container {
// ^def:1
struct Resource {
uint value;
// ^def:2
}

function cell() public returns (Resource memory) { return Resource(1); }
// ^def:3
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# This file is generated automatically by infrastructure scripts. Please don't edit by hand.

References and definitions:
╭─[input.sol:1:1]
1 │ contract Test {
│ ──┬─
│ ╰─── def: 1
2 │ function test_new() public returns (uint) {
│ ────┬───
│ ╰───── def: 2
3 │ return new Container().cell().value;
│ ────┬──── ──┬─ ──┬──
│ ╰───────────────────── ref: 4
│ │ │
│ ╰─────────── ref: 5
│ │
│ ╰──── ref: 8
5 │ function test_call() public returns (uint) {
│ ────┬────
│ ╰────── def: 3
6 │ return Utils.create().value;
│ ──┬── ───┬── ──┬──
│ ╰─────────────────── ref: 6
│ │ │
│ ╰──────────── ref: 9
│ │
│ ╰──── ref: 8
10 │ contract Container {
│ ────┬────
│ ╰────── def: 4
11 │ function cell() public returns (Utils.Resource memory) {
│ ──┬─ ──┬── ────┬───
│ ╰──────────────────────────────────── def: 5
│ │ │
│ ╰───────────── ref: 6
│ │
│ ╰───── ref: 7
12 │ return Utils.create();
│ ──┬── ───┬──
│ ╰─────────── ref: 6
│ │
│ ╰──── ref: 9
16 │ library Utils {
│ ──┬──
│ ╰──── def: 6
17 │ struct Resource {
│ ────┬───
│ ╰───── def: 7
18 │ uint value;
│ ──┬──
│ ╰──── def: 8
21 │ function create() public returns (Resource memory) {
│ ───┬── ────┬───
│ ╰─────────────────────────────── def: 9
│ │
│ ╰───── ref: 7
22 │ return Resource(1);
│ ────┬───
│ ╰───── ref: 7
────╯
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
contract Test {
function test_new() public returns (uint) {
return new Container().cell().value;
}
function test_call() public returns (uint) {
return Utils.create().value;
}
}

contract Container {
function cell() public returns (Utils.Resource memory) {
return Utils.create();
}
}

library Utils {
struct Resource {
uint value;
}

function create() public returns (Resource memory) {
return Resource(1);
}
}

0 comments on commit c3c45ff

Please sign in to comment.