Skip to content

Commit

Permalink
Add binding rules for arrays, mappings and other types (#1082)
Browse files Browse the repository at this point in the history
This PR adds binding rules to allow support name resolution of:
- Top-level constants (contract/library/interface constants were already
supported because they are parsed as state variables)
- Mappings: both resolving key and value types as well as computing the
result type of indexing
- Arrays: same as above; missing support for array type members, which
will be covered when we implement built-ins support
- User defined value types; same as above to member functions
- Function types; ditto
  • Loading branch information
ggiraldez authored Aug 21, 2024
1 parent b1afb08 commit d223865
Show file tree
Hide file tree
Showing 25 changed files with 868 additions and 8 deletions.
148 changes: 145 additions & 3 deletions crates/solidity/inputs/language/bindings/rules.msgb
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ attribute symbol_reference = symbol => type = "push_symbol", symbol = symbol, i
| [StructDefinition]
| [EventDefinition]
| [ErrorDefinition]
| [UserDefinedValueTypeDefinition]
)]
]] {
edge @member.lexical_scope -> @contract.lexical_scope
Expand Down Expand Up @@ -280,6 +281,7 @@ attribute symbol_reference = symbol => type = "push_symbol", symbol = symbol, i
| [StructDefinition]
| [EventDefinition]
| [ErrorDefinition]
| [UserDefinedValueTypeDefinition]
)]
]] {
edge @member.lexical_scope -> @interface.lexical_scope
Expand Down Expand Up @@ -327,6 +329,7 @@ attribute symbol_reference = symbol => type = "push_symbol", symbol = symbol, i
| [StructDefinition]
| [EventDefinition]
| [ErrorDefinition]
| [UserDefinedValueTypeDefinition]
)]
]] {
edge @member.lexical_scope -> @library.lexical_scope
Expand Down Expand Up @@ -358,6 +361,111 @@ attribute symbol_reference = symbol => type = "push_symbol", symbol = symbol, i
edge @type_name.output -> @id_path.right
}

@type_name [TypeName @mapping [MappingType]] {
edge @mapping.lexical_scope -> @type_name.type_ref
edge @type_name.output -> @mapping.output
}

@type_name [TypeName @array [ArrayTypeName]] {
edge @array.lexical_scope -> @type_name.type_ref
edge @type_name.output -> @array.output
}

@type_name [TypeName @ftype [FunctionType]] {
edge @ftype.lexical_scope -> @type_name.type_ref
edge @type_name.output -> @ftype.output
}


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Mappings
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@mapping [MappingType] {
node @mapping.lexical_scope
node @mapping.output
}

@mapping [MappingType [MappingKey [MappingKeyType @key_ident [IdentifierPath]]]] {
edge @key_ident.left -> @mapping.lexical_scope
}

@mapping [MappingType [MappingValue @value_type [TypeName]]] {
edge @value_type.type_ref -> @mapping.lexical_scope

node typeof_input
attr (typeof_input) pop_symbol = "@typeof"

node index
attr (index) pop_symbol = "[]"

node typeof_output
attr (typeof_output) push_symbol = "@typeof"

;; The mapping's type exposes the `[]` operator that returns the value type
edge @mapping.output -> typeof_input
edge typeof_input -> index
edge index -> typeof_output
edge typeof_output -> @value_type.output
}


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Arrays types
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@array [ArrayTypeName] {
node @array.lexical_scope
node @array.output
}

@array [ArrayTypeName @type_name [TypeName]] {
edge @type_name.type_ref -> @array.lexical_scope

node typeof_input
attr (typeof_input) pop_symbol = "@typeof"

node index
attr (index) pop_symbol = "[]"

node typeof_output
attr (typeof_output) push_symbol = "@typeof"

;; The array type exposes the `[]` operator that returns the value type
edge @array.output -> typeof_input
edge typeof_input -> index
edge index -> typeof_output
edge typeof_output -> @type_name.output
}

@array [ArrayTypeName @size index: [Expression]] {
edge @size.lexical_scope -> @array.lexical_scope
}


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Function types
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

@ftype [FunctionType] {
node @ftype.lexical_scope
node @ftype.output
}

@ftype [FunctionType @params [ParametersDeclaration]] {
edge @params.lexical_scope -> @ftype.lexical_scope
}

@ftype [FunctionType [ReturnsDeclaration @return_params [ParametersDeclaration]]] {
edge @return_params.lexical_scope -> @ftype.lexical_scope
}



;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; Identifier Paths (aka. references to custom types)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; The identifier path constructs a path of nodes connected from right to left
@id_path [IdentifierPath] {
node @id_path.left
Expand Down Expand Up @@ -970,9 +1078,32 @@ attribute symbol_reference = symbol => type = "push_symbol", symbol = symbol, i
node @constant.def
}

@value_type [UserDefinedValueTypeDefinition] {
node @value_type.lexical_scope
node @value_type.def
@constant [ConstantDefinition
@type_name type_name: [TypeName]
@name name: [Identifier]
@value value: [Expression]
] {
node def
attr (def) node_definition = @name
attr (def) definiens_node = @constant

edge @constant.def -> def

edge @value.lexical_scope -> @constant.lexical_scope
edge @type_name.type_ref -> @constant.lexical_scope
}

@user_type [UserDefinedValueTypeDefinition] {
node @user_type.lexical_scope
node @user_type.def
}

@user_type [UserDefinedValueTypeDefinition @name [Identifier]] {
node def
attr (def) node_definition = @name
attr (def) definiens_node = @user_type

edge @user_type.def -> def
}


Expand Down Expand Up @@ -1024,6 +1155,17 @@ attribute symbol_reference = symbol => type = "push_symbol", symbol = symbol, i
edge @expr.output -> ref
}

;; Index access expressions
@expr [Expression [IndexAccessExpression
@operand operand: [Expression]
]] {
node index
attr (index) push_symbol = "[]"

edge @expr.output -> index
edge index -> @operand.output
}

;; Type expressions
@type_expr [Expression [TypeExpression @type [TypeName]]] {
edge @type.type_ref -> @type_expr.lexical_scope
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.

Loading

0 comments on commit d223865

Please sign in to comment.