diff --git a/crates/solidity/inputs/language/bindings/rules.msgb b/crates/solidity/inputs/language/bindings/rules.msgb index d727843a21..7c92611c9e 100644 --- a/crates/solidity/inputs/language/bindings/rules.msgb +++ b/crates/solidity/inputs/language/bindings/rules.msgb @@ -52,6 +52,18 @@ inherit .enclosing_def edge @source_unit.defs -> @unit_member.def } +@source_unit [SourceUnit [SourceUnitMembers [SourceUnitMember @using [UsingDirective]]]] { + let @using.lexical_scope = @source_unit.lexical_scope + edge @source_unit.lexical_scope -> @using.def +} + +@source_unit [SourceUnit [SourceUnitMembers [SourceUnitMember + @using [UsingDirective [GlobalKeyword]] +]]] { + ; global using directives are exported by this source unit + edge @source_unit.defs -> @using.def +} + ;; ... and imports @source_unit [SourceUnit [SourceUnitMembers [SourceUnitMember [ImportDirective @@ -269,7 +281,7 @@ inherit .enclosing_def ]]] { ;; Resolve contract bases names through the parent scope of the contract (aka ;; the source unit) - edge @type_name.left -> @contract.parent_scope + edge @type_name.push_end -> @contract.parent_scope ;; Make base members accesible as our own members node member @@ -280,21 +292,21 @@ inherit .enclosing_def edge @contract.members -> member edge member -> typeof - edge typeof -> @type_name.right + edge typeof -> @type_name.push_begin ;; Make base contract defs (eg. enums and structs) accessible as our own node type_member attr (type_member) push_symbol = "." edge @contract.type_members -> type_member - edge type_member -> @type_name.right + edge type_member -> @type_name.push_begin ;; The base contract defs are directly accesible through our special super scope - edge @contract.super_scope -> @type_name.right + edge @contract.super_scope -> @type_name.push_begin } @parent [InheritanceType @type_name [IdentifierPath]] { - let @parent.ref = @type_name.ref + let @parent.ref = @type_name.push_begin } ;; NOTE: we use anchors here to prevent the query engine from returning all the @@ -329,6 +341,13 @@ inherit .enclosing_def edge @member.lexical_scope -> @contract.lexical_scope } +@contract [ContractDefinition [ContractMembers + [ContractMember @using [UsingDirective]] +]] { + let @using.lexical_scope = @contract.lexical_scope + edge @contract.lexical_scope -> @using.def +} + @contract [ContractDefinition [ContractMembers [ContractMember @member ( [EnumDefinition] @@ -377,7 +396,7 @@ inherit .enclosing_def ]]] ]]] { ;; Resolve overriden bases when listed in the function modifiers - edge @base_ident.left -> @contract.parent_scope + edge @base_ident.push_end -> @contract.parent_scope } @@ -438,6 +457,13 @@ inherit .enclosing_def edge @interface.members -> @function.def } +[InterfaceDefinition [InterfaceMembers [ContractMember @using [UsingDirective]]]] { + ; using directives are not allowed in interfaces, but the grammar allows them + ; so we need to create an artificial node here to connect to created edges from + ; the internal nodes + let @using.lexical_scope = (node) +} + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Libraries @@ -479,44 +505,158 @@ inherit .enclosing_def edge @library.members -> @member.def } +@library [LibraryDefinition [LibraryMembers + [ContractMember @using [UsingDirective]] +]] { + let @using.lexical_scope = @library.lexical_scope + edge @library.lexical_scope -> @using.def +} + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Using directives +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; The UsingDirective node requires the enclosing context to setup a +;; .lexical_scope scoped variable for it to resolve both targets and subjects. + +@using [UsingDirective] { + ; This node acts as a definition in the sense that provides an entry point + ; that pops the target type and pushes the library/functions to attach to the + ; target type + node @using.def + + ; This internal node connects the other end of the popping path starting at + ; .def and resolves for the library/functions in the directive + node @using.clause +} + +@using [UsingDirective [UsingClause @id_path [IdentifierPath]]] { + ; resolve the library to be used in the directive + edge @id_path.push_end -> @using.lexical_scope + + ; because we're using the whole library, we don't need to "consume" the + ; attached function (as when using the deconstruction syntax), but we still + ; need to verify that we're only using this path when resolving a function + ; access to the target type, not the target type itself + node dot_guard_pop + attr (dot_guard_pop) pop_symbol = "." + node dot_guard_push + attr (dot_guard_push) push_symbol = "." + + edge @using.clause -> dot_guard_pop + edge dot_guard_pop -> dot_guard_push + edge dot_guard_push -> @id_path.push_begin +} + +@using [UsingDirective [UsingClause [UsingDeconstruction + [UsingDeconstructionSymbols [UsingDeconstructionSymbol + @id_path [IdentifierPath] + ]] +]]] { + ; resolve the function to be used in the directive + edge @id_path.push_end -> @using.lexical_scope + + node dot + attr (dot) pop_symbol = "." + node last_identifier + attr (last_identifier) pop_symbol = (source-text @id_path.rightmost_identifier) + + edge @using.clause -> dot + edge dot -> last_identifier + edge last_identifier -> @id_path.push_begin +} + +@using [UsingDirective [UsingTarget @type_name [TypeName]]] { + ; pop the type symbols to connect to the attached function (via @using.clause) + node typeof + attr (typeof) pop_symbol = "@typeof" + + edge @using.def -> @type_name.pop_begin + edge @type_name.pop_end -> typeof + edge typeof -> @using.clause + + ; resolve the target type of the directive + edge @type_name.type_ref -> @using.lexical_scope +} + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Type names ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -@type_name [TypeName] { - ;; This node should connect to the parent lexical scope to resolve the type - node @type_name.type_ref +;; TypeName nodes should define two scoped variables: +;; +;; - @type_name.type_ref represents the node in the graph where we're ready to +;; resolve the type, and thus should generally be connected to a (lexical) +;; scope node (source node, outside edges connect *from* here). +;; +;; - @type_name.output represents the other end of the type and corresponds to a +;; state where the type has already been resolved so we can, for example +;; resolve its members (sink node, outside edges connect *to* here). - ;; This represents the output of the type, ie. the node to which a variable - ;; that is of this type should connect through a @typeof node - node @type_name.output +@type_name [TypeName @elementary [ElementaryType]] { + let @type_name.type_ref = @elementary.ref + let @type_name.output = @elementary.ref + let @type_name.pop_begin = @elementary.pop + let @type_name.pop_end = @elementary.pop } @type_name [TypeName @id_path [IdentifierPath]] { ;; For an identifier path used as a type, the left-most element is the one ;; that connects to the parent lexical scope, because the name resolution ;; starts at the left of the identifier. - edge @id_path.left -> @type_name.type_ref + let @type_name.type_ref = @id_path.push_end ;; Conversely, the complete type is found at the right-most name, and that's ;; where users of this type should link to (eg. a variable declaration). - edge @type_name.output -> @id_path.right + let @type_name.output = @id_path.push_begin + + let @type_name.pop_begin = @id_path.pop_begin + let @type_name.pop_end = @id_path.pop_end +} + +@type_name [TypeName @type_variant ([ArrayTypeName] | [FunctionType])] { + let @type_name.type_ref = @type_variant.lexical_scope + let @type_name.output = @type_variant.output + let @type_name.pop_begin = @type_variant.pop_begin + let @type_name.pop_end = @type_variant.pop_end } @type_name [TypeName @mapping [MappingType]] { - edge @mapping.lexical_scope -> @type_name.type_ref - edge @type_name.output -> @mapping.output + let @type_name.type_ref = @mapping.lexical_scope + let @type_name.output = @mapping.output } -@type_name [TypeName @array [ArrayTypeName]] { - edge @array.lexical_scope -> @type_name.type_ref - edge @type_name.output -> @array.output + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Elementary types +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@elementary [ElementaryType] { + node @elementary.ref + attr (@elementary.ref) type = "push_symbol" + attr (@elementary.ref) source_node = @elementary, symbol = @elementary.symbol + + node @elementary.pop + attr (@elementary.pop) pop_symbol = @elementary.symbol } -@type_name [TypeName @ftype [FunctionType]] { - edge @ftype.lexical_scope -> @type_name.type_ref - edge @type_name.output -> @ftype.output +@elementary [ElementaryType variant: [AddressType @address [AddressKeyword]]] { + let @elementary.symbol = (format "%{}" (source-text @address)) +} + +@elementary [ElementaryType @keyword ( + [BoolKeyword] + | [ByteKeyword] + | [BytesKeyword] + | [StringKeyword] + | [IntKeyword] + | [UintKeyword] + | [FixedKeyword] + | [UfixedKeyword] +)] { + let @elementary.symbol = (format "%{}" (source-text @keyword)) } @@ -530,12 +670,15 @@ inherit .enclosing_def } @mapping [MappingType [MappingKey [MappingKeyType @key_ident [IdentifierPath]]]] { - edge @key_ident.left -> @mapping.lexical_scope + ; resolve key type + edge @key_ident.push_end -> @mapping.lexical_scope } @mapping [MappingType [MappingValue @value_type [TypeName]]] { - edge @value_type.type_ref -> @mapping.lexical_scope + ; for mapping types we don't need to push the type itself, because we don't need it (yet) + ; ditto for the pop path, because a mapping type cannot be the target of a using directive + ;; The mapping's type exposes the `[]` operator that returns the value type node typeof_input attr (typeof_input) pop_symbol = "@typeof" @@ -545,11 +688,13 @@ inherit .enclosing_def 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 + + ; resolve the value type through our scope + edge @value_type.type_ref -> @mapping.lexical_scope } @@ -563,8 +708,16 @@ inherit .enclosing_def } @array [ArrayTypeName @type_name [TypeName]] { - edge @type_name.type_ref -> @array.lexical_scope + ; This path pushes the array type to the symbol stack (ie. the [] marker + + ; element type) + node array_type + attr (array_type) push_symbol = "%[]" + edge @array.output -> array_type + edge array_type -> @type_name.output + + ; Provide an index access `[]` operator that "returns" the type of the + ; elements of the array node typeof_input attr (typeof_input) pop_symbol = "@typeof" @@ -574,11 +727,21 @@ inherit .enclosing_def 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 + + ; finally resolve the inner type through our parent scope + edge @type_name.type_ref -> @array.lexical_scope + + ; the pop path for the using directive + node pop_array_type + attr (pop_array_type) pop_symbol = "%[]" + + let @array.pop_begin = @type_name.pop_begin + edge @type_name.pop_end -> pop_array_type + let @array.pop_end = pop_array_type } @array [ArrayTypeName @size index: [Expression]] { @@ -593,6 +756,21 @@ inherit .enclosing_def @ftype [FunctionType] { node @ftype.lexical_scope node @ftype.output + + ; This path pushes the function type to the symbol stack + ; TODO: add parameter and return types to distinguish between different function types + node function_type + attr (function_type) push_symbol = "%function" + + edge @ftype.output -> function_type + edge function_type -> @ftype.lexical_scope + + ; the pop path for the using directive + node pop_function_type + attr (pop_function_type) pop_symbol = "%function" + + let @ftype.pop_begin = pop_function_type + let @ftype.pop_end = pop_function_type } @ftype [FunctionType @params [ParametersDeclaration]] { @@ -603,38 +781,78 @@ inherit .enclosing_def edge @return_params.lexical_scope -> @ftype.lexical_scope } +@ftype [FunctionType [ReturnsDeclaration + [ParametersDeclaration [Parameters . @param [Parameter] .]] +]] { + ; variables of a function type type can be "called" and resolve to the type of + ; the return parameter + node typeof + attr (typeof) pop_symbol = "@typeof" + + node call + attr (call) pop_symbol = "()" + + edge @ftype.output -> typeof + edge typeof -> call + edge call -> @param.typeof +} ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 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 - node @id_path.right -} +;; The identifier path builds two graph paths: +;; +;; - From right to left, pushing the identifiers and acting as a "reference". +;; This path begins at @id_path.push_begin and ends at @id_path.push_end. +;; +;; - From left to right, popping the identifiers (used as a definition sink in +;; using directives). This path begins at @id_path.pop_begin and ends at +;; @id_path.pop_end. +;; +;; NOTE: most of the time, and unless this identifier path is the target of a +;; using directive this path will not be used and will form a disconnected +;; graph component. We currently have no way of determining when this path is +;; necessary, so we always construct it. +;; +;; Additionally the IdentifierPath defines another scoped variable +;; @id_path.rightmost_identifier which corresponds to the identifier in the last +;; position in the path, from left to right. Useful for the using directive to +;; be able to pop the name of the attached function. [IdentifierPath @name [Identifier]] { node @name.ref attr (@name.ref) node_reference = @name + + node @name.pop + attr (@name.pop) pop_symbol = (source-text @name) } @id_path [IdentifierPath @name [Identifier] .] { - edge @id_path.right -> @name.ref - let @id_path.ref = @name.ref + let @id_path.rightmost_identifier = @name + + let @id_path.push_begin = @name.ref + let @id_path.pop_end = @name.pop } [IdentifierPath @left_name [Identifier] . [Period] . @right_name [Identifier]] { - node member - attr (member) push_symbol = "." + node ref_member + attr (ref_member) push_symbol = "." - edge @right_name.ref -> member - edge member -> @left_name.ref + edge @right_name.ref -> ref_member + edge ref_member -> @left_name.ref + + node pop_member + attr (pop_member) pop_symbol = "." + + edge @left_name.pop -> pop_member + edge pop_member -> @right_name.pop } @id_path [IdentifierPath . @name [Identifier]] { - edge @name.ref -> @id_path.left + let @id_path.push_end = @name.ref + let @id_path.pop_begin = @name.pop } @@ -678,6 +896,16 @@ inherit .enclosing_def @function [FunctionDefinition] { node @function.lexical_scope node @function.def + + ; this path from the function definition to the scope allows attaching + ; functions to this function's type + node typeof + attr (typeof) push_symbol = "@typeof" + node type_function + attr (type_function) push_symbol = "%function" + edge @function.def -> typeof + edge typeof -> type_function + edge type_function -> @function.lexical_scope } @function [FunctionDefinition name: [FunctionName @name [Identifier]]] { @@ -734,7 +962,7 @@ inherit .enclosing_def @modifier [ModifierInvocation @name [IdentifierPath]] { node @modifier.lexical_scope - edge @name.left -> @modifier.lexical_scope + edge @name.push_end -> @modifier.lexical_scope } @modifier [ModifierInvocation @args [ArgumentsDeclaration]] { @@ -1136,7 +1364,7 @@ inherit .enclosing_def ;;; Revert statements @stmt [Statement [RevertStatement @error_ident [IdentifierPath]]] { - edge @error_ident.left -> @stmt.lexical_scope + edge @error_ident.push_end -> @stmt.lexical_scope } @stmt [Statement [RevertStatement @args [ArgumentsDeclaration]]] { @@ -1147,7 +1375,7 @@ inherit .enclosing_def @error_ident [IdentifierPath] @args [ArgumentsDeclaration] ]] { - edge @args.refs -> @error_ident.right + edge @args.refs -> @error_ident.push_begin } @@ -1165,9 +1393,9 @@ inherit .enclosing_def @event_ident [IdentifierPath] @args [ArgumentsDeclaration] ]] { - edge @event_ident.left -> @stmt.lexical_scope + edge @event_ident.push_end -> @stmt.lexical_scope edge @args.lexical_scope -> @stmt.lexical_scope - edge @args.refs -> @event_ident.right + edge @args.refs -> @event_ident.push_begin } ;;; Unchecked diff --git a/crates/solidity/outputs/cargo/slang_solidity/src/generated/bindings/generated/binding_rules.rs b/crates/solidity/outputs/cargo/slang_solidity/src/generated/bindings/generated/binding_rules.rs index 5b26fc0f84..3d0d9be28e 100644 --- a/crates/solidity/outputs/cargo/slang_solidity/src/generated/bindings/generated/binding_rules.rs +++ b/crates/solidity/outputs/cargo/slang_solidity/src/generated/bindings/generated/binding_rules.rs @@ -57,6 +57,18 @@ inherit .enclosing_def edge @source_unit.defs -> @unit_member.def } +@source_unit [SourceUnit [SourceUnitMembers [SourceUnitMember @using [UsingDirective]]]] { + let @using.lexical_scope = @source_unit.lexical_scope + edge @source_unit.lexical_scope -> @using.def +} + +@source_unit [SourceUnit [SourceUnitMembers [SourceUnitMember + @using [UsingDirective [GlobalKeyword]] +]]] { + ; global using directives are exported by this source unit + edge @source_unit.defs -> @using.def +} + ;; ... and imports @source_unit [SourceUnit [SourceUnitMembers [SourceUnitMember [ImportDirective @@ -274,7 +286,7 @@ inherit .enclosing_def ]]] { ;; Resolve contract bases names through the parent scope of the contract (aka ;; the source unit) - edge @type_name.left -> @contract.parent_scope + edge @type_name.push_end -> @contract.parent_scope ;; Make base members accesible as our own members node member @@ -285,21 +297,21 @@ inherit .enclosing_def edge @contract.members -> member edge member -> typeof - edge typeof -> @type_name.right + edge typeof -> @type_name.push_begin ;; Make base contract defs (eg. enums and structs) accessible as our own node type_member attr (type_member) push_symbol = "." edge @contract.type_members -> type_member - edge type_member -> @type_name.right + edge type_member -> @type_name.push_begin ;; The base contract defs are directly accesible through our special super scope - edge @contract.super_scope -> @type_name.right + edge @contract.super_scope -> @type_name.push_begin } @parent [InheritanceType @type_name [IdentifierPath]] { - let @parent.ref = @type_name.ref + let @parent.ref = @type_name.push_begin } ;; NOTE: we use anchors here to prevent the query engine from returning all the @@ -334,6 +346,13 @@ inherit .enclosing_def edge @member.lexical_scope -> @contract.lexical_scope } +@contract [ContractDefinition [ContractMembers + [ContractMember @using [UsingDirective]] +]] { + let @using.lexical_scope = @contract.lexical_scope + edge @contract.lexical_scope -> @using.def +} + @contract [ContractDefinition [ContractMembers [ContractMember @member ( [EnumDefinition] @@ -382,7 +401,7 @@ inherit .enclosing_def ]]] ]]] { ;; Resolve overriden bases when listed in the function modifiers - edge @base_ident.left -> @contract.parent_scope + edge @base_ident.push_end -> @contract.parent_scope } @@ -443,6 +462,13 @@ inherit .enclosing_def edge @interface.members -> @function.def } +[InterfaceDefinition [InterfaceMembers [ContractMember @using [UsingDirective]]]] { + ; using directives are not allowed in interfaces, but the grammar allows them + ; so we need to create an artificial node here to connect to created edges from + ; the internal nodes + let @using.lexical_scope = (node) +} + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Libraries @@ -484,44 +510,158 @@ inherit .enclosing_def edge @library.members -> @member.def } +@library [LibraryDefinition [LibraryMembers + [ContractMember @using [UsingDirective]] +]] { + let @using.lexical_scope = @library.lexical_scope + edge @library.lexical_scope -> @using.def +} + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Using directives +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +;; The UsingDirective node requires the enclosing context to setup a +;; .lexical_scope scoped variable for it to resolve both targets and subjects. + +@using [UsingDirective] { + ; This node acts as a definition in the sense that provides an entry point + ; that pops the target type and pushes the library/functions to attach to the + ; target type + node @using.def + + ; This internal node connects the other end of the popping path starting at + ; .def and resolves for the library/functions in the directive + node @using.clause +} + +@using [UsingDirective [UsingClause @id_path [IdentifierPath]]] { + ; resolve the library to be used in the directive + edge @id_path.push_end -> @using.lexical_scope + + ; because we're using the whole library, we don't need to "consume" the + ; attached function (as when using the deconstruction syntax), but we still + ; need to verify that we're only using this path when resolving a function + ; access to the target type, not the target type itself + node dot_guard_pop + attr (dot_guard_pop) pop_symbol = "." + node dot_guard_push + attr (dot_guard_push) push_symbol = "." + + edge @using.clause -> dot_guard_pop + edge dot_guard_pop -> dot_guard_push + edge dot_guard_push -> @id_path.push_begin +} + +@using [UsingDirective [UsingClause [UsingDeconstruction + [UsingDeconstructionSymbols [UsingDeconstructionSymbol + @id_path [IdentifierPath] + ]] +]]] { + ; resolve the function to be used in the directive + edge @id_path.push_end -> @using.lexical_scope + + node dot + attr (dot) pop_symbol = "." + node last_identifier + attr (last_identifier) pop_symbol = (source-text @id_path.rightmost_identifier) + + edge @using.clause -> dot + edge dot -> last_identifier + edge last_identifier -> @id_path.push_begin +} + +@using [UsingDirective [UsingTarget @type_name [TypeName]]] { + ; pop the type symbols to connect to the attached function (via @using.clause) + node typeof + attr (typeof) pop_symbol = "@typeof" + + edge @using.def -> @type_name.pop_begin + edge @type_name.pop_end -> typeof + edge typeof -> @using.clause + + ; resolve the target type of the directive + edge @type_name.type_ref -> @using.lexical_scope +} + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Type names ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -@type_name [TypeName] { - ;; This node should connect to the parent lexical scope to resolve the type - node @type_name.type_ref +;; TypeName nodes should define two scoped variables: +;; +;; - @type_name.type_ref represents the node in the graph where we're ready to +;; resolve the type, and thus should generally be connected to a (lexical) +;; scope node (source node, outside edges connect *from* here). +;; +;; - @type_name.output represents the other end of the type and corresponds to a +;; state where the type has already been resolved so we can, for example +;; resolve its members (sink node, outside edges connect *to* here). - ;; This represents the output of the type, ie. the node to which a variable - ;; that is of this type should connect through a @typeof node - node @type_name.output +@type_name [TypeName @elementary [ElementaryType]] { + let @type_name.type_ref = @elementary.ref + let @type_name.output = @elementary.ref + let @type_name.pop_begin = @elementary.pop + let @type_name.pop_end = @elementary.pop } @type_name [TypeName @id_path [IdentifierPath]] { ;; For an identifier path used as a type, the left-most element is the one ;; that connects to the parent lexical scope, because the name resolution ;; starts at the left of the identifier. - edge @id_path.left -> @type_name.type_ref + let @type_name.type_ref = @id_path.push_end ;; Conversely, the complete type is found at the right-most name, and that's ;; where users of this type should link to (eg. a variable declaration). - edge @type_name.output -> @id_path.right + let @type_name.output = @id_path.push_begin + + let @type_name.pop_begin = @id_path.pop_begin + let @type_name.pop_end = @id_path.pop_end +} + +@type_name [TypeName @type_variant ([ArrayTypeName] | [FunctionType])] { + let @type_name.type_ref = @type_variant.lexical_scope + let @type_name.output = @type_variant.output + let @type_name.pop_begin = @type_variant.pop_begin + let @type_name.pop_end = @type_variant.pop_end } @type_name [TypeName @mapping [MappingType]] { - edge @mapping.lexical_scope -> @type_name.type_ref - edge @type_name.output -> @mapping.output + let @type_name.type_ref = @mapping.lexical_scope + let @type_name.output = @mapping.output } -@type_name [TypeName @array [ArrayTypeName]] { - edge @array.lexical_scope -> @type_name.type_ref - edge @type_name.output -> @array.output + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Elementary types +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@elementary [ElementaryType] { + node @elementary.ref + attr (@elementary.ref) type = "push_symbol" + attr (@elementary.ref) source_node = @elementary, symbol = @elementary.symbol + + node @elementary.pop + attr (@elementary.pop) pop_symbol = @elementary.symbol } -@type_name [TypeName @ftype [FunctionType]] { - edge @ftype.lexical_scope -> @type_name.type_ref - edge @type_name.output -> @ftype.output +@elementary [ElementaryType variant: [AddressType @address [AddressKeyword]]] { + let @elementary.symbol = (format "%{}" (source-text @address)) +} + +@elementary [ElementaryType @keyword ( + [BoolKeyword] + | [ByteKeyword] + | [BytesKeyword] + | [StringKeyword] + | [IntKeyword] + | [UintKeyword] + | [FixedKeyword] + | [UfixedKeyword] +)] { + let @elementary.symbol = (format "%{}" (source-text @keyword)) } @@ -535,12 +675,15 @@ inherit .enclosing_def } @mapping [MappingType [MappingKey [MappingKeyType @key_ident [IdentifierPath]]]] { - edge @key_ident.left -> @mapping.lexical_scope + ; resolve key type + edge @key_ident.push_end -> @mapping.lexical_scope } @mapping [MappingType [MappingValue @value_type [TypeName]]] { - edge @value_type.type_ref -> @mapping.lexical_scope + ; for mapping types we don't need to push the type itself, because we don't need it (yet) + ; ditto for the pop path, because a mapping type cannot be the target of a using directive + ;; The mapping's type exposes the `[]` operator that returns the value type node typeof_input attr (typeof_input) pop_symbol = "@typeof" @@ -550,11 +693,13 @@ inherit .enclosing_def 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 + + ; resolve the value type through our scope + edge @value_type.type_ref -> @mapping.lexical_scope } @@ -568,8 +713,16 @@ inherit .enclosing_def } @array [ArrayTypeName @type_name [TypeName]] { - edge @type_name.type_ref -> @array.lexical_scope + ; This path pushes the array type to the symbol stack (ie. the [] marker + + ; element type) + node array_type + attr (array_type) push_symbol = "%[]" + edge @array.output -> array_type + edge array_type -> @type_name.output + + ; Provide an index access `[]` operator that "returns" the type of the + ; elements of the array node typeof_input attr (typeof_input) pop_symbol = "@typeof" @@ -579,11 +732,21 @@ inherit .enclosing_def 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 + + ; finally resolve the inner type through our parent scope + edge @type_name.type_ref -> @array.lexical_scope + + ; the pop path for the using directive + node pop_array_type + attr (pop_array_type) pop_symbol = "%[]" + + let @array.pop_begin = @type_name.pop_begin + edge @type_name.pop_end -> pop_array_type + let @array.pop_end = pop_array_type } @array [ArrayTypeName @size index: [Expression]] { @@ -598,6 +761,21 @@ inherit .enclosing_def @ftype [FunctionType] { node @ftype.lexical_scope node @ftype.output + + ; This path pushes the function type to the symbol stack + ; TODO: add parameter and return types to distinguish between different function types + node function_type + attr (function_type) push_symbol = "%function" + + edge @ftype.output -> function_type + edge function_type -> @ftype.lexical_scope + + ; the pop path for the using directive + node pop_function_type + attr (pop_function_type) pop_symbol = "%function" + + let @ftype.pop_begin = pop_function_type + let @ftype.pop_end = pop_function_type } @ftype [FunctionType @params [ParametersDeclaration]] { @@ -608,38 +786,78 @@ inherit .enclosing_def edge @return_params.lexical_scope -> @ftype.lexical_scope } +@ftype [FunctionType [ReturnsDeclaration + [ParametersDeclaration [Parameters . @param [Parameter] .]] +]] { + ; variables of a function type type can be "called" and resolve to the type of + ; the return parameter + node typeof + attr (typeof) pop_symbol = "@typeof" + + node call + attr (call) pop_symbol = "()" + + edge @ftype.output -> typeof + edge typeof -> call + edge call -> @param.typeof +} ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; 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 - node @id_path.right -} +;; The identifier path builds two graph paths: +;; +;; - From right to left, pushing the identifiers and acting as a "reference". +;; This path begins at @id_path.push_begin and ends at @id_path.push_end. +;; +;; - From left to right, popping the identifiers (used as a definition sink in +;; using directives). This path begins at @id_path.pop_begin and ends at +;; @id_path.pop_end. +;; +;; NOTE: most of the time, and unless this identifier path is the target of a +;; using directive this path will not be used and will form a disconnected +;; graph component. We currently have no way of determining when this path is +;; necessary, so we always construct it. +;; +;; Additionally the IdentifierPath defines another scoped variable +;; @id_path.rightmost_identifier which corresponds to the identifier in the last +;; position in the path, from left to right. Useful for the using directive to +;; be able to pop the name of the attached function. [IdentifierPath @name [Identifier]] { node @name.ref attr (@name.ref) node_reference = @name + + node @name.pop + attr (@name.pop) pop_symbol = (source-text @name) } @id_path [IdentifierPath @name [Identifier] .] { - edge @id_path.right -> @name.ref - let @id_path.ref = @name.ref + let @id_path.rightmost_identifier = @name + + let @id_path.push_begin = @name.ref + let @id_path.pop_end = @name.pop } [IdentifierPath @left_name [Identifier] . [Period] . @right_name [Identifier]] { - node member - attr (member) push_symbol = "." + node ref_member + attr (ref_member) push_symbol = "." - edge @right_name.ref -> member - edge member -> @left_name.ref + edge @right_name.ref -> ref_member + edge ref_member -> @left_name.ref + + node pop_member + attr (pop_member) pop_symbol = "." + + edge @left_name.pop -> pop_member + edge pop_member -> @right_name.pop } @id_path [IdentifierPath . @name [Identifier]] { - edge @name.ref -> @id_path.left + let @id_path.push_end = @name.ref + let @id_path.pop_begin = @name.pop } @@ -683,6 +901,16 @@ inherit .enclosing_def @function [FunctionDefinition] { node @function.lexical_scope node @function.def + + ; this path from the function definition to the scope allows attaching + ; functions to this function's type + node typeof + attr (typeof) push_symbol = "@typeof" + node type_function + attr (type_function) push_symbol = "%function" + edge @function.def -> typeof + edge typeof -> type_function + edge type_function -> @function.lexical_scope } @function [FunctionDefinition name: [FunctionName @name [Identifier]]] { @@ -739,7 +967,7 @@ inherit .enclosing_def @modifier [ModifierInvocation @name [IdentifierPath]] { node @modifier.lexical_scope - edge @name.left -> @modifier.lexical_scope + edge @name.push_end -> @modifier.lexical_scope } @modifier [ModifierInvocation @args [ArgumentsDeclaration]] { @@ -1141,7 +1369,7 @@ inherit .enclosing_def ;;; Revert statements @stmt [Statement [RevertStatement @error_ident [IdentifierPath]]] { - edge @error_ident.left -> @stmt.lexical_scope + edge @error_ident.push_end -> @stmt.lexical_scope } @stmt [Statement [RevertStatement @args [ArgumentsDeclaration]]] { @@ -1152,7 +1380,7 @@ inherit .enclosing_def @error_ident [IdentifierPath] @args [ArgumentsDeclaration] ]] { - edge @args.refs -> @error_ident.right + edge @args.refs -> @error_ident.push_begin } @@ -1170,9 +1398,9 @@ inherit .enclosing_def @event_ident [IdentifierPath] @args [ArgumentsDeclaration] ]] { - edge @event_ident.left -> @stmt.lexical_scope + edge @event_ident.push_end -> @stmt.lexical_scope edge @args.lexical_scope -> @stmt.lexical_scope - edge @args.refs -> @event_ident.right + edge @args.refs -> @event_ident.push_begin } ;;; Unchecked diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/function_types.rs b/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/function_types.rs new file mode 100644 index 0000000000..e2e4d9a80c --- /dev/null +++ b/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/function_types.rs @@ -0,0 +1,10 @@ +// This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +use anyhow::Result; + +use crate::bindings_output::runner::run; + +#[test] +fn call() -> Result<()> { + run("function_types", "call") +} diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/mod.rs b/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/mod.rs index 40ad07613e..4cf2c8df17 100644 --- a/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/mod.rs +++ b/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/mod.rs @@ -6,11 +6,13 @@ mod enums; mod errors; mod events; mod expressions; +mod function_types; mod imports; mod interfaces; mod libraries; mod mappings; mod modifiers; mod structs; +mod using; mod variables; mod yul; diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/using.rs b/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/using.rs new file mode 100644 index 0000000000..3f7367e71c --- /dev/null +++ b/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/using.rs @@ -0,0 +1,45 @@ +// This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +use anyhow::Result; + +use crate::bindings_output::runner::run; + +#[test] +fn deconstruction() -> Result<()> { + run("using", "deconstruction") +} + +#[test] +fn elementary() -> Result<()> { + run("using", "elementary") +} + +#[test] +fn elementary_arrays() -> Result<()> { + run("using", "elementary_arrays") +} + +#[test] +fn function_types() -> Result<()> { + run("using", "function_types") +} + +#[test] +fn global() -> Result<()> { + run("using", "global") +} + +#[test] +fn in_contract() -> Result<()> { + run("using", "in_contract") +} + +#[test] +fn in_library() -> Result<()> { + run("using", "in_library") +} + +#[test] +fn top_level() -> Result<()> { + run("using", "top_level") +} diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_output/graph.rs b/crates/solidity/outputs/cargo/tests/src/bindings_output/graph.rs deleted file mode 100644 index b70edba996..0000000000 --- a/crates/solidity/outputs/cargo/tests/src/bindings_output/graph.rs +++ /dev/null @@ -1,277 +0,0 @@ -use std::fmt; - -use metaslang_graph_builder::graph::{Graph, GraphNodeRef, Value}; -use slang_solidity::cst::KindTypes; - -use super::runner::ParsedPart; - -const VARIABLE_DEBUG_ATTR: &str = "debug_msgb_variable"; -const LOCATION_DEBUG_ATTR: &str = "debug_msgb_location"; -const MATCH_DEBUG_ATTR: &str = "debug_msgb_match_node"; - -pub(crate) fn render_graph(parsed_parts: &[ParsedPart<'_>]) -> String { - let mut result = Vec::new(); - result.push("graph TD".to_string()); - result.push("ROOT_NODE((ROOT NODE))".to_string()); - - for (index, part) in parsed_parts.iter().enumerate() { - let title = if part.parse_output.is_valid() { - part.path.to_string() - } else { - format!("PARSING FAILED: {}", part.path) - }; - - let graph_id = format!("G{index}"); - result.push(render_mermaid_subgraph(&graph_id, &part.graph, &title).to_string()); - } - - result.join("\n") -} - -fn render_mermaid_subgraph<'a>( - graph_id: &'a str, - graph: &'a Graph, - title: &'a str, -) -> impl fmt::Display + 'a { - struct DisplayGraph<'a> { - graph_id: &'a str, - graph: &'a Graph, - title: &'a str, - } - - impl<'a> DisplayGraph<'a> { - fn root_node(&self) -> GraphNodeRef { - self.graph - .iter_nodes() - .next() - .expect("graph should have at least the root node") - } - - fn node_id(&self, node: GraphNodeRef) -> String { - if node == self.root_node() { - // special case: ROOT_NODE - "ROOT_NODE".to_string() - } else { - format!( - "{graph_id}N{index}", - graph_id = self.graph_id, - index = node.index() - ) - } - } - } - - impl<'a> fmt::Display for DisplayGraph<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let root = self.root_node(); - - // we need to print edges connecting to the ROOT NODE outside of the subgraph - for node in self.graph.iter_nodes() { - let graph_node = &self.graph[node]; - let node_id = self.node_id(node); - - for (sink, _edge) in graph_node.iter_edges() { - if node == root || sink == root { - writeln!(f, "{node_id} --> {sink_id}", sink_id = self.node_id(sink))?; - } - } - } - - writeln!(f)?; - writeln!( - f, - "subgraph {graph_id} [{title}]", - graph_id = self.graph_id, - title = self.title - )?; - - for node in self.graph.iter_nodes() { - if node == root { - // we already rendered the ROOT NODE and all its edges - continue; - } - - let graph_node = &self.graph[node]; - let node_label = if let Some(symbol) = graph_node.attributes.get("symbol") { - symbol.to_string() - } else { - format!("{}", node.index()) - }; - let source = graph_node - .attributes - .get(MATCH_DEBUG_ATTR) - .and_then(|source| source.as_syntax_node_ref().ok()); - let location = graph_node.attributes.get(LOCATION_DEBUG_ATTR); - - let node_label = format!( - "\"`**{node_label}** @{source}\n{variable}\n{location}`\"", - source = source.map(|s| s.location()).unwrap_or_default(), - variable = graph_node - .attributes - .get(VARIABLE_DEBUG_ATTR) - .unwrap_or(&Value::Null), - location = location.unwrap_or(&Value::Null), - ); - let node_type = graph_node - .attributes - .get("type") - .and_then(|x| x.as_str().ok()); - let node_id = self.node_id(node); - - match node_type { - Some("push_symbol") => writeln!(f, "\t{node_id}[/{node_label}\\]")?, - Some("pop_symbol") => writeln!(f, "\t{node_id}[\\{node_label}/]")?, - _ => writeln!(f, "\t{node_id}[{node_label}]")?, - } - - for (sink, _edge) in graph_node.iter_edges() { - if sink == root { - // we already rendered the edges going to ROOT NODE - continue; - } - writeln!(f, "\t{node_id} --> {sink_id}", sink_id = self.node_id(sink))?; - } - } - - writeln!(f, "end")?; - Ok(()) - } - } - - DisplayGraph { - graph_id, - graph, - title, - } -} - -pub(crate) fn render_dot_graph(parsed_parts: &[ParsedPart<'_>]) -> String { - let mut result = Vec::new(); - result.push("digraph {".to_string()); - result.push("ROOT_NODE".to_string()); - - for (index, part) in parsed_parts.iter().enumerate() { - let title = if part.parse_output.is_valid() { - part.path.to_string() - } else { - format!("PARSING FAILED: {}", part.path) - }; - - let graph_id = format!("G{index}"); - result.push(render_dot_subgraph(&graph_id, &part.graph, &title).to_string()); - } - result.push("}".to_string()); - - result.join("\n") -} - -fn render_dot_subgraph<'a>( - graph_id: &'a str, - graph: &'a Graph, - title: &'a str, -) -> impl fmt::Display + 'a { - struct DisplayGraph<'a> { - graph_id: &'a str, - graph: &'a Graph, - title: &'a str, - } - - impl<'a> DisplayGraph<'a> { - fn root_node(&self) -> GraphNodeRef { - self.graph - .iter_nodes() - .next() - .expect("graph should have at least the root node") - } - - fn node_id(&self, node: GraphNodeRef) -> String { - if node == self.root_node() { - // special case: ROOT_NODE - "ROOT_NODE".to_string() - } else { - format!( - "{graph_id}N{index}", - graph_id = self.graph_id, - index = node.index() - ) - } - } - } - - impl<'a> fmt::Display for DisplayGraph<'a> { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - let root = self.root_node(); - - // we need to print edges connecting to the ROOT NODE outside of the subgraph - for node in self.graph.iter_nodes() { - let graph_node = &self.graph[node]; - let node_id = self.node_id(node); - - for (sink, _edge) in graph_node.iter_edges() { - if node == root || sink == root { - writeln!(f, "{node_id} -> {sink_id}", sink_id = self.node_id(sink))?; - } - } - } - - writeln!(f)?; - writeln!( - f, - "subgraph cluster_{graph_id} {{\nlabel = \"{title}\"", - graph_id = self.graph_id, - title = self.title - )?; - - for node in self.graph.iter_nodes() { - if node == root { - // we already rendered the ROOT NODE and all its edges - continue; - } - - let graph_node = &self.graph[node]; - let node_label = if let Some(symbol) = graph_node.attributes.get("symbol") { - symbol.to_string() - } else if let Some(variable) = graph_node.attributes.get(VARIABLE_DEBUG_ATTR) { - variable.to_string() - } else { - format!("{}", node.index()) - }; - - let node_label = format!("\"{node_label}\""); - let node_type = graph_node - .attributes - .get("type") - .and_then(|x| x.as_str().ok()); - let node_id = self.node_id(node); - - match node_type { - Some("push_symbol") => writeln!( - f, - "\t{node_id} [label = {node_label}, shape = \"invhouse\"]" - )?, - Some("pop_symbol") => { - writeln!(f, "\t{node_id} [label = {node_label}, shape = \"house\"]")?; - } - _ => writeln!(f, "\t{node_id} [label = {node_label}]")?, - } - - for (sink, _edge) in graph_node.iter_edges() { - if sink == root { - // we already rendered the edges going to ROOT NODE - continue; - } - writeln!(f, "\t{node_id} -> {sink_id}", sink_id = self.node_id(sink))?; - } - } - - writeln!(f, "}}")?; - Ok(()) - } - } - - DisplayGraph { - graph_id, - graph, - title, - } -} diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_output/graph/graphviz.rs b/crates/solidity/outputs/cargo/tests/src/bindings_output/graph/graphviz.rs new file mode 100644 index 0000000000..37f5d7efe9 --- /dev/null +++ b/crates/solidity/outputs/cargo/tests/src/bindings_output/graph/graphviz.rs @@ -0,0 +1,149 @@ +use std::fmt; + +use metaslang_graph_builder::graph::{Graph, GraphNodeRef}; +use slang_solidity::cst::KindTypes; + +use super::super::runner::ParsedPart; + +const VARIABLE_DEBUG_ATTR: &str = "debug_msgb_variable"; + +pub(crate) fn render(parsed_parts: &[ParsedPart<'_>]) -> String { + let mut result = Vec::new(); + result.push("digraph {".to_string()); + result.push("ROOT_NODE".to_string()); + + for (index, part) in parsed_parts.iter().enumerate() { + let title = if part.parse_output.is_valid() { + part.path.to_string() + } else { + format!("PARSING FAILED: {}", part.path) + }; + + let graph_id = format!("G{index}"); + result.push( + DotSubGraph { + graph_id, + graph: &part.graph, + title, + } + .to_string(), + ); + } + result.push("}".to_string()); + + result.join("\n") +} + +struct DotSubGraph<'a> { + graph_id: String, + graph: &'a Graph, + title: String, +} + +impl<'a> DotSubGraph<'a> { + fn root_node(&self) -> GraphNodeRef { + self.graph + .iter_nodes() + .next() + .expect("graph should have at least the root node") + } + + fn node_id(&self, node: GraphNodeRef) -> String { + if node == self.root_node() { + // special case: ROOT_NODE + "ROOT_NODE".to_string() + } else { + format!( + "{graph_id}N{index}", + graph_id = self.graph_id, + index = node.index() + ) + } + } +} + +impl<'a> fmt::Display for DotSubGraph<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let root = self.root_node(); + + // we need to print edges connecting to the ROOT NODE outside of the subgraph + for node in self.graph.iter_nodes() { + let graph_node = &self.graph[node]; + let node_id = self.node_id(node); + + for (sink, _edge) in graph_node.iter_edges() { + if node == root || sink == root { + writeln!(f, "{node_id} -> {sink_id}", sink_id = self.node_id(sink))?; + } + } + } + + writeln!(f)?; + writeln!( + f, + "subgraph cluster_{graph_id} {{\nlabel = \"{title}\"", + graph_id = self.graph_id, + title = self.title + )?; + + for node in self.graph.iter_nodes() { + if node == root { + // we already rendered the ROOT NODE and all its edges + continue; + } + + let graph_node = &self.graph[node]; + let node_label = if let Some(symbol) = graph_node.attributes.get("symbol") { + symbol.to_string() + } else if let Some(variable) = graph_node.attributes.get(VARIABLE_DEBUG_ATTR) { + variable.to_string() + } else { + format!("{}", node.index()) + }; + + let node_label = format!("\"{node_label}\""); + let node_type = graph_node + .attributes + .get("type") + .and_then(|x| x.as_str().ok()); + let node_id = self.node_id(node); + + match node_type { + Some("push_symbol") => { + let extra_attrs = if graph_node.attributes.get("is_reference").is_some() { + ", penwidth = 2, color = \"limegreen\", fontcolor = \"limegreen\"" + } else { + ", color = \"lightgreen\", fontcolor = \"lightgreen\"" + }; + writeln!( + f, + "\t{node_id} [label = {node_label}, shape = \"invhouse\"{extra_attrs}]" + )?; + } + Some("pop_symbol") => { + let extra_attrs = if graph_node.attributes.get("is_definition").is_some() { + ", penwidth = 2, color = \"red\", fontcolor = \"red\"" + } else { + ", color = \"coral\", fontcolor = \"coral\"" + }; + writeln!( + f, + "\t{node_id} [label = {node_label}, shape = \"house\"{extra_attrs}]" + )?; + } + _ => writeln!(f, "\t{node_id} [label = {node_label}]")?, + } + + for (sink, _edge) in graph_node.iter_edges() { + if sink == root { + // we already rendered the edges going to ROOT NODE + continue; + } + writeln!(f, "\t{node_id} -> {sink_id}", sink_id = self.node_id(sink))?; + } + } + + writeln!(f, "}}")?; + Ok(()) + } +} diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_output/graph/mermaid.rs b/crates/solidity/outputs/cargo/tests/src/bindings_output/graph/mermaid.rs new file mode 100644 index 0000000000..602ec15680 --- /dev/null +++ b/crates/solidity/outputs/cargo/tests/src/bindings_output/graph/mermaid.rs @@ -0,0 +1,141 @@ +use std::fmt; + +use metaslang_graph_builder::graph::{Graph, GraphNodeRef, Value}; +use slang_solidity::cst::KindTypes; + +use super::super::runner::ParsedPart; + +const VARIABLE_DEBUG_ATTR: &str = "debug_msgb_variable"; +const LOCATION_DEBUG_ATTR: &str = "debug_msgb_location"; +const MATCH_DEBUG_ATTR: &str = "debug_msgb_match_node"; + +pub(crate) fn render(parsed_parts: &[ParsedPart<'_>]) -> String { + let mut result = Vec::new(); + result.push("graph TD".to_string()); + result.push("ROOT_NODE((ROOT NODE))".to_string()); + + for (index, part) in parsed_parts.iter().enumerate() { + let title = if part.parse_output.is_valid() { + part.path.to_string() + } else { + format!("PARSING FAILED: {}", part.path) + }; + + let graph_id = format!("G{index}"); + result.push( + MermaidSubGraph { + graph_id, + graph: &part.graph, + title, + } + .to_string(), + ); + } + + result.join("\n") +} + +struct MermaidSubGraph<'a> { + graph_id: String, + graph: &'a Graph, + title: String, +} + +impl<'a> MermaidSubGraph<'a> { + fn root_node(&self) -> GraphNodeRef { + self.graph + .iter_nodes() + .next() + .expect("graph should have at least the root node") + } + + fn node_id(&self, node: GraphNodeRef) -> String { + if node == self.root_node() { + // special case: ROOT_NODE + "ROOT_NODE".to_string() + } else { + format!( + "{graph_id}N{index}", + graph_id = self.graph_id, + index = node.index() + ) + } + } +} + +impl<'a> fmt::Display for MermaidSubGraph<'a> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + let root = self.root_node(); + + // we need to print edges connecting to the ROOT NODE outside of the subgraph + for node in self.graph.iter_nodes() { + let graph_node = &self.graph[node]; + let node_id = self.node_id(node); + + for (sink, _edge) in graph_node.iter_edges() { + if node == root || sink == root { + writeln!(f, "{node_id} --> {sink_id}", sink_id = self.node_id(sink))?; + } + } + } + + writeln!(f)?; + writeln!( + f, + "subgraph {graph_id} [{title}]", + graph_id = self.graph_id, + title = self.title + )?; + + for node in self.graph.iter_nodes() { + if node == root { + // we already rendered the ROOT NODE and all its edges + continue; + } + + let graph_node = &self.graph[node]; + let node_label = if let Some(symbol) = graph_node.attributes.get("symbol") { + symbol.to_string() + } else { + format!("{}", node.index()) + }; + let source = graph_node + .attributes + .get(MATCH_DEBUG_ATTR) + .and_then(|source| source.as_syntax_node_ref().ok()); + let location = graph_node.attributes.get(LOCATION_DEBUG_ATTR); + + let node_label = format!( + "\"`**{node_label}** @{source}\n{variable}\n{location}`\"", + source = source.map(|s| s.location()).unwrap_or_default(), + variable = graph_node + .attributes + .get(VARIABLE_DEBUG_ATTR) + .unwrap_or(&Value::Null), + location = location.unwrap_or(&Value::Null), + ); + let node_type = graph_node + .attributes + .get("type") + .and_then(|x| x.as_str().ok()); + let node_id = self.node_id(node); + + match node_type { + Some("push_symbol") => writeln!(f, "\t{node_id}[/{node_label}\\]")?, + Some("pop_symbol") => writeln!(f, "\t{node_id}[\\{node_label}/]")?, + _ => writeln!(f, "\t{node_id}[{node_label}]")?, + } + + for (sink, _edge) in graph_node.iter_edges() { + if sink == root { + // we already rendered the edges going to ROOT NODE + continue; + } + writeln!(f, "\t{node_id} --> {sink_id}", sink_id = self.node_id(sink))?; + } + } + + writeln!(f, "end")?; + Ok(()) + } +} diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_output/graph/mod.rs b/crates/solidity/outputs/cargo/tests/src/bindings_output/graph/mod.rs new file mode 100644 index 0000000000..af05358d11 --- /dev/null +++ b/crates/solidity/outputs/cargo/tests/src/bindings_output/graph/mod.rs @@ -0,0 +1,2 @@ +pub mod graphviz; +pub mod mermaid; diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_output/runner.rs b/crates/solidity/outputs/cargo/tests/src/bindings_output/runner.rs index 219388fe72..7fa624f9f2 100644 --- a/crates/solidity/outputs/cargo/tests/src/bindings_output/runner.rs +++ b/crates/solidity/outputs/cargo/tests/src/bindings_output/runner.rs @@ -10,7 +10,8 @@ use slang_solidity::bindings; use slang_solidity::cst::KindTypes; use slang_solidity::parser::{ParseOutput, Parser}; -use super::graph::{render_dot_graph, render_graph}; +use super::graph::graphviz::render as render_graphviz_graph; +use super::graph::mermaid::render as render_mermaid_graph; use super::renderer::render_bindings; use crate::generated::VERSION_BREAKS; use crate::multi_part_file::{split_multi_file, Part}; @@ -73,7 +74,7 @@ pub fn run(group_name: &str, test_name: &str) -> Result<()> { // Don't run this in CI, since the graph outputs are not committed // to the repository and hence we cannot verify their contents, // which is what `fs.write_file` does in CI. - let graph_output = render_graph(&parsed_parts); + let graph_output = render_mermaid_graph(&parsed_parts); match last_graph_output { Some(ref last) if last == &graph_output => (), _ => { @@ -84,7 +85,7 @@ pub fn run(group_name: &str, test_name: &str) -> Result<()> { fs.write_file(snapshot_path, &graph_output)?; last_graph_output = Some(graph_output); - let dot_output = render_dot_graph(&parsed_parts); + let dot_output = render_graphviz_graph(&parsed_parts); let dot_output_path = test_dir .join("generated") .join(format!("{version}-{parse_status}.dot")); diff --git a/crates/solidity/testing/snapshots/bindings_output/function_types/call/generated/0.4.11-success.txt b/crates/solidity/testing/snapshots/bindings_output/function_types/call/generated/0.4.11-success.txt new file mode 100644 index 0000000000..f0a6bd09a5 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/function_types/call/generated/0.4.11-success.txt @@ -0,0 +1,28 @@ +# 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 │ struct Value { + │ ──┬── + │ ╰──── def: 2 + 3 │ int x; + │ ┬ + │ ╰── def: 3 + │ + 5 │ function test(function() returns (Value) f) public { + │ ──┬─ ──┬── ┬ + │ ╰──────────────────────────────── def: 4 + │ │ │ + │ ╰─────── ref: 2 + │ │ + │ ╰── def: 5 + 6 │ f().x; + │ ┬ ┬ + │ ╰────── ref: 5 + │ │ + │ ╰── ref: 3 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/function_types/call/input.sol b/crates/solidity/testing/snapshots/bindings_output/function_types/call/input.sol new file mode 100644 index 0000000000..8d2084590e --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/function_types/call/input.sol @@ -0,0 +1,8 @@ +contract Test { + struct Value { + int x; + } + function test(function() returns (Value) f) public { + f().x; + } +} diff --git a/crates/solidity/testing/snapshots/bindings_output/using/deconstruction/generated/0.4.11-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/deconstruction/generated/0.4.11-failure.txt new file mode 100644 index 0000000000..a10e58ac37 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/deconstruction/generated/0.4.11-failure.txt @@ -0,0 +1,50 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected Identifier. + ╭─[input.sol:10:11] + │ + 10 │ using {Lib.increment} for Lib.Counter; + │ ───────────────┬─────────────── + │ ╰───────────────── Error occurred here. +────╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ library Lib { + │ ─┬─ + │ ╰─── def: 1 + 2 │ struct Counter { + │ ───┬─── + │ ╰───── def: 2 + 3 │ uint value; + │ ──┬── + │ ╰──── def: 3 + │ + 6 │ function increment(Counter memory _counter) public {} + │ ────┬──── ───┬─── ────┬─── + │ ╰────────────────────────────── def: 4 + │ │ │ + │ ╰───────────────────── ref: 2 + │ │ + │ ╰───── def: 5 + │ + 9 │ contract Test { + │ ──┬─ + │ ╰─── def: 6 + │ + 12 │ function test(Lib.Counter memory c) public { + │ ──┬─ ─┬─ ───┬─── ┬ + │ ╰──────────────────────── def: 7 + │ │ │ │ + │ ╰──────────────────── ref: 1 + │ │ │ + │ ╰────────────── ref: 2 + │ │ + │ ╰── def: 8 + 13 │ c.increment(); + │ ┬ ────┬──── + │ ╰──────────── ref: 8 + │ │ + │ ╰────── unresolved +────╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/deconstruction/generated/0.8.13-success.txt b/crates/solidity/testing/snapshots/bindings_output/using/deconstruction/generated/0.8.13-success.txt new file mode 100644 index 0000000000..b50b605fe6 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/deconstruction/generated/0.8.13-success.txt @@ -0,0 +1,51 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ library Lib { + │ ─┬─ + │ ╰─── def: 1 + 2 │ struct Counter { + │ ───┬─── + │ ╰───── def: 2 + 3 │ uint value; + │ ──┬── + │ ╰──── def: 3 + │ + 6 │ function increment(Counter memory _counter) public {} + │ ────┬──── ───┬─── ────┬─── + │ ╰────────────────────────────── def: 4 + │ │ │ + │ ╰───────────────────── ref: 2 + │ │ + │ ╰───── def: 5 + │ + 9 │ contract Test { + │ ──┬─ + │ ╰─── def: 6 + 10 │ using {Lib.increment} for Lib.Counter; + │ ─┬─ ────┬──── ─┬─ ───┬─── + │ ╰────────────────────────────── ref: 1 + │ │ │ │ + │ ╰─────────────────────── ref: 4 + │ │ │ + │ ╰─────────── ref: 1 + │ │ + │ ╰───── ref: 2 + │ + 12 │ function test(Lib.Counter memory c) public { + │ ──┬─ ─┬─ ───┬─── ┬ + │ ╰──────────────────────── def: 7 + │ │ │ │ + │ ╰──────────────────── ref: 1 + │ │ │ + │ ╰────────────── ref: 2 + │ │ + │ ╰── def: 8 + 13 │ c.increment(); + │ ┬ ────┬──── + │ ╰──────────── ref: 8 + │ │ + │ ╰────── ref: 4 +────╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/deconstruction/input.sol b/crates/solidity/testing/snapshots/bindings_output/using/deconstruction/input.sol new file mode 100644 index 0000000000..e0d3b744eb --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/deconstruction/input.sol @@ -0,0 +1,15 @@ +library Lib { + struct Counter { + uint value; + } + + function increment(Counter memory _counter) public {} +} + +contract Test { + using {Lib.increment} for Lib.Counter; + + function test(Lib.Counter memory c) public { + c.increment(); + } +} diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.4.11-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.4.11-failure.txt new file mode 100644 index 0000000000..d5bc149c8f --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.4.11-failure.txt @@ -0,0 +1,13 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected ContractKeyword or ImportKeyword or InterfaceKeyword or LibraryKeyword or PragmaKeyword. + ╭─[input.sol:1:1] + │ + 1 │ ╭─▶ function square(int value) returns (int) {} + ┆ ┆ + 7 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +───╯ +References and definitions: diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.6.0-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.6.0-failure.txt new file mode 100644 index 0000000000..8db01439b4 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.6.0-failure.txt @@ -0,0 +1,13 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected ContractKeyword or EnumKeyword or ImportKeyword or InterfaceKeyword or LibraryKeyword or PragmaKeyword or StructKeyword. + ╭─[input.sol:1:1] + │ + 1 │ ╭─▶ function square(int value) returns (int) {} + ┆ ┆ + 7 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +───╯ +References and definitions: diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.7.1-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.7.1-failure.txt new file mode 100644 index 0000000000..42901b1e0d --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.7.1-failure.txt @@ -0,0 +1,21 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected ContractKeyword or EnumKeyword or FunctionKeyword or ImportKeyword or InterfaceKeyword or LibraryKeyword or PragmaKeyword or StructKeyword. + ╭─[input.sol:3:1] + │ + 3 │ ╭─▶ using {square} for int; + ┆ ┆ + 7 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +───╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ function square(int value) returns (int) {} + │ ───┬── ──┬── + │ ╰────────────── def: 1 + │ │ + │ ╰──── def: 2 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.7.4-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.7.4-failure.txt new file mode 100644 index 0000000000..6f22fc10c0 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.7.4-failure.txt @@ -0,0 +1,21 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or ByteKeyword or BytesKeyword or ContractKeyword or EnumKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or UfixedKeyword or UintKeyword. + ╭─[input.sol:3:1] + │ + 3 │ ╭─▶ using {square} for int; + ┆ ┆ + 7 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +───╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ function square(int value) returns (int) {} + │ ───┬── ──┬── + │ ╰────────────── def: 1 + │ │ + │ ╰──── def: 2 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.8.0-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.8.0-failure.txt new file mode 100644 index 0000000000..727aa868e4 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.8.0-failure.txt @@ -0,0 +1,21 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or BytesKeyword or ContractKeyword or EnumKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or UfixedKeyword or UintKeyword. + ╭─[input.sol:3:1] + │ + 3 │ ╭─▶ using {square} for int; + ┆ ┆ + 7 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +───╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ function square(int value) returns (int) {} + │ ───┬── ──┬── + │ ╰────────────── def: 1 + │ │ + │ ╰──── def: 2 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.8.13-success.txt b/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.8.13-success.txt new file mode 100644 index 0000000000..b5e0e14463 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.8.13-success.txt @@ -0,0 +1,26 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ function square(int value) returns (int) {} + │ ───┬── ──┬── + │ ╰────────────── def: 1 + │ │ + │ ╰──── def: 2 + │ + 3 │ using {square} for int; + │ ───┬── + │ ╰──── ref: 1 + │ + 5 │ function test(int x) returns (int) { + │ ──┬─ ┬ + │ ╰───────── def: 3 + │ │ + │ ╰── def: 4 + 6 │ return x.square(); + │ ┬ ───┬── + │ ╰───────── ref: 4 + │ │ + │ ╰──── ref: 1 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.8.4-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.8.4-failure.txt new file mode 100644 index 0000000000..fb351beeb5 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.8.4-failure.txt @@ -0,0 +1,21 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or BytesKeyword or ContractKeyword or EnumKeyword or ErrorKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or UfixedKeyword or UintKeyword. + ╭─[input.sol:3:1] + │ + 3 │ ╭─▶ using {square} for int; + ┆ ┆ + 7 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +───╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ function square(int value) returns (int) {} + │ ───┬── ──┬── + │ ╰────────────── def: 1 + │ │ + │ ╰──── def: 2 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.8.8-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.8.8-failure.txt new file mode 100644 index 0000000000..95eb6e1847 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary/generated/0.8.8-failure.txt @@ -0,0 +1,21 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or BytesKeyword or ContractKeyword or EnumKeyword or ErrorKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or TypeKeyword or UfixedKeyword or UintKeyword. + ╭─[input.sol:3:1] + │ + 3 │ ╭─▶ using {square} for int; + ┆ ┆ + 7 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +───╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ function square(int value) returns (int) {} + │ ───┬── ──┬── + │ ╰────────────── def: 1 + │ │ + │ ╰──── def: 2 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary/input.sol b/crates/solidity/testing/snapshots/bindings_output/using/elementary/input.sol new file mode 100644 index 0000000000..c9059b5981 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary/input.sol @@ -0,0 +1,7 @@ +function square(int value) returns (int) {} + +using {square} for int; + +function test(int x) returns (int) { + return x.square(); +} diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.4.11-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.4.11-failure.txt new file mode 100644 index 0000000000..1ff7ffa08a --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.4.11-failure.txt @@ -0,0 +1,13 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected ContractKeyword or ImportKeyword or InterfaceKeyword or LibraryKeyword or PragmaKeyword. + ╭─[input.sol:1:1] + │ + 1 │ ╭─▶ function first(uint[] memory values) returns (uint) { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +───╯ +References and definitions: diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.6.0-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.6.0-failure.txt new file mode 100644 index 0000000000..01f52f86d5 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.6.0-failure.txt @@ -0,0 +1,13 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected ContractKeyword or EnumKeyword or ImportKeyword or InterfaceKeyword or LibraryKeyword or PragmaKeyword or StructKeyword. + ╭─[input.sol:1:1] + │ + 1 │ ╭─▶ function first(uint[] memory values) returns (uint) { + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +───╯ +References and definitions: diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.7.1-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.7.1-failure.txt new file mode 100644 index 0000000000..7148e3d878 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.7.1-failure.txt @@ -0,0 +1,24 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected ContractKeyword or EnumKeyword or FunctionKeyword or ImportKeyword or InterfaceKeyword or LibraryKeyword or PragmaKeyword or StructKeyword. + ╭─[input.sol:5:1] + │ + 5 │ ╭─▶ using {first} for uint[]; + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +───╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ function first(uint[] memory values) returns (uint) { + │ ──┬── ───┬── + │ ╰───────────────────────── def: 1 + │ │ + │ ╰──── def: 2 + 2 │ return values[0]; + │ ───┬── + │ ╰──── ref: 2 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.7.4-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.7.4-failure.txt new file mode 100644 index 0000000000..ec13c7c601 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.7.4-failure.txt @@ -0,0 +1,24 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or ByteKeyword or BytesKeyword or ContractKeyword or EnumKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or UfixedKeyword or UintKeyword. + ╭─[input.sol:5:1] + │ + 5 │ ╭─▶ using {first} for uint[]; + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +───╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ function first(uint[] memory values) returns (uint) { + │ ──┬── ───┬── + │ ╰───────────────────────── def: 1 + │ │ + │ ╰──── def: 2 + 2 │ return values[0]; + │ ───┬── + │ ╰──── ref: 2 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.8.0-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.8.0-failure.txt new file mode 100644 index 0000000000..195b5dfa8f --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.8.0-failure.txt @@ -0,0 +1,24 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or BytesKeyword or ContractKeyword or EnumKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or UfixedKeyword or UintKeyword. + ╭─[input.sol:5:1] + │ + 5 │ ╭─▶ using {first} for uint[]; + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +───╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ function first(uint[] memory values) returns (uint) { + │ ──┬── ───┬── + │ ╰───────────────────────── def: 1 + │ │ + │ ╰──── def: 2 + 2 │ return values[0]; + │ ───┬── + │ ╰──── ref: 2 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.8.13-success.txt b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.8.13-success.txt new file mode 100644 index 0000000000..e10430f5e7 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.8.13-success.txt @@ -0,0 +1,29 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ function first(uint[] memory values) returns (uint) { + │ ──┬── ───┬── + │ ╰───────────────────────── def: 1 + │ │ + │ ╰──── def: 2 + 2 │ return values[0]; + │ ───┬── + │ ╰──── ref: 2 + │ + 5 │ using {first} for uint[]; + │ ──┬── + │ ╰──── ref: 1 + │ + 7 │ function test(uint[] memory values) returns (uint) { + │ ──┬─ ───┬── + │ ╰──────────────────────── def: 3 + │ │ + │ ╰──── def: 4 + 8 │ return values.first(); + │ ───┬── ──┬── + │ ╰────────── ref: 4 + │ │ + │ ╰──── ref: 1 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.8.4-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.8.4-failure.txt new file mode 100644 index 0000000000..7108951852 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.8.4-failure.txt @@ -0,0 +1,24 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or BytesKeyword or ContractKeyword or EnumKeyword or ErrorKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or UfixedKeyword or UintKeyword. + ╭─[input.sol:5:1] + │ + 5 │ ╭─▶ using {first} for uint[]; + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +───╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ function first(uint[] memory values) returns (uint) { + │ ──┬── ───┬── + │ ╰───────────────────────── def: 1 + │ │ + │ ╰──── def: 2 + 2 │ return values[0]; + │ ───┬── + │ ╰──── ref: 2 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.8.8-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.8.8-failure.txt new file mode 100644 index 0000000000..4762b7438c --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/generated/0.8.8-failure.txt @@ -0,0 +1,24 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or BytesKeyword or ContractKeyword or EnumKeyword or ErrorKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or TypeKeyword or UfixedKeyword or UintKeyword. + ╭─[input.sol:5:1] + │ + 5 │ ╭─▶ using {first} for uint[]; + ┆ ┆ + 9 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +───╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ function first(uint[] memory values) returns (uint) { + │ ──┬── ───┬── + │ ╰───────────────────────── def: 1 + │ │ + │ ╰──── def: 2 + 2 │ return values[0]; + │ ───┬── + │ ╰──── ref: 2 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/input.sol b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/input.sol new file mode 100644 index 0000000000..9845b2610e --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/elementary_arrays/input.sol @@ -0,0 +1,9 @@ +function first(uint[] memory values) returns (uint) { + return values[0]; +} + +using {first} for uint[]; + +function test(uint[] memory values) returns (uint) { + return values.first(); +} diff --git a/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.4.11-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.4.11-failure.txt new file mode 100644 index 0000000000..35d503d83c --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.4.11-failure.txt @@ -0,0 +1,13 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected ContractKeyword or ImportKeyword or InterfaceKeyword or LibraryKeyword or PragmaKeyword. + ╭─[input.sol:1:1] + │ + 1 │ ╭─▶ using {invoke} for function(uint); + ┆ ┆ + 14 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +────╯ +References and definitions: diff --git a/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.6.0-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.6.0-failure.txt new file mode 100644 index 0000000000..25715a30c8 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.6.0-failure.txt @@ -0,0 +1,13 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected ContractKeyword or EnumKeyword or ImportKeyword or InterfaceKeyword or LibraryKeyword or PragmaKeyword or StructKeyword. + ╭─[input.sol:1:1] + │ + 1 │ ╭─▶ using {invoke} for function(uint); + ┆ ┆ + 14 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +────╯ +References and definitions: diff --git a/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.7.1-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.7.1-failure.txt new file mode 100644 index 0000000000..d7fed1da78 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.7.1-failure.txt @@ -0,0 +1,13 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected ContractKeyword or EnumKeyword or FunctionKeyword or ImportKeyword or InterfaceKeyword or LibraryKeyword or PragmaKeyword or StructKeyword. + ╭─[input.sol:1:1] + │ + 1 │ ╭─▶ using {invoke} for function(uint); + ┆ ┆ + 14 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +────╯ +References and definitions: diff --git a/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.7.4-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.7.4-failure.txt new file mode 100644 index 0000000000..672a64c307 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.7.4-failure.txt @@ -0,0 +1,13 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or ByteKeyword or BytesKeyword or ContractKeyword or EnumKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or UfixedKeyword or UintKeyword. + ╭─[input.sol:1:1] + │ + 1 │ ╭─▶ using {invoke} for function(uint); + ┆ ┆ + 14 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +────╯ +References and definitions: diff --git a/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.8.0-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.8.0-failure.txt new file mode 100644 index 0000000000..02390336ef --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.8.0-failure.txt @@ -0,0 +1,13 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or BytesKeyword or ContractKeyword or EnumKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or UfixedKeyword or UintKeyword. + ╭─[input.sol:1:1] + │ + 1 │ ╭─▶ using {invoke} for function(uint); + ┆ ┆ + 14 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +────╯ +References and definitions: diff --git a/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.8.13-success.txt b/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.8.13-success.txt new file mode 100644 index 0000000000..8dd4bdd0fb --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.8.13-success.txt @@ -0,0 +1,44 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ using {invoke} for function(uint); + │ ───┬── + │ ╰──── ref: 1 + │ + 3 │ function invoke(function(uint) x) { + │ ───┬── ┬ + │ ╰───────────────────── def: 1 + │ │ + │ ╰── def: 2 + 4 │ x(1); + │ ┬ + │ ╰── ref: 2 + │ + 7 │ function foo(uint x) {} + │ ─┬─ ┬ + │ ╰────────── def: 3 + │ │ + │ ╰── def: 4 + │ + 9 │ function test() { + │ ──┬─ + │ ╰─── def: 5 + 10 │ foo.invoke(); + │ ─┬─ ───┬── + │ ╰────────── ref: 3 + │ │ + │ ╰──── ref: 1 + │ + 12 │ function (uint) bar = foo; + │ ─┬─ ─┬─ + │ ╰───────── def: 6 + │ │ + │ ╰─── ref: 3 + 13 │ bar.invoke(); + │ ─┬─ ───┬── + │ ╰────────── ref: 6 + │ │ + │ ╰──── ref: 1 +────╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.8.4-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.8.4-failure.txt new file mode 100644 index 0000000000..612f25229b --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.8.4-failure.txt @@ -0,0 +1,13 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or BytesKeyword or ContractKeyword or EnumKeyword or ErrorKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or UfixedKeyword or UintKeyword. + ╭─[input.sol:1:1] + │ + 1 │ ╭─▶ using {invoke} for function(uint); + ┆ ┆ + 14 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +────╯ +References and definitions: diff --git a/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.8.8-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.8.8-failure.txt new file mode 100644 index 0000000000..d1063c781b --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/function_types/generated/0.8.8-failure.txt @@ -0,0 +1,13 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or BytesKeyword or ContractKeyword or EnumKeyword or ErrorKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or TypeKeyword or UfixedKeyword or UintKeyword. + ╭─[input.sol:1:1] + │ + 1 │ ╭─▶ using {invoke} for function(uint); + ┆ ┆ + 14 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +────╯ +References and definitions: diff --git a/crates/solidity/testing/snapshots/bindings_output/using/function_types/input.sol b/crates/solidity/testing/snapshots/bindings_output/using/function_types/input.sol new file mode 100644 index 0000000000..97c6017c09 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/function_types/input.sol @@ -0,0 +1,14 @@ +using {invoke} for function(uint); + +function invoke(function(uint) x) { + x(1); +} + +function foo(uint x) {} + +function test() { + foo.invoke(); + + function (uint) bar = foo; + bar.invoke(); +} diff --git a/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.4.11-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.4.11-failure.txt new file mode 100644 index 0000000000..fecd944dcb --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.4.11-failure.txt @@ -0,0 +1,38 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected ContractKeyword or ImportKeyword or InterfaceKeyword or LibraryKeyword or PragmaKeyword. + ╭─[counter.sol:1:1] + │ + 1 │ ╭─▶ struct Counter { + ┆ ┆ + 8 │ ├─▶ + │ │ + │ ╰────── Error occurred here. +───╯ +References and definitions: +References and definitions: + ╭─[main.sol:1:1] + │ + 1 │ import {Counter} from "counter.sol"; + │ ───┬─── + │ ╰───── def: 1 + │ │ + │ ╰───── unresolved + │ + 3 │ contract Test { + │ ──┬─ + │ ╰─── def: 2 + 4 │ function test(Counter memory c) public { + │ ──┬─ ───┬─── ┬ + │ ╰──────────────────── def: 3 + │ │ │ + │ ╰────────────── ref: 1 + │ │ + │ ╰── def: 4 + 5 │ c.increment(); + │ ┬ ────┬──── + │ ╰──────────── ref: 4 + │ │ + │ ╰────── unresolved +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.6.0-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.6.0-failure.txt new file mode 100644 index 0000000000..7b9380887a --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.6.0-failure.txt @@ -0,0 +1,47 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected ContractKeyword or EnumKeyword or ImportKeyword or InterfaceKeyword or LibraryKeyword or PragmaKeyword or StructKeyword. + ╭─[counter.sol:5:1] + │ + 5 │ ╭─▶ function increment(Counter memory _counter) public {} + ┆ ┆ + 8 │ ├─▶ + │ │ + │ ╰────── Error occurred here. +───╯ +References and definitions: + ╭─[counter.sol:1:1] + │ + 1 │ struct Counter { + │ ───┬─── + │ ╰───── def: 1 + 2 │ uint value; + │ ──┬── + │ ╰──── def: 2 +───╯ +References and definitions: + ╭─[main.sol:1:1] + │ + 1 │ import {Counter} from "counter.sol"; + │ ───┬─── + │ ╰───── def: 3 + │ │ + │ ╰───── ref: 1 + │ + 3 │ contract Test { + │ ──┬─ + │ ╰─── def: 4 + 4 │ function test(Counter memory c) public { + │ ──┬─ ───┬─── ┬ + │ ╰──────────────────── def: 5 + │ │ │ + │ ╰────────────── ref: 1 + │ │ + │ ╰── def: 6 + 5 │ c.increment(); + │ ┬ ────┬──── + │ ╰──────────── ref: 6 + │ │ + │ ╰────── unresolved +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.7.1-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.7.1-failure.txt new file mode 100644 index 0000000000..8818c91b3a --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.7.1-failure.txt @@ -0,0 +1,54 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected ContractKeyword or EnumKeyword or FunctionKeyword or ImportKeyword or InterfaceKeyword or LibraryKeyword or PragmaKeyword or StructKeyword. + ╭─[counter.sol:7:1] + │ + 7 │ ╭─▶ using {increment} for Counter global; + 8 │ ├─▶ + │ │ + │ ╰────── Error occurred here. +───╯ +References and definitions: + ╭─[counter.sol:1:1] + │ + 1 │ struct Counter { + │ ───┬─── + │ ╰───── def: 1 + 2 │ uint value; + │ ──┬── + │ ╰──── def: 2 + │ + 5 │ function increment(Counter memory _counter) public {} + │ ────┬──── ───┬─── ────┬─── + │ ╰────────────────────────────── def: 3 + │ │ │ + │ ╰───────────────────── ref: 1 + │ │ + │ ╰───── def: 4 +───╯ +References and definitions: + ╭─[main.sol:1:1] + │ + 1 │ import {Counter} from "counter.sol"; + │ ───┬─── + │ ╰───── def: 5 + │ │ + │ ╰───── ref: 1 + │ + 3 │ contract Test { + │ ──┬─ + │ ╰─── def: 6 + 4 │ function test(Counter memory c) public { + │ ──┬─ ───┬─── ┬ + │ ╰──────────────────── def: 7 + │ │ │ + │ ╰────────────── ref: 1 + │ │ + │ ╰── def: 8 + 5 │ c.increment(); + │ ┬ ────┬──── + │ ╰──────────── ref: 8 + │ │ + │ ╰────── unresolved +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.7.4-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.7.4-failure.txt new file mode 100644 index 0000000000..19f25ba046 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.7.4-failure.txt @@ -0,0 +1,54 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or ByteKeyword or BytesKeyword or ContractKeyword or EnumKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or UfixedKeyword or UintKeyword. + ╭─[counter.sol:7:1] + │ + 7 │ ╭─▶ using {increment} for Counter global; + 8 │ ├─▶ + │ │ + │ ╰────── Error occurred here. +───╯ +References and definitions: + ╭─[counter.sol:1:1] + │ + 1 │ struct Counter { + │ ───┬─── + │ ╰───── def: 1 + 2 │ uint value; + │ ──┬── + │ ╰──── def: 2 + │ + 5 │ function increment(Counter memory _counter) public {} + │ ────┬──── ───┬─── ────┬─── + │ ╰────────────────────────────── def: 3 + │ │ │ + │ ╰───────────────────── ref: 1 + │ │ + │ ╰───── def: 4 +───╯ +References and definitions: + ╭─[main.sol:1:1] + │ + 1 │ import {Counter} from "counter.sol"; + │ ───┬─── + │ ╰───── def: 5 + │ │ + │ ╰───── ref: 1 + │ + 3 │ contract Test { + │ ──┬─ + │ ╰─── def: 6 + 4 │ function test(Counter memory c) public { + │ ──┬─ ───┬─── ┬ + │ ╰──────────────────── def: 7 + │ │ │ + │ ╰────────────── ref: 1 + │ │ + │ ╰── def: 8 + 5 │ c.increment(); + │ ┬ ────┬──── + │ ╰──────────── ref: 8 + │ │ + │ ╰────── unresolved +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.8.0-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.8.0-failure.txt new file mode 100644 index 0000000000..dd2e75f8c2 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.8.0-failure.txt @@ -0,0 +1,54 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or BytesKeyword or ContractKeyword or EnumKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or UfixedKeyword or UintKeyword. + ╭─[counter.sol:7:1] + │ + 7 │ ╭─▶ using {increment} for Counter global; + 8 │ ├─▶ + │ │ + │ ╰────── Error occurred here. +───╯ +References and definitions: + ╭─[counter.sol:1:1] + │ + 1 │ struct Counter { + │ ───┬─── + │ ╰───── def: 1 + 2 │ uint value; + │ ──┬── + │ ╰──── def: 2 + │ + 5 │ function increment(Counter memory _counter) public {} + │ ────┬──── ───┬─── ────┬─── + │ ╰────────────────────────────── def: 3 + │ │ │ + │ ╰───────────────────── ref: 1 + │ │ + │ ╰───── def: 4 +───╯ +References and definitions: + ╭─[main.sol:1:1] + │ + 1 │ import {Counter} from "counter.sol"; + │ ───┬─── + │ ╰───── def: 5 + │ │ + │ ╰───── ref: 1 + │ + 3 │ contract Test { + │ ──┬─ + │ ╰─── def: 6 + 4 │ function test(Counter memory c) public { + │ ──┬─ ───┬─── ┬ + │ ╰──────────────────── def: 7 + │ │ │ + │ ╰────────────── ref: 1 + │ │ + │ ╰── def: 8 + 5 │ c.increment(); + │ ┬ ────┬──── + │ ╰──────────── ref: 8 + │ │ + │ ╰────── unresolved +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.8.13-success.txt b/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.8.13-success.txt new file mode 100644 index 0000000000..ee2ee4c284 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.8.13-success.txt @@ -0,0 +1,51 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +References and definitions: + ╭─[counter.sol:1:1] + │ + 1 │ struct Counter { + │ ───┬─── + │ ╰───── def: 1 + 2 │ uint value; + │ ──┬── + │ ╰──── def: 2 + │ + 5 │ function increment(Counter memory _counter) public {} + │ ────┬──── ───┬─── ────┬─── + │ ╰────────────────────────────── def: 3 + │ │ │ + │ ╰───────────────────── ref: 1 + │ │ + │ ╰───── def: 4 + │ + 7 │ using {increment} for Counter global; + │ ────┬──── ───┬─── + │ ╰─────────────────── ref: 3 + │ │ + │ ╰───── ref: 1 +───╯ +References and definitions: + ╭─[main.sol:1:1] + │ + 1 │ import {Counter} from "counter.sol"; + │ ───┬─── + │ ╰───── def: 5 + │ │ + │ ╰───── ref: 1 + │ + 3 │ contract Test { + │ ──┬─ + │ ╰─── def: 6 + 4 │ function test(Counter memory c) public { + │ ──┬─ ───┬─── ┬ + │ ╰──────────────────── def: 7 + │ │ │ + │ ╰────────────── ref: 1 + │ │ + │ ╰── def: 8 + 5 │ c.increment(); + │ ┬ ────┬──── + │ ╰──────────── ref: 8 + │ │ + │ ╰────── ref: 3 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.8.4-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.8.4-failure.txt new file mode 100644 index 0000000000..5b849d8c4b --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.8.4-failure.txt @@ -0,0 +1,54 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or BytesKeyword or ContractKeyword or EnumKeyword or ErrorKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or UfixedKeyword or UintKeyword. + ╭─[counter.sol:7:1] + │ + 7 │ ╭─▶ using {increment} for Counter global; + 8 │ ├─▶ + │ │ + │ ╰────── Error occurred here. +───╯ +References and definitions: + ╭─[counter.sol:1:1] + │ + 1 │ struct Counter { + │ ───┬─── + │ ╰───── def: 1 + 2 │ uint value; + │ ──┬── + │ ╰──── def: 2 + │ + 5 │ function increment(Counter memory _counter) public {} + │ ────┬──── ───┬─── ────┬─── + │ ╰────────────────────────────── def: 3 + │ │ │ + │ ╰───────────────────── ref: 1 + │ │ + │ ╰───── def: 4 +───╯ +References and definitions: + ╭─[main.sol:1:1] + │ + 1 │ import {Counter} from "counter.sol"; + │ ───┬─── + │ ╰───── def: 5 + │ │ + │ ╰───── ref: 1 + │ + 3 │ contract Test { + │ ──┬─ + │ ╰─── def: 6 + 4 │ function test(Counter memory c) public { + │ ──┬─ ───┬─── ┬ + │ ╰──────────────────── def: 7 + │ │ │ + │ ╰────────────── ref: 1 + │ │ + │ ╰── def: 8 + 5 │ c.increment(); + │ ┬ ────┬──── + │ ╰──────────── ref: 8 + │ │ + │ ╰────── unresolved +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.8.8-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.8.8-failure.txt new file mode 100644 index 0000000000..bdd41ff013 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/global/generated/0.8.8-failure.txt @@ -0,0 +1,54 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or BytesKeyword or ContractKeyword or EnumKeyword or ErrorKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or TypeKeyword or UfixedKeyword or UintKeyword. + ╭─[counter.sol:7:1] + │ + 7 │ ╭─▶ using {increment} for Counter global; + 8 │ ├─▶ + │ │ + │ ╰────── Error occurred here. +───╯ +References and definitions: + ╭─[counter.sol:1:1] + │ + 1 │ struct Counter { + │ ───┬─── + │ ╰───── def: 1 + 2 │ uint value; + │ ──┬── + │ ╰──── def: 2 + │ + 5 │ function increment(Counter memory _counter) public {} + │ ────┬──── ───┬─── ────┬─── + │ ╰────────────────────────────── def: 3 + │ │ │ + │ ╰───────────────────── ref: 1 + │ │ + │ ╰───── def: 4 +───╯ +References and definitions: + ╭─[main.sol:1:1] + │ + 1 │ import {Counter} from "counter.sol"; + │ ───┬─── + │ ╰───── def: 5 + │ │ + │ ╰───── ref: 1 + │ + 3 │ contract Test { + │ ──┬─ + │ ╰─── def: 6 + 4 │ function test(Counter memory c) public { + │ ──┬─ ───┬─── ┬ + │ ╰──────────────────── def: 7 + │ │ │ + │ ╰────────────── ref: 1 + │ │ + │ ╰── def: 8 + 5 │ c.increment(); + │ ┬ ────┬──── + │ ╰──────────── ref: 8 + │ │ + │ ╰────── unresolved +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/global/input.sol b/crates/solidity/testing/snapshots/bindings_output/using/global/input.sol new file mode 100644 index 0000000000..6fd2e3113b --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/global/input.sol @@ -0,0 +1,17 @@ +// ---- path: counter.sol +struct Counter { + uint value; +} + +function increment(Counter memory _counter) public {} + +using {increment} for Counter global; + +// ---- path: main.sol +import {Counter} from "counter.sol"; + +contract Test { + function test(Counter memory c) public { + c.increment(); + } +} diff --git a/crates/solidity/testing/snapshots/bindings_output/using/in_contract/generated/0.4.11-success.txt b/crates/solidity/testing/snapshots/bindings_output/using/in_contract/generated/0.4.11-success.txt new file mode 100644 index 0000000000..8f55bce19a --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/in_contract/generated/0.4.11-success.txt @@ -0,0 +1,49 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ library Lib { + │ ─┬─ + │ ╰─── def: 1 + 2 │ struct Counter { + │ ───┬─── + │ ╰───── def: 2 + 3 │ uint value; + │ ──┬── + │ ╰──── def: 3 + │ + 6 │ function increment(Counter memory _counter) public {} + │ ────┬──── ───┬─── ────┬─── + │ ╰────────────────────────────── def: 4 + │ │ │ + │ ╰───────────────────── ref: 2 + │ │ + │ ╰───── def: 5 + │ + 9 │ contract Test { + │ ──┬─ + │ ╰─── def: 6 + 10 │ using Lib for Lib.Counter; + │ ─┬─ ─┬─ ───┬─── + │ ╰─────────────────── ref: 1 + │ │ │ + │ ╰─────────── ref: 1 + │ │ + │ ╰───── ref: 2 + │ + 12 │ function test(Lib.Counter memory c) public { + │ ──┬─ ─┬─ ───┬─── ┬ + │ ╰──────────────────────── def: 7 + │ │ │ │ + │ ╰──────────────────── ref: 1 + │ │ │ + │ ╰────────────── ref: 2 + │ │ + │ ╰── def: 8 + 13 │ c.increment(); + │ ┬ ────┬──── + │ ╰──────────── ref: 8 + │ │ + │ ╰────── ref: 4 +────╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/in_contract/input.sol b/crates/solidity/testing/snapshots/bindings_output/using/in_contract/input.sol new file mode 100644 index 0000000000..7ded97ba0b --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/in_contract/input.sol @@ -0,0 +1,15 @@ +library Lib { + struct Counter { + uint value; + } + + function increment(Counter memory _counter) public {} +} + +contract Test { + using Lib for Lib.Counter; + + function test(Lib.Counter memory c) public { + c.increment(); + } +} diff --git a/crates/solidity/testing/snapshots/bindings_output/using/in_library/generated/0.4.11-success.txt b/crates/solidity/testing/snapshots/bindings_output/using/in_library/generated/0.4.11-success.txt new file mode 100644 index 0000000000..0822d8a3a3 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/in_library/generated/0.4.11-success.txt @@ -0,0 +1,49 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ library Lib { + │ ─┬─ + │ ╰─── def: 1 + 2 │ struct Counter { + │ ───┬─── + │ ╰───── def: 2 + 3 │ uint value; + │ ──┬── + │ ╰──── def: 3 + │ + 6 │ function increment(Counter memory _counter) public {} + │ ────┬──── ───┬─── ────┬─── + │ ╰────────────────────────────── def: 4 + │ │ │ + │ ╰───────────────────── ref: 2 + │ │ + │ ╰───── def: 5 + │ + 9 │ library Utils { + │ ──┬── + │ ╰──── def: 6 + 10 │ using Lib for Lib.Counter; + │ ─┬─ ─┬─ ───┬─── + │ ╰─────────────────── ref: 1 + │ │ │ + │ ╰─────────── ref: 1 + │ │ + │ ╰───── ref: 2 + │ + 12 │ function test(Lib.Counter memory c) public { + │ ──┬─ ─┬─ ───┬─── ┬ + │ ╰──────────────────────── def: 7 + │ │ │ │ + │ ╰──────────────────── ref: 1 + │ │ │ + │ ╰────────────── ref: 2 + │ │ + │ ╰── def: 8 + 13 │ c.increment(); + │ ┬ ────┬──── + │ ╰──────────── ref: 8 + │ │ + │ ╰────── ref: 4 +────╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/in_library/input.sol b/crates/solidity/testing/snapshots/bindings_output/using/in_library/input.sol new file mode 100644 index 0000000000..14f1037300 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/in_library/input.sol @@ -0,0 +1,15 @@ +library Lib { + struct Counter { + uint value; + } + + function increment(Counter memory _counter) public {} +} + +library Utils { + using Lib for Lib.Counter; + + function test(Lib.Counter memory c) public { + c.increment(); + } +} diff --git a/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.4.11-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.4.11-failure.txt new file mode 100644 index 0000000000..ae1890fdba --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.4.11-failure.txt @@ -0,0 +1,13 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected ContractKeyword or ImportKeyword or InterfaceKeyword or LibraryKeyword or PragmaKeyword. + ╭─[input.sol:1:1] + │ + 1 │ ╭─▶ struct Counter { + ┆ ┆ + 13 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +────╯ +References and definitions: diff --git a/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.6.0-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.6.0-failure.txt new file mode 100644 index 0000000000..f3f1f399ce --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.6.0-failure.txt @@ -0,0 +1,22 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected ContractKeyword or EnumKeyword or ImportKeyword or InterfaceKeyword or LibraryKeyword or PragmaKeyword or StructKeyword. + ╭─[input.sol:5:1] + │ + 5 │ ╭─▶ function increment(Counter memory _counter) public {} + ┆ ┆ + 13 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +────╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ struct Counter { + │ ───┬─── + │ ╰───── def: 1 + 2 │ uint value; + │ ──┬── + │ ╰──── def: 2 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.7.1-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.7.1-failure.txt new file mode 100644 index 0000000000..8d6d2aff39 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.7.1-failure.txt @@ -0,0 +1,30 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected ContractKeyword or EnumKeyword or FunctionKeyword or ImportKeyword or InterfaceKeyword or LibraryKeyword or PragmaKeyword or StructKeyword. + ╭─[input.sol:7:1] + │ + 7 │ ╭─▶ using {increment} for Counter; + ┆ ┆ + 13 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +────╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ struct Counter { + │ ───┬─── + │ ╰───── def: 1 + 2 │ uint value; + │ ──┬── + │ ╰──── def: 2 + │ + 5 │ function increment(Counter memory _counter) public {} + │ ────┬──── ───┬─── ────┬─── + │ ╰────────────────────────────── def: 3 + │ │ │ + │ ╰───────────────────── ref: 1 + │ │ + │ ╰───── def: 4 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.7.4-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.7.4-failure.txt new file mode 100644 index 0000000000..a4414df943 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.7.4-failure.txt @@ -0,0 +1,30 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or ByteKeyword or BytesKeyword or ContractKeyword or EnumKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or UfixedKeyword or UintKeyword. + ╭─[input.sol:7:1] + │ + 7 │ ╭─▶ using {increment} for Counter; + ┆ ┆ + 13 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +────╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ struct Counter { + │ ───┬─── + │ ╰───── def: 1 + 2 │ uint value; + │ ──┬── + │ ╰──── def: 2 + │ + 5 │ function increment(Counter memory _counter) public {} + │ ────┬──── ───┬─── ────┬─── + │ ╰────────────────────────────── def: 3 + │ │ │ + │ ╰───────────────────── ref: 1 + │ │ + │ ╰───── def: 4 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.8.0-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.8.0-failure.txt new file mode 100644 index 0000000000..447ed737f3 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.8.0-failure.txt @@ -0,0 +1,30 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or BytesKeyword or ContractKeyword or EnumKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or UfixedKeyword or UintKeyword. + ╭─[input.sol:7:1] + │ + 7 │ ╭─▶ using {increment} for Counter; + ┆ ┆ + 13 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +────╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ struct Counter { + │ ───┬─── + │ ╰───── def: 1 + 2 │ uint value; + │ ──┬── + │ ╰──── def: 2 + │ + 5 │ function increment(Counter memory _counter) public {} + │ ────┬──── ───┬─── ────┬─── + │ ╰────────────────────────────── def: 3 + │ │ │ + │ ╰───────────────────── ref: 1 + │ │ + │ ╰───── def: 4 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.8.13-success.txt b/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.8.13-success.txt new file mode 100644 index 0000000000..cec8162ea1 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.8.13-success.txt @@ -0,0 +1,42 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ struct Counter { + │ ───┬─── + │ ╰───── def: 1 + 2 │ uint value; + │ ──┬── + │ ╰──── def: 2 + │ + 5 │ function increment(Counter memory _counter) public {} + │ ────┬──── ───┬─── ────┬─── + │ ╰────────────────────────────── def: 3 + │ │ │ + │ ╰───────────────────── ref: 1 + │ │ + │ ╰───── def: 4 + │ + 7 │ using {increment} for Counter; + │ ────┬──── ───┬─── + │ ╰─────────────────── ref: 3 + │ │ + │ ╰───── ref: 1 + │ + 9 │ contract Test { + │ ──┬─ + │ ╰─── def: 5 + 10 │ function test(Counter memory c) public { + │ ──┬─ ───┬─── ┬ + │ ╰──────────────────── def: 6 + │ │ │ + │ ╰────────────── ref: 1 + │ │ + │ ╰── def: 7 + 11 │ c.increment(); + │ ┬ ────┬──── + │ ╰──────────── ref: 7 + │ │ + │ ╰────── ref: 3 +────╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.8.4-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.8.4-failure.txt new file mode 100644 index 0000000000..93c5946dce --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.8.4-failure.txt @@ -0,0 +1,30 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or BytesKeyword or ContractKeyword or EnumKeyword or ErrorKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or UfixedKeyword or UintKeyword. + ╭─[input.sol:7:1] + │ + 7 │ ╭─▶ using {increment} for Counter; + ┆ ┆ + 13 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +────╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ struct Counter { + │ ───┬─── + │ ╰───── def: 1 + 2 │ uint value; + │ ──┬── + │ ╰──── def: 2 + │ + 5 │ function increment(Counter memory _counter) public {} + │ ────┬──── ───┬─── ────┬─── + │ ╰────────────────────────────── def: 3 + │ │ │ + │ ╰───────────────────── ref: 1 + │ │ + │ ╰───── def: 4 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.8.8-failure.txt b/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.8.8-failure.txt new file mode 100644 index 0000000000..8c897d071d --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/top_level/generated/0.8.8-failure.txt @@ -0,0 +1,30 @@ +# This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +Parse errors: +Error: Expected AddressKeyword or BoolKeyword or BytesKeyword or ContractKeyword or EnumKeyword or ErrorKeyword or FixedKeyword or FunctionKeyword or Identifier or ImportKeyword or IntKeyword or InterfaceKeyword or LibraryKeyword or MappingKeyword or PragmaKeyword or StringKeyword or StructKeyword or TypeKeyword or UfixedKeyword or UintKeyword. + ╭─[input.sol:7:1] + │ + 7 │ ╭─▶ using {increment} for Counter; + ┆ ┆ + 13 │ ├─▶ } + │ │ + │ ╰─────── Error occurred here. +────╯ +References and definitions: + ╭─[input.sol:1:1] + │ + 1 │ struct Counter { + │ ───┬─── + │ ╰───── def: 1 + 2 │ uint value; + │ ──┬── + │ ╰──── def: 2 + │ + 5 │ function increment(Counter memory _counter) public {} + │ ────┬──── ───┬─── ────┬─── + │ ╰────────────────────────────── def: 3 + │ │ │ + │ ╰───────────────────── ref: 1 + │ │ + │ ╰───── def: 4 +───╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/using/top_level/input.sol b/crates/solidity/testing/snapshots/bindings_output/using/top_level/input.sol new file mode 100644 index 0000000000..b4e4394beb --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/using/top_level/input.sol @@ -0,0 +1,13 @@ +struct Counter { + uint value; +} + +function increment(Counter memory _counter) public {} + +using {increment} for Counter; + +contract Test { + function test(Counter memory c) public { + c.increment(); + } +}