diff --git a/crates/metaslang/bindings/src/builder/functions.rs b/crates/metaslang/bindings/src/builder/functions.rs index 67a1f9eeff..5bdab61182 100644 --- a/crates/metaslang/bindings/src/builder/functions.rs +++ b/crates/metaslang/bindings/src/builder/functions.rs @@ -87,7 +87,7 @@ mod resolver { let path_to_resolve = parameters.param()?.into_string()?; parameters.finish()?; - let context_file_descriptor = FileDescriptor::from_string(&context_path); + let context_file_descriptor = FileDescriptor::try_from(&context_path); let Ok(FileDescriptor::User(context_user_path)) = context_file_descriptor else { // Since the path resolver should only map to user paths from // user paths, it is an error to attempt to resolve a path in @@ -127,7 +127,7 @@ mod resolver { let file_path = parameters.param()?.into_string()?; parameters.finish()?; - let Ok(file_descriptor) = FileDescriptor::from_string(&file_path) else { + let Ok(file_descriptor) = FileDescriptor::try_from(&file_path) else { return Err(ExecutionError::FunctionFailed( "is-system-file".into(), "Parameter is not a valid file path".into(), diff --git a/crates/metaslang/bindings/src/builder/mod.rs b/crates/metaslang/bindings/src/builder/mod.rs index 03eb7d16c9..3a27e9b1cc 100644 --- a/crates/metaslang/bindings/src/builder/mod.rs +++ b/crates/metaslang/bindings/src/builder/mod.rs @@ -345,6 +345,8 @@ static PRECEDENCE_ATTR: &str = "precedence"; // Global variables /// Name of the variable used to pass the root node. pub const ROOT_NODE_VAR: &str = "ROOT_NODE"; +/// Name of the variable used to pass the jump to scope node. +pub const JUMP_TO_SCOPE_NODE_VAR: &str = "JUMP_TO_SCOPE_NODE"; /// Name of the variable used to pass the file path. pub const FILE_PATH_VAR: &str = "FILE_PATH"; @@ -405,6 +407,11 @@ impl<'a, KT: KindTypes + 'static> Builder<'a, KT> { .add(ROOT_NODE_VAR.into(), root_node.into()) .expect("Failed to set ROOT_NODE"); + let jump_to_scope_node = self.inject_node(NodeID::jump_to()); + variables + .add(JUMP_TO_SCOPE_NODE_VAR.into(), jump_to_scope_node.into()) + .expect("Failed to set JUMP_TO_SCOPE_NODE"); + #[cfg(feature = "__private_testing_utils")] { // For debugging purposes only @@ -418,6 +425,17 @@ impl<'a, KT: KindTypes + 'static> Builder<'a, KT> { ROOT_NODE_VAR.to_string(), ) .expect("Failed to set ROOT_NODE variable name for debugging"); + + self.graph[jump_to_scope_node] + .attributes + .add( + [DEBUG_ATTR_PREFIX, "msgb_variable"] + .concat() + .as_str() + .into(), + JUMP_TO_SCOPE_NODE_VAR.to_string(), + ) + .expect("Failed to set JUMP_TO_SCOPE_NODE variable name for debugging"); } variables diff --git a/crates/metaslang/bindings/src/lib.rs b/crates/metaslang/bindings/src/lib.rs index 57ef3048ff..ccc855fca5 100644 --- a/crates/metaslang/bindings/src/lib.rs +++ b/crates/metaslang/bindings/src/lib.rs @@ -60,6 +60,7 @@ pub enum FileDescriptor { System(String), } +#[derive(Debug)] pub(crate) struct FileDescriptorError; impl FileDescriptor { @@ -73,14 +74,21 @@ impl FileDescriptor { } } - pub(crate) fn from_string(value: &str) -> Result { - if let Some(path) = value.strip_prefix("user:") { - Ok(FileDescriptor::User(path.into())) - } else if let Some(path) = value.strip_prefix("system:") { - Ok(FileDescriptor::System(path.into())) - } else { - Err(FileDescriptorError) - } + pub(crate) fn try_from(value: &str) -> Result { + value + .strip_prefix("user:") + .map(|path| FileDescriptor::User(path.into())) + .or_else(|| { + value + .strip_prefix("system:") + .map(|path| FileDescriptor::System(path.into())) + }) + .ok_or(FileDescriptorError) + } + + pub(crate) fn from(value: &str) -> Self { + Self::try_from(value) + .unwrap_or_else(|_| panic!("{value} should be a valid file descriptor")) } pub fn get_path(&self) -> &str { @@ -372,8 +380,8 @@ impl<'a, KT: KindTypes + 'static> Definition<'a, KT> { pub fn get_file(&self) -> FileDescriptor { self.owner.stack_graph[self.handle] .file() - .and_then(|file| FileDescriptor::from_string(self.owner.stack_graph[file].name()).ok()) - .unwrap_or_else(|| unreachable!("Definition does not have a valid file descriptor")) + .map(|file| FileDescriptor::from(self.owner.stack_graph[file].name())) + .expect("Definition does not have a valid file descriptor") } pub(crate) fn has_tag(&self, tag: Tag) -> bool { @@ -459,8 +467,8 @@ impl<'a, KT: KindTypes + 'static> Reference<'a, KT> { pub fn get_file(&self) -> FileDescriptor { self.owner.stack_graph[self.handle] .file() - .and_then(|file| FileDescriptor::from_string(self.owner.stack_graph[file].name()).ok()) - .unwrap_or_else(|| unreachable!("Reference does not have a valid file descriptor")) + .map(|file| FileDescriptor::from(self.owner.stack_graph[file].name())) + .expect("Reference does not have a valid file descriptor") } pub fn jump_to_definition(&self) -> Result, ResolutionError<'a, KT>> { diff --git a/crates/metaslang/bindings/src/resolver/mod.rs b/crates/metaslang/bindings/src/resolver/mod.rs index b4487a5446..46a92cdc0f 100644 --- a/crates/metaslang/bindings/src/resolver/mod.rs +++ b/crates/metaslang/bindings/src/resolver/mod.rs @@ -129,6 +129,7 @@ impl<'a, KT: KindTypes + 'static> Resolver<'a, KT> { return; } self.mark_down_aliases(); + self.mark_down_built_ins(); self.rank_c3_methods(); self.results.sort_by(|a, b| b.score.total_cmp(&a.score)); } @@ -157,6 +158,14 @@ impl<'a, KT: KindTypes + 'static> Resolver<'a, KT> { } } + fn mark_down_built_ins(&mut self) { + for result in &mut self.results { + if result.definition.get_file().is_system() { + result.score -= 200.0; + } + } + } + fn rank_c3_methods(&mut self) { // compute the linearisation to use for ranking let caller_parents = self.reference.resolve_parents(); @@ -184,9 +193,12 @@ impl<'a, KT: KindTypes + 'static> Resolver<'a, KT> { let caller_context_index = mro.iter().position(|x| x == caller_context); let super_call = self.reference.has_tag(Tag::Super); - // mark up methods tagged C3 according to the computed linearisation + // Mark up user methods tagged C3 according to the computed linearisation. + // Because only contract functions are marked with the C3 tag, this has + // the added benefit of prioritizing them over globally defined + // functions. for result in &mut self.results { - if result.definition.has_tag(Tag::C3) { + if result.definition.has_tag(Tag::C3) && result.definition.get_file().is_user() { let definition_parents = result.definition.resolve_parents(); let Some(definition_context) = definition_parents.first() else { // this should not normally happen: the definition is tagged diff --git a/crates/solidity/inputs/language/bindings/rules.msgb b/crates/solidity/inputs/language/bindings/rules.msgb index db16a5e17b..42a3bd16e9 100644 --- a/crates/solidity/inputs/language/bindings/rules.msgb +++ b/crates/solidity/inputs/language/bindings/rules.msgb @@ -1,5 +1,6 @@ global ROOT_NODE global FILE_PATH +global JUMP_TO_SCOPE_NODE attribute node_definition = node => type = "pop_symbol", node_symbol = node, is_definition attribute node_reference = node => type = "push_symbol", node_symbol = node, is_reference @@ -9,10 +10,18 @@ attribute push_symbol = symbol => type = "push_symbol", symbol = symbol attribute symbol_definition = symbol => type = "pop_symbol", symbol = symbol, is_definition attribute symbol_reference = symbol => type = "push_symbol", symbol = symbol, is_reference +attribute scoped_node_definition = node => type = "pop_scoped_symbol", node_symbol = node, is_definition +attribute scoped_node_reference = node => type = "push_scoped_symbol", node_symbol = node, is_reference +attribute pop_scoped_symbol = symbol => type = "pop_scoped_symbol", symbol = symbol +attribute push_scoped_symbol = symbol => type = "push_scoped_symbol", symbol = symbol + ;; Keeps a link to the enclosing contract definition to provide a parent for ;; method calls (to correctly resolve virtual methods) inherit .enclosing_def + inherit .parent_scope +inherit .lexical_scope + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Source unit (aka .sol file) @@ -77,11 +86,12 @@ inherit .parent_scope ;; Special case for built-ins: we want to export all symbols in the contract: ;; functions, types and state variables. All built-in symbols are defined in an -;; internal contract named '$BuiltIns$' so we need to export all its members and -;; type members directly as a source unit definition. +;; internal contract named '%BuiltIns%' (renamed from '$BuiltIns$') so we need +;; to export all its members and type members directly as a source unit +;; definition. ;; __SLANG_SOLIDITY_BUILT_INS_CONTRACT_NAME__ keep in sync with built-ins generation. @source_unit [SourceUnit [SourceUnitMembers - [SourceUnitMember @contract [ContractDefinition name: ["$BuiltIns$"]]] + [SourceUnitMember @contract [ContractDefinition name: ["%BuiltIns%"]]] ]] { if (is-system-file FILE_PATH) { edge @source_unit.defs -> @contract.members @@ -91,7 +101,6 @@ inherit .parent_scope } @source_unit [SourceUnit [SourceUnitMembers [SourceUnitMember @using [UsingDirective]]]] { - let @using.lexical_scope = @source_unit.lexical_scope edge @source_unit.lexical_scope -> @using.def } @@ -258,6 +267,9 @@ inherit .parent_scope edge heir.type_members -> type_member edge type_member -> @type_name.push_begin + + ; Resolve the "super" keyword to the inherited type + edge heir.super -> @type_name.push_begin } ;; NOTE: we use anchors here to prevent the query engine from returning all the @@ -339,19 +351,28 @@ inherit .parent_scope ;; ... and make it available in the contract's lexical scope edge @contract.lexical_scope -> this + ; Resolve the "this" keyword to the contract itself + node name_push + attr (name_push) push_symbol = (source-text @name) + edge this -> name_push + edge name_push -> @contract.lexical_scope + ;; Define "super" effectively as if it was a state variable of a type connected by our super_scope ;; super_scope will later connect to the base contract defs directly - node super - attr (super) pop_symbol = "super" + node @contract.super + attr (@contract.super) pop_symbol = "super" node super_typeof attr (super_typeof) push_symbol = "@typeof" - edge super -> super_typeof + edge @contract.super -> super_typeof edge super_typeof -> @contract.super_scope ;; Finally make "super" available in the contract's lexical scope for function bodies to use - edge @contract.lexical_scope -> super + edge @contract.lexical_scope -> @contract.super + + ; NOTE: The keyword "super" itself resolves to each of its parent contracts. + ; See the related rules in the InheritanceSpecifier section above. ;; This defines the sink of edges added from base contracts when setting this ;; contract as the compilation context @@ -362,12 +383,21 @@ inherit .parent_scope ;; (recursively) node super_import attr (super_import) pop_symbol = "." - edge super -> super_import + edge @contract.super -> super_import ;; This defines the source side of edges added to base contracts when setting ;; a contract as compilation context; this allows this contract (a base) to ;; access virtual methods in any sub-contract defined in the hierarchy attr (@contract.def) import_nodes = [@contract.lexical_scope, super_import] + + ; Path to resolve the built-in type for type() expressions + node type + attr (type) pop_symbol = "%type" + node type_contract_type + attr (type_contract_type) push_symbol = "%typeContractType" + edge @contract.def -> type + edge type -> type_contract_type + edge type_contract_type -> @contract.lexical_scope } @contract [ContractDefinition @specifier [InheritanceSpecifier]] { @@ -403,7 +433,6 @@ inherit .parent_scope @contract [ContractDefinition [ContractMembers [ContractMember @using [UsingDirective]] ]] { - let @using.lexical_scope = @contract.lexical_scope edge @contract.lexical_scope -> @using.def } @@ -446,6 +475,15 @@ inherit .parent_scope attr (@function.def) parents = [@contract.def] } +@contract [ContractDefinition [ContractMembers + [ContractMember @function [FunctionDefinition + [FunctionAttributes [FunctionAttribute ([ExternalKeyword] | [PublicKeyword])]] + ]] +]] { + ; public or external functions are also accessible through the contract type + edge @contract.type_members -> @function.def +} + @contract [ContractDefinition members: [ContractMembers [ContractMember @modifier [ModifierDefinition]] ]] { @@ -505,16 +543,29 @@ inherit .parent_scope attr (type_member) pop_symbol = "." edge @interface.def -> type_member edge type_member -> @interface.type_members + + ; Path to resolve the built-in type for type() expressions + node type + attr (type) pop_symbol = "%type" + node type_interface_type + attr (type_interface_type) push_symbol = "%typeInterfaceType" + edge @interface.def -> type + edge type -> type_interface_type + edge type_interface_type -> @interface.lexical_scope } @interface [InterfaceDefinition @specifier [InheritanceSpecifier]] { let @specifier.heir = @interface attr (@interface.def) parents = @specifier.parent_refs + + ; Define a dummy "super" node required by the rules for InheritanceSpecifier + node @interface.super } @interface [InterfaceDefinition [InterfaceMembers [ContractMember @member ( [EnumDefinition] + | [FunctionDefinition] | [StructDefinition] | [EventDefinition] | [ErrorDefinition] @@ -525,6 +576,8 @@ inherit .parent_scope edge @interface.type_members -> @member.def } +;; Allow references (eg. variables of the interface type) to the interface to +;; access functions @interface [InterfaceDefinition members: [InterfaceMembers item: [ContractMember @function variant: [FunctionDefinition]] ]] { @@ -553,17 +606,23 @@ inherit .parent_scope } @library [LibraryDefinition @name name: [Identifier]] { - node def - attr (def) node_definition = @name - attr (def) definiens_node = @library - - edge @library.def -> def + attr (@library.def) node_definition = @name + attr (@library.def) definiens_node = @library node member attr (member) pop_symbol = "." - edge def -> member + edge @library.def -> member edge member -> @library.members + + ; Path to resolve the built-in type for type() expressions (same as contracts) + node type + attr (type) pop_symbol = "%type" + node type_library_type + attr (type_library_type) push_symbol = "%typeContractType" + edge @library.def -> type + edge type -> type_library_type + edge type_library_type -> @library.lexical_scope } @library [LibraryDefinition [LibraryMembers @@ -583,7 +642,6 @@ inherit .parent_scope @library [LibraryDefinition [LibraryMembers [ContractMember @using [UsingDirective]] ]] { - let @using.lexical_scope = @library.lexical_scope edge @library.lexical_scope -> @using.def } @@ -655,6 +713,14 @@ inherit .parent_scope edge @type_name.type_ref -> @using.lexical_scope } +[ContractMember @using [UsingDirective [UsingTarget [Asterisk]]]] { + ; using X for * is only allowed inside contracts + node star + attr (star) pop_symbol = "@*" + edge @using.def -> star + edge star -> @using.clause +} + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Type names @@ -753,19 +819,28 @@ inherit .parent_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 + ; The mapping's type exposes the `%index` (ie. `[]`) operator that returns the value type + ; This is similar to arrays, only in that case we have a built-in type where + ; we can define an index function. For mappings we hard-code in the rules directly. + node typeof_input attr (typeof_input) pop_symbol = "@typeof" + node index_member + attr (index_member) pop_symbol = "." node index - attr (index) pop_symbol = "[]" + attr (index) pop_symbol = "%index" + node index_call + attr (index_call) pop_symbol = "()" node typeof_output attr (typeof_output) push_symbol = "@typeof" edge @mapping.output -> typeof_input - edge typeof_input -> index - edge index -> typeof_output + edge typeof_input -> index_member + edge index_member -> index + edge index -> index_call + edge index_call -> typeof_output edge typeof_output -> @value_type.output ; resolve the value type through our scope @@ -782,45 +857,52 @@ inherit .parent_scope node @array.output } -@array [ArrayTypeName @type_name [TypeName]] { - ; 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" - - node index - attr (index) pop_symbol = "[]" - - node typeof_output - attr (typeof_output) push_symbol = "@typeof" +@array [ArrayTypeName [TypeName] index: [Expression]] { + let @array.type = "%arrayFixed" +} - edge @array.output -> typeof_input - edge typeof_input -> index - edge index -> typeof_output - edge typeof_output -> @type_name.output +@array [ArrayTypeName [OpenBracket] . [CloseBracket]] { + let @array.type = "%array" +} - ; finally resolve the inner type through our parent scope +@array [ArrayTypeName @type_name [TypeName]] { + ; First define the normal, reference route: + + ; We first push the array type `%array`, which should connect to two distinct paths: + ; 1. the typed path, which will use a jump scope entry to resolve the element type + ; 2. the hard-coded path to connect to any `using` directive + node array + attr (array) push_symbol = @array.type + edge @array.output -> array + + ; For the first path, we need to define a scope jump entry for resolving the element type of the array + node entry + attr (entry) is_exported + node element + attr (element) pop_symbol = "%element" + edge entry -> element + edge element -> @type_name.output + + ; And then the path itself + node params + attr (params) push_scoped_symbol = "<>", scope = entry + edge array -> params + + ; Second path, for `using` directives + edge array -> @type_name.output + + ; Finally, both ends connect to our lexical scope + edge params -> @array.lexical_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 = "%[]" + ; Now we define the "definition" route (aka. the pop route), to use in `using` directives only + ; This is essentially the reverse of the second path above + node pop_array + attr (pop_array) pop_symbol = @array.type 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]] { - edge @size.lexical_scope -> @array.lexical_scope + edge @type_name.pop_end -> pop_array + let @array.pop_end = pop_array } @@ -828,21 +910,30 @@ inherit .parent_scope ;;; Function types ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -@ftype [FunctionType] { +@ftype [FunctionType @attrs [FunctionTypeAttributes]] { + ; Compute the built-in type of the function + ; %functionExternal provides access to .selector and .address + var type = "%function" + scan (source-text @attrs) { + "external" { + set type = "%functionExternal" + } + } + 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" + attr (function_type) push_symbol = type 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" + attr (pop_function_type) pop_symbol = type let @ftype.pop_begin = pop_function_type let @ftype.pop_end = pop_function_type @@ -969,7 +1060,14 @@ inherit .parent_scope edge @params.defs -> @param.def } -@function [FunctionDefinition] { +@function [FunctionDefinition @attrs [FunctionAttributes]] { + var function_type = "%function" + scan (source-text @attrs) { + "\\b(public|external)\\b" { + set function_type = "%functionExternal" + } + } + node @function.lexical_scope node @function.def @@ -978,7 +1076,7 @@ inherit .parent_scope node typeof attr (typeof) push_symbol = "@typeof" node type_function - attr (type_function) push_symbol = "%function" + attr (type_function) push_symbol = function_type edge @function.def -> typeof edge typeof -> type_function edge type_function -> @function.lexical_scope @@ -1089,6 +1187,22 @@ inherit .parent_scope edge @contract.def -> @constructor.def } +;; Solidity < 0.5.0 constructors were declared as functions of the contract's name +@contract [ContractDefinition + @contract_name [Identifier] + [ContractMembers [ContractMember [FunctionDefinition + [FunctionName @function_name [Identifier]] + @params [ParametersDeclaration] + ]]] +] { + if (version-matches "< 0.5.0") { + if (eq (source-text @contract_name) (source-text @function_name)) { + ; Connect to paramaters for named argument resolution + edge @contract.def -> @params.names + } + } +} + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Fallback and receive functions @@ -1158,6 +1272,17 @@ inherit .parent_scope attr (@modifier.def) definiens_node = @modifier edge @body.lexical_scope -> @modifier.lexical_scope + + ; Special case: bind the place holder statement `_` to the built-in + ; `%placeholder`. This only happens in the body of a modifier. + node placeholder_pop + attr (placeholder_pop) pop_symbol = "_" + node placeholder_ref + attr (placeholder_ref) push_symbol = "%placeholder" + + edge @body.lexical_scope -> placeholder_pop + edge placeholder_pop -> placeholder_ref + edge placeholder_ref -> @modifier.lexical_scope } @modifier [ModifierDefinition @params [ParametersDeclaration]] { @@ -1256,10 +1381,6 @@ inherit .parent_scope node @expr_stmt.defs } -@expr_stmt [ExpressionStatement @expr [Expression]] { - edge @expr.lexical_scope -> @expr_stmt.lexical_scope -} - ;;; Variable declaration statements @@ -1273,12 +1394,6 @@ inherit .parent_scope node @var_decl.defs } -@var_decl [VariableDeclarationStatement - value: [VariableDeclarationValue @expr [Expression]] -] { - edge @expr.lexical_scope -> @var_decl.lexical_scope -} - @var_decl [VariableDeclarationStatement [VariableDeclarationType @var_type [TypeName]] @name name: [Identifier] @@ -1310,12 +1425,6 @@ inherit .parent_scope node @tuple_decon.defs } -@tuple_decon [TupleDeconstructionStatement - @expr expression: [Expression] -] { - edge @expr.lexical_scope -> @tuple_decon.lexical_scope -} - @tuple_decon [TupleDeconstructionStatement [TupleDeconstructionElements [TupleDeconstructionElement @tuple_member [TupleMember variant: [UntypedTupleMember @@ -1359,10 +1468,6 @@ inherit .parent_scope ;; If conditionals -@stmt [Statement [IfStatement @condition condition: [Expression]]] { - edge @condition.lexical_scope -> @stmt.lexical_scope -} - @stmt [Statement [IfStatement @body body: [Statement]]] { edge @body.lexical_scope -> @stmt.lexical_scope if (version-matches "< 0.5.0") { @@ -1398,6 +1503,10 @@ inherit .parent_scope } @stmt [Statement [ForStatement @iter_expr iterator: [Expression]]] { + ; for the iterator expression we need an independent scope node that can + ; connect to both the for-statement *and* the definitions in the init + ; expression + node @iter_expr.lexical_scope edge @iter_expr.lexical_scope -> @stmt.lexical_scope edge @iter_expr.lexical_scope -> @stmt.init_defs } @@ -1415,10 +1524,6 @@ inherit .parent_scope ;; While loops -@stmt [Statement [WhileStatement @condition condition: [Expression]]] { - edge @condition.lexical_scope -> @stmt.lexical_scope -} - @stmt [Statement [WhileStatement @body body: [Statement]]] { edge @body.lexical_scope -> @stmt.lexical_scope if (version-matches "< 0.5.0") { @@ -1435,10 +1540,6 @@ inherit .parent_scope } } -@stmt [Statement [DoWhileStatement @condition condition: [Expression]]] { - edge @condition.lexical_scope -> @stmt.lexical_scope -} - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Error handling @@ -1446,10 +1547,6 @@ inherit .parent_scope ;;; Try-catch statements -@stmt [Statement [TryStatement @expr expression: [Expression]]] { - edge @expr.lexical_scope -> @stmt.lexical_scope -} - @stmt [Statement [TryStatement @body body: [Block]]] { edge @body.lexical_scope -> @stmt.lexical_scope } @@ -1503,11 +1600,6 @@ inherit .parent_scope ;;; Other statements ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Return -@stmt [Statement [ReturnStatement @expr [Expression]]] { - edge @expr.lexical_scope -> @stmt.lexical_scope -} - ;;; Emit @stmt [Statement [EmitStatement @event_ident [IdentifierPath] @@ -1554,12 +1646,6 @@ inherit .parent_scope edge typeof -> @type_name.output } -@state_var [StateVariableDefinition - value: [StateVariableDefinitionValue @expr [Expression]] -] { - edge @expr.lexical_scope -> @state_var.lexical_scope -} - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Enum definitions @@ -1572,17 +1658,23 @@ inherit .parent_scope } @enum [EnumDefinition @name name: [Identifier]] { - node def - attr (def) node_definition = @name - attr (def) definiens_node = @enum - - edge @enum.def -> def + attr (@enum.def) node_definition = @name + attr (@enum.def) definiens_node = @enum node member attr (member) pop_symbol = "." - edge def -> member + edge @enum.def -> member edge member -> @enum.members + + ; Path to resolve the built-in type for enums (which is the same as for integer types) + node type + attr (type) pop_symbol = "%type" + node type_enum_type + attr (type_enum_type) push_symbol = "%typeIntType" + edge @enum.def -> type + edge type -> type_enum_type + edge type_enum_type -> @enum.lexical_scope } @enum [EnumDefinition @@ -1607,26 +1699,48 @@ inherit .parent_scope } @struct [StructDefinition @name name: [Identifier]] { + ; Since we use structs to define built-in types and some of them (ie. array) + ; have have a parametric type, we define two distinct paths to define a + ; struct: + ; 1. the normal, non parametric path, should drop scopes in the scope stack first of all + ; 2. the parametric path, that pops a scope to resolve the parametric type + ; Both of these connect to the node that pops the struct identifier symbol + + ; First the normal path + node struct_drop + attr (struct_drop) type = "drop_scopes" + edge @struct.def -> struct_drop + + ; Second path, pops the scope + node typed_params + attr (typed_params) pop_scoped_symbol = "<>" + edge @struct.def -> typed_params + + ; Connect both to the struct identifier node def attr (def) node_definition = @name attr (def) definiens_node = @struct + edge struct_drop -> def + edge typed_params -> def - edge @struct.def -> def + ; On the other end, to properly close the second path we need to jump to the popped scope + ; (this is why on the other path we drop scopes) + edge @struct.lexical_scope -> JUMP_TO_SCOPE_NODE + ; Now connect normally to the struct members node type_def attr (type_def) pop_symbol = "@typeof" - node member attr (member) pop_symbol = "." - edge def -> type_def edge type_def -> member edge member -> @struct.members -} -@struct [StructDefinition [StructMembers @member item: [StructMember]]] { - node @member.lexical_scope - edge @member.lexical_scope -> @struct.lexical_scope + ; Bind member names when using construction with named arguments + node param_names + attr (param_names) pop_symbol = "@param_names" + edge def -> param_names + edge param_names -> @struct.members } @struct [StructDefinition [StructMembers @@ -1638,7 +1752,7 @@ inherit .parent_scope edge @struct.members -> def - edge @type_name.type_ref -> @member.lexical_scope + edge @type_name.type_ref -> @struct.lexical_scope node typeof attr (typeof) push_symbol = "@typeof" @@ -1730,7 +1844,6 @@ inherit .parent_scope @constant [ConstantDefinition @type_name type_name: [TypeName] @name name: [Identifier] - @value value: [Expression] ] { node def attr (def) node_definition = @name @@ -1738,7 +1851,6 @@ inherit .parent_scope edge @constant.def -> def - edge @value.lexical_scope -> @constant.lexical_scope edge @type_name.type_ref -> @constant.lexical_scope } @@ -1760,25 +1872,18 @@ inherit .parent_scope ;;; Expressions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Expressions have two important scoped variables: +;; - @expr.lexical_scope should be set by the enclosing node to provide a scope +;; for name resolution +;; - @expr.output is a node provided by the expression and represents the output +;; of the expression for chaining eg. with a member access + @expr [Expression] { - node @expr.lexical_scope - ;; this is an output scope for use in member access + ;; this is an output scope for use in member access (and other uses) node @expr.output } -;; General case for nested expressions -@expr [Expression variant: [_ @child [Expression]]] { - edge @child.lexical_scope -> @expr.lexical_scope -} - -;; Tuple expressions -@tuple_expr [Expression [TupleExpression - items: [TupleValues [TupleValue @expr [Expression]]] -]] { - edge @expr.lexical_scope -> @tuple_expr.lexical_scope -} - -;; primary expressions +;; Identifier expressions @expr [Expression @name ( variant: [Identifier] | variant: [SuperKeyword] | variant: [ThisKeyword] )] { @@ -1806,6 +1911,12 @@ inherit .parent_scope edge member -> @operand.output edge @expr.output -> @name.ref + + ; Shortcut path for expressions inside contracts with using X for * directives + node star + attr (star) push_symbol = "@*" + edge member -> star + edge star -> @expr.lexical_scope } ;; Special case: member accesses to `super` are tagged with "super" to rank @@ -1821,11 +1932,17 @@ inherit .parent_scope @expr [Expression [IndexAccessExpression @operand operand: [Expression] ]] { + node index_call + attr (index_call) push_symbol = "()" node index - attr (index) push_symbol = "[]" + attr (index) push_symbol = "%index" + node index_member + attr (index_member) push_symbol = "." - edge @expr.output -> index - edge index -> @operand.output + edge @expr.output -> index_call + edge index_call -> index + edge index -> index_member + edge index_member -> @operand.output } ;; Type expressions @@ -1833,6 +1950,30 @@ inherit .parent_scope edge @type.type_ref -> @type_expr.lexical_scope } +@type_expr [Expression [TypeExpression [TypeName [ElementaryType ([IntKeyword] | [UintKeyword])]]]] { + ; For integer types the type's type is fixed + node typeof + attr (typeof) push_symbol = "@typeof" + node type + attr (type) push_symbol = "%typeIntType" + + edge @type_expr.output -> typeof + edge typeof -> type + edge type -> @type_expr.lexical_scope +} + +@type_expr [Expression [TypeExpression [TypeName @id_path [IdentifierPath]]]] { + ; For other identifiers, resolve it through a pseudo-member `%type` + node typeof + attr (typeof) push_symbol = "@typeof" + node type + attr (type) push_symbol = "%type" + + edge @type_expr.output -> typeof + edge typeof -> type + edge type -> @id_path.push_begin +} + ;; New expressions @new_expr [Expression [NewExpression @type [TypeName]]] { @@ -1850,17 +1991,9 @@ inherit .parent_scope attr (@args.refs) push_symbol = "@param_names" } -@args [ArgumentsDeclaration [PositionalArgumentsDeclaration - [PositionalArguments @argument [Expression]] -]] { - edge @argument.lexical_scope -> @args.lexical_scope -} - -@named_arg [NamedArgument @name [Identifier] [Colon] @value [Expression]] { +@named_arg [NamedArgument @name [Identifier] [Colon] [Expression]] { node @named_arg.lexical_scope - edge @value.lexical_scope -> @named_arg.lexical_scope - node @named_arg.ref attr (@named_arg.ref) node_reference = @name } @@ -1891,11 +2024,28 @@ inherit .parent_scope ;;; Call options -@expr [Expression [CallOptionsExpression options: [CallOptions @named_arg [NamedArgument]]]] { +@expr [Expression [CallOptionsExpression @operand [Expression] @options [CallOptions]]] { + edge @expr.output -> @operand.output + + node @options.refs + attr (@options.refs) push_symbol = "@param_names" + + node call_options + attr (call_options) push_symbol = "%callOptions" + + edge @options.refs -> call_options + edge call_options -> @expr.lexical_scope +} + +@expr [Expression [CallOptionsExpression + @options [CallOptions @named_arg [NamedArgument]] +]] { edge @named_arg.lexical_scope -> @expr.lexical_scope + edge @named_arg.ref -> @options.refs } + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Yul ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/crates/solidity/inputs/language/src/definition.rs b/crates/solidity/inputs/language/src/definition.rs index ba72f94bfd..15a61a65da 100644 --- a/crates/solidity/inputs/language/src/definition.rs +++ b/crates/solidity/inputs/language/src/definition.rs @@ -6633,37 +6633,364 @@ codegen_language_macros::compile!(Language( ), BuiltInFunction(name = "assert", parameters = ["bool condition"]), BuiltInFunction( - name = "require", - parameters = ["bool condition"], - enabled = From("0.5.0") + name = "blockhash", + parameters = ["uint blockNumber"], + return_type = "bytes32", + enabled = From("0.4.22") + ), + BuiltInFunction( + name = "blobhash", + parameters = ["uint index"], + return_type = "bytes32", + enabled = From("0.8.24") + ), + BuiltInFunction( + name = "ecrecover", + parameters = ["bytes32 hash", "uint8 v", "bytes32 r", "bytes32 s"], + return_type = "address" + ), + BuiltInFunction( + name = "gasleft", + parameters = [], + return_type = "uint256", + enabled = From("0.4.22") + ), + BuiltInFunction( + name = "keccak256", + parameters = ["bytes memory"], + return_type = "bytes32" + ), + BuiltInFunction( + name = "log0", + parameters = ["bytes32"], + enabled = Till("0.8.0") + ), + BuiltInFunction( + name = "log1", + parameters = ["bytes32", "bytes32"], + enabled = Till("0.8.0") + ), + BuiltInFunction( + name = "log2", + parameters = ["bytes32", "bytes32", "bytes32"], + enabled = Till("0.8.0") + ), + BuiltInFunction( + name = "log3", + parameters = ["bytes32", "bytes32", "bytes32", "bytes32"], + enabled = Till("0.8.0") + ), + BuiltInFunction( + name = "log4", + parameters = ["bytes32", "bytes32", "bytes32", "bytes32", "bytes32"], + enabled = Till("0.8.0") + ), + BuiltInFunction( + name = "mulmod", + parameters = ["uint x", "uint y", "uint k"], + return_type = "uint" ), + BuiltInFunction(name = "require", parameters = ["bool condition"]), BuiltInFunction( name = "require", parameters = ["bool condition", "string memory message"], - enabled = From("0.5.0") + enabled = From("0.4.22") + ), + BuiltInFunction( + name = "require", + parameters = ["bool condition", "Error error"], + enabled = From("0.8.26") + ), + BuiltInFunction(name = "revert", parameters = []), + BuiltInFunction( + name = "revert", + parameters = ["string memory reason"], + enabled = From("0.4.22") + ), + BuiltInFunction( + name = "ripemd160", + parameters = ["bytes memory"], + return_type = "bytes20" + ), + BuiltInFunction( + name = "selfdestruct", + parameters = ["address payable recipient"] + ), + BuiltInFunction( + name = "sha256", + parameters = ["bytes memory"], + return_type = "bytes32" + ), + BuiltInFunction( + name = "sha3", + parameters = ["bytes memory"], + return_type = "bytes32", + enabled = Till("0.5.0") + ), + BuiltInFunction( + name = "suicide", + parameters = ["address payable recipient"], + enabled = Till("0.5.0") + ), + BuiltInType( + name = "$abiType", + fields = [], + functions = [ + BuiltInFunction( + name = "decode", + parameters = ["bytes memory", "$args"], + return_type = "$args", + enabled = From("0.5.0") + ), + BuiltInFunction( + name = "encode", + parameters = ["$args"], + return_type = "bytes memory", + enabled = From("0.4.22") + ), + BuiltInFunction( + name = "encodeCall", + parameters = ["function()", "$args"], + return_type = "bytes memory", + enabled = From("0.8.11") + ), + BuiltInFunction( + name = "encodePacked", + parameters = ["$args"], + return_type = "bytes memory", + enabled = From("0.4.22") + ), + BuiltInFunction( + name = "encodeWithSelector", + parameters = ["bytes4 selector", "$args"], + return_type = "bytes memory", + enabled = From("0.4.22") + ), + BuiltInFunction( + name = "encodeWithSignature", + parameters = ["string memory", "$args"], + return_type = "bytes memory", + enabled = From("0.4.22") + ) + ] ), - BuiltInFunction(name = "revert", parameters = ["string memory reason"]), BuiltInType( - name = "$BuiltIn$Address", + name = "$address", fields = [ BuiltInField(definition = "uint256 balance"), - BuiltInField(definition = "bytes code", enabled = From("0.8.0")) + BuiltInField(definition = "bytes code", enabled = From("0.8.0")), + BuiltInField(definition = "bytes32 codehash", enabled = From("0.8.0")) + ], + functions = [ + BuiltInFunction( + name = "call", + parameters = ["bytes memory"], + return_type = "bool", + enabled = Till("0.5.0") + ), + BuiltInFunction( + name = "call", + parameters = ["bytes memory"], + return_type = "bool, bytes memory", + enabled = From("0.5.0") + ), + BuiltInFunction( + name = "callcode", + parameters = ["bytes memory"], + return_type = "bool, bytes memory", + enabled = Till("0.5.0") + ), + BuiltInFunction( + name = "delegatecall", + parameters = ["bytes memory"], + return_type = "bool", + enabled = Till("0.5.0") + ), + BuiltInFunction( + name = "delegatecall", + parameters = ["bytes memory"], + return_type = "bool, bytes memory", + enabled = From("0.5.0") + ), + BuiltInFunction( + name = "send", + parameters = ["uint256"], + return_type = "bool" + ), + BuiltInFunction( + name = "staticcall", + parameters = ["bytes memory"], + return_type = "bool, bytes memory", + enabled = From("0.5.0") + ), + BuiltInFunction(name = "transfer", parameters = ["uint256"]) + ] + ), + BuiltInType( + name = "$array", + fields = [BuiltInField(definition = "uint length")], + functions = [ + BuiltInFunction( + name = "$index", + parameters = ["uint"], + return_type = "$element" + ), + BuiltInFunction( + name = "push", + parameters = [], + return_type = "$element", + enabled = From("0.6.0") + ), + BuiltInFunction( + name = "push", + parameters = ["$element"], + return_type = "uint", + enabled = Till("0.6.0") + ), + BuiltInFunction( + name = "push", + parameters = ["$element"], + enabled = From("0.6.0") + ), + BuiltInFunction(name = "pop", parameters = []) + ] + ), + BuiltInType( + name = "$arrayFixed", + fields = [BuiltInField(definition = "uint length")], + functions = [BuiltInFunction( + name = "$index", + parameters = ["uint"], + return_type = "$element" + )] + ), + BuiltInType( + name = "$blockType", + fields = [ + BuiltInField(definition = "uint basefee", enabled = From("0.8.7")), + BuiltInField(definition = "uint blobbasefee", enabled = From("0.8.24")), + BuiltInField(definition = "uint chainid", enabled = From("0.8.0")), + BuiltInField(definition = "address payable coinbase"), + BuiltInField(definition = "uint difficulty"), + BuiltInField(definition = "uint gaslimit"), + BuiltInField(definition = "uint number"), + BuiltInField(definition = "uint prevrandao", enabled = From("0.8.18")), + BuiltInField(definition = "uint timestamp") ], functions = [BuiltInFunction( - name = "send", - parameters = ["uint256 amount"], - return_type = "bool" + name = "blockhash", + parameters = ["uint"], + return_type = "bytes32", + enabled = Till("0.5.0") )] ), BuiltInType( - name = "$BuiltIn$TxType", + name = "$bytes", + fields = [], + functions = [BuiltInFunction( + name = "concat", + parameters = ["$args"], + return_type = "bytes memory" + )] + ), + BuiltInType( + name = "$callOptions", + fields = [ + BuiltInField(definition = "uint gas"), + BuiltInField(definition = "uint salt"), + BuiltInField(definition = "uint value") + ], + functions = [], + enabled = From("0.6.2") + ), + BuiltInType( + name = "$functionExternal", + fields = [ + BuiltInField(definition = "$address address", enabled = From("0.8.2")), + BuiltInField(definition = "$selector selector", enabled = From("0.4.17")) + ], + functions = [ + BuiltInFunction( + name = "gas", + parameters = ["uint"], + return_type = "$function", + enabled = Till("0.7.0") + ), + BuiltInFunction( + name = "value", + parameters = ["uint"], + return_type = "$function", + enabled = Till("0.7.0") + ) + ] + ), + BuiltInType( + name = "$msgType", + fields = [ + BuiltInField(definition = "bytes data"), + BuiltInField(definition = "uint256 gas", enabled = Till("0.5.0")), + BuiltInField( + definition = "address payable sender", + enabled = Till("0.8.0") + ), + BuiltInField(definition = "address sender", enabled = From("0.8.0")), + BuiltInField(definition = "bytes4 sig"), + BuiltInField(definition = "uint value") + ], + functions = [] + ), + BuiltInType( + name = "$string", + fields = [], + functions = [BuiltInFunction( + name = "concat", + parameters = ["$args"], + return_type = "string memory" + )] + ), + BuiltInType( + name = "$txType", fields = [ BuiltInField(definition = "uint gasprice"), - BuiltInField(definition = "address payable origin") + BuiltInField( + definition = "address payable origin", + enabled = Till("0.8.0") + ), + BuiltInField(definition = "address origin", enabled = From("0.8.0")) + ], + functions = [] + ), + BuiltInType( + name = "$typeContractType", + fields = [ + BuiltInField(definition = "string name"), + BuiltInField(definition = "bytes creationCode", enabled = From("0.5.3")), + BuiltInField(definition = "bytes runtimeCode", enabled = From("0.5.3")), + BuiltInField(definition = "bytes4 interfaceId", enabled = From("0.6.7")) + ], + functions = [] + ), + BuiltInType( + name = "$typeInterfaceType", + fields = [ + BuiltInField(definition = "string name"), + BuiltInField(definition = "bytes4 interfaceId", enabled = From("0.6.7")) + ], + functions = [] + ), + BuiltInType( + name = "$typeIntType", + fields = [ + BuiltInField(definition = "int min", enabled = From("0.6.8")), + BuiltInField(definition = "int max", enabled = From("0.6.8")) ], functions = [] ), - BuiltInVariable(definition = "uint now"), - BuiltInVariable(definition = "$BuiltIn$TxType tx") + BuiltInVariable(definition = "$function $placeholder"), + BuiltInVariable(definition = "$abiType abi"), + BuiltInVariable(definition = "$blockType block"), + BuiltInVariable(definition = "$msgType msg"), + BuiltInVariable(definition = "uint now", enabled = Till("0.7.0")), + BuiltInVariable(definition = "$txType tx") ] )); diff --git a/crates/solidity/outputs/cargo/crate/generated/public_api.txt b/crates/solidity/outputs/cargo/crate/generated/public_api.txt index a0b77bd22d..5169e9aab8 100644 --- a/crates/solidity/outputs/cargo/crate/generated/public_api.txt +++ b/crates/solidity/outputs/cargo/crate/generated/public_api.txt @@ -927,3 +927,4 @@ pub fn slang_solidity::parser::Parser::parse(&self, kind: slang_solidity::cst::N pub fn slang_solidity::parser::Parser::version(&self) -> &semver::Version impl core::fmt::Debug for slang_solidity::parser::Parser pub fn slang_solidity::parser::Parser::fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result +pub fn slang_solidity::transform_built_ins_node(node: &slang_solidity::cst::Node) -> slang_solidity::cst::Node diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/binding_rules.rs b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/binding_rules.rs index bdc3981e25..e60d727395 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/binding_rules.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/binding_rules.rs @@ -5,6 +5,7 @@ pub const BINDING_RULES_SOURCE: &str = r#####" global ROOT_NODE global FILE_PATH +global JUMP_TO_SCOPE_NODE attribute node_definition = node => type = "pop_symbol", node_symbol = node, is_definition attribute node_reference = node => type = "push_symbol", node_symbol = node, is_reference @@ -14,10 +15,18 @@ attribute push_symbol = symbol => type = "push_symbol", symbol = symbol attribute symbol_definition = symbol => type = "pop_symbol", symbol = symbol, is_definition attribute symbol_reference = symbol => type = "push_symbol", symbol = symbol, is_reference +attribute scoped_node_definition = node => type = "pop_scoped_symbol", node_symbol = node, is_definition +attribute scoped_node_reference = node => type = "push_scoped_symbol", node_symbol = node, is_reference +attribute pop_scoped_symbol = symbol => type = "pop_scoped_symbol", symbol = symbol +attribute push_scoped_symbol = symbol => type = "push_scoped_symbol", symbol = symbol + ;; Keeps a link to the enclosing contract definition to provide a parent for ;; method calls (to correctly resolve virtual methods) inherit .enclosing_def + inherit .parent_scope +inherit .lexical_scope + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Source unit (aka .sol file) @@ -82,11 +91,12 @@ inherit .parent_scope ;; Special case for built-ins: we want to export all symbols in the contract: ;; functions, types and state variables. All built-in symbols are defined in an -;; internal contract named '$BuiltIns$' so we need to export all its members and -;; type members directly as a source unit definition. +;; internal contract named '%BuiltIns%' (renamed from '$BuiltIns$') so we need +;; to export all its members and type members directly as a source unit +;; definition. ;; __SLANG_SOLIDITY_BUILT_INS_CONTRACT_NAME__ keep in sync with built-ins generation. @source_unit [SourceUnit [SourceUnitMembers - [SourceUnitMember @contract [ContractDefinition name: ["$BuiltIns$"]]] + [SourceUnitMember @contract [ContractDefinition name: ["%BuiltIns%"]]] ]] { if (is-system-file FILE_PATH) { edge @source_unit.defs -> @contract.members @@ -96,7 +106,6 @@ inherit .parent_scope } @source_unit [SourceUnit [SourceUnitMembers [SourceUnitMember @using [UsingDirective]]]] { - let @using.lexical_scope = @source_unit.lexical_scope edge @source_unit.lexical_scope -> @using.def } @@ -263,6 +272,9 @@ inherit .parent_scope edge heir.type_members -> type_member edge type_member -> @type_name.push_begin + + ; Resolve the "super" keyword to the inherited type + edge heir.super -> @type_name.push_begin } ;; NOTE: we use anchors here to prevent the query engine from returning all the @@ -344,19 +356,28 @@ inherit .parent_scope ;; ... and make it available in the contract's lexical scope edge @contract.lexical_scope -> this + ; Resolve the "this" keyword to the contract itself + node name_push + attr (name_push) push_symbol = (source-text @name) + edge this -> name_push + edge name_push -> @contract.lexical_scope + ;; Define "super" effectively as if it was a state variable of a type connected by our super_scope ;; super_scope will later connect to the base contract defs directly - node super - attr (super) pop_symbol = "super" + node @contract.super + attr (@contract.super) pop_symbol = "super" node super_typeof attr (super_typeof) push_symbol = "@typeof" - edge super -> super_typeof + edge @contract.super -> super_typeof edge super_typeof -> @contract.super_scope ;; Finally make "super" available in the contract's lexical scope for function bodies to use - edge @contract.lexical_scope -> super + edge @contract.lexical_scope -> @contract.super + + ; NOTE: The keyword "super" itself resolves to each of its parent contracts. + ; See the related rules in the InheritanceSpecifier section above. ;; This defines the sink of edges added from base contracts when setting this ;; contract as the compilation context @@ -367,12 +388,21 @@ inherit .parent_scope ;; (recursively) node super_import attr (super_import) pop_symbol = "." - edge super -> super_import + edge @contract.super -> super_import ;; This defines the source side of edges added to base contracts when setting ;; a contract as compilation context; this allows this contract (a base) to ;; access virtual methods in any sub-contract defined in the hierarchy attr (@contract.def) import_nodes = [@contract.lexical_scope, super_import] + + ; Path to resolve the built-in type for type() expressions + node type + attr (type) pop_symbol = "%type" + node type_contract_type + attr (type_contract_type) push_symbol = "%typeContractType" + edge @contract.def -> type + edge type -> type_contract_type + edge type_contract_type -> @contract.lexical_scope } @contract [ContractDefinition @specifier [InheritanceSpecifier]] { @@ -408,7 +438,6 @@ inherit .parent_scope @contract [ContractDefinition [ContractMembers [ContractMember @using [UsingDirective]] ]] { - let @using.lexical_scope = @contract.lexical_scope edge @contract.lexical_scope -> @using.def } @@ -451,6 +480,15 @@ inherit .parent_scope attr (@function.def) parents = [@contract.def] } +@contract [ContractDefinition [ContractMembers + [ContractMember @function [FunctionDefinition + [FunctionAttributes [FunctionAttribute ([ExternalKeyword] | [PublicKeyword])]] + ]] +]] { + ; public or external functions are also accessible through the contract type + edge @contract.type_members -> @function.def +} + @contract [ContractDefinition members: [ContractMembers [ContractMember @modifier [ModifierDefinition]] ]] { @@ -510,16 +548,29 @@ inherit .parent_scope attr (type_member) pop_symbol = "." edge @interface.def -> type_member edge type_member -> @interface.type_members + + ; Path to resolve the built-in type for type() expressions + node type + attr (type) pop_symbol = "%type" + node type_interface_type + attr (type_interface_type) push_symbol = "%typeInterfaceType" + edge @interface.def -> type + edge type -> type_interface_type + edge type_interface_type -> @interface.lexical_scope } @interface [InterfaceDefinition @specifier [InheritanceSpecifier]] { let @specifier.heir = @interface attr (@interface.def) parents = @specifier.parent_refs + + ; Define a dummy "super" node required by the rules for InheritanceSpecifier + node @interface.super } @interface [InterfaceDefinition [InterfaceMembers [ContractMember @member ( [EnumDefinition] + | [FunctionDefinition] | [StructDefinition] | [EventDefinition] | [ErrorDefinition] @@ -530,6 +581,8 @@ inherit .parent_scope edge @interface.type_members -> @member.def } +;; Allow references (eg. variables of the interface type) to the interface to +;; access functions @interface [InterfaceDefinition members: [InterfaceMembers item: [ContractMember @function variant: [FunctionDefinition]] ]] { @@ -558,17 +611,23 @@ inherit .parent_scope } @library [LibraryDefinition @name name: [Identifier]] { - node def - attr (def) node_definition = @name - attr (def) definiens_node = @library - - edge @library.def -> def + attr (@library.def) node_definition = @name + attr (@library.def) definiens_node = @library node member attr (member) pop_symbol = "." - edge def -> member + edge @library.def -> member edge member -> @library.members + + ; Path to resolve the built-in type for type() expressions (same as contracts) + node type + attr (type) pop_symbol = "%type" + node type_library_type + attr (type_library_type) push_symbol = "%typeContractType" + edge @library.def -> type + edge type -> type_library_type + edge type_library_type -> @library.lexical_scope } @library [LibraryDefinition [LibraryMembers @@ -588,7 +647,6 @@ inherit .parent_scope @library [LibraryDefinition [LibraryMembers [ContractMember @using [UsingDirective]] ]] { - let @using.lexical_scope = @library.lexical_scope edge @library.lexical_scope -> @using.def } @@ -660,6 +718,14 @@ inherit .parent_scope edge @type_name.type_ref -> @using.lexical_scope } +[ContractMember @using [UsingDirective [UsingTarget [Asterisk]]]] { + ; using X for * is only allowed inside contracts + node star + attr (star) pop_symbol = "@*" + edge @using.def -> star + edge star -> @using.clause +} + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Type names @@ -758,19 +824,28 @@ inherit .parent_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 + ; The mapping's type exposes the `%index` (ie. `[]`) operator that returns the value type + ; This is similar to arrays, only in that case we have a built-in type where + ; we can define an index function. For mappings we hard-code in the rules directly. + node typeof_input attr (typeof_input) pop_symbol = "@typeof" + node index_member + attr (index_member) pop_symbol = "." node index - attr (index) pop_symbol = "[]" + attr (index) pop_symbol = "%index" + node index_call + attr (index_call) pop_symbol = "()" node typeof_output attr (typeof_output) push_symbol = "@typeof" edge @mapping.output -> typeof_input - edge typeof_input -> index - edge index -> typeof_output + edge typeof_input -> index_member + edge index_member -> index + edge index -> index_call + edge index_call -> typeof_output edge typeof_output -> @value_type.output ; resolve the value type through our scope @@ -787,45 +862,52 @@ inherit .parent_scope node @array.output } -@array [ArrayTypeName @type_name [TypeName]] { - ; 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" - - node index - attr (index) pop_symbol = "[]" - - node typeof_output - attr (typeof_output) push_symbol = "@typeof" +@array [ArrayTypeName [TypeName] index: [Expression]] { + let @array.type = "%arrayFixed" +} - edge @array.output -> typeof_input - edge typeof_input -> index - edge index -> typeof_output - edge typeof_output -> @type_name.output +@array [ArrayTypeName [OpenBracket] . [CloseBracket]] { + let @array.type = "%array" +} - ; finally resolve the inner type through our parent scope +@array [ArrayTypeName @type_name [TypeName]] { + ; First define the normal, reference route: + + ; We first push the array type `%array`, which should connect to two distinct paths: + ; 1. the typed path, which will use a jump scope entry to resolve the element type + ; 2. the hard-coded path to connect to any `using` directive + node array + attr (array) push_symbol = @array.type + edge @array.output -> array + + ; For the first path, we need to define a scope jump entry for resolving the element type of the array + node entry + attr (entry) is_exported + node element + attr (element) pop_symbol = "%element" + edge entry -> element + edge element -> @type_name.output + + ; And then the path itself + node params + attr (params) push_scoped_symbol = "<>", scope = entry + edge array -> params + + ; Second path, for `using` directives + edge array -> @type_name.output + + ; Finally, both ends connect to our lexical scope + edge params -> @array.lexical_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 = "%[]" + ; Now we define the "definition" route (aka. the pop route), to use in `using` directives only + ; This is essentially the reverse of the second path above + node pop_array + attr (pop_array) pop_symbol = @array.type 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]] { - edge @size.lexical_scope -> @array.lexical_scope + edge @type_name.pop_end -> pop_array + let @array.pop_end = pop_array } @@ -833,21 +915,30 @@ inherit .parent_scope ;;; Function types ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -@ftype [FunctionType] { +@ftype [FunctionType @attrs [FunctionTypeAttributes]] { + ; Compute the built-in type of the function + ; %functionExternal provides access to .selector and .address + var type = "%function" + scan (source-text @attrs) { + "external" { + set type = "%functionExternal" + } + } + 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" + attr (function_type) push_symbol = type 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" + attr (pop_function_type) pop_symbol = type let @ftype.pop_begin = pop_function_type let @ftype.pop_end = pop_function_type @@ -974,7 +1065,14 @@ inherit .parent_scope edge @params.defs -> @param.def } -@function [FunctionDefinition] { +@function [FunctionDefinition @attrs [FunctionAttributes]] { + var function_type = "%function" + scan (source-text @attrs) { + "\\b(public|external)\\b" { + set function_type = "%functionExternal" + } + } + node @function.lexical_scope node @function.def @@ -983,7 +1081,7 @@ inherit .parent_scope node typeof attr (typeof) push_symbol = "@typeof" node type_function - attr (type_function) push_symbol = "%function" + attr (type_function) push_symbol = function_type edge @function.def -> typeof edge typeof -> type_function edge type_function -> @function.lexical_scope @@ -1094,6 +1192,22 @@ inherit .parent_scope edge @contract.def -> @constructor.def } +;; Solidity < 0.5.0 constructors were declared as functions of the contract's name +@contract [ContractDefinition + @contract_name [Identifier] + [ContractMembers [ContractMember [FunctionDefinition + [FunctionName @function_name [Identifier]] + @params [ParametersDeclaration] + ]]] +] { + if (version-matches "< 0.5.0") { + if (eq (source-text @contract_name) (source-text @function_name)) { + ; Connect to paramaters for named argument resolution + edge @contract.def -> @params.names + } + } +} + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Fallback and receive functions @@ -1163,6 +1277,17 @@ inherit .parent_scope attr (@modifier.def) definiens_node = @modifier edge @body.lexical_scope -> @modifier.lexical_scope + + ; Special case: bind the place holder statement `_` to the built-in + ; `%placeholder`. This only happens in the body of a modifier. + node placeholder_pop + attr (placeholder_pop) pop_symbol = "_" + node placeholder_ref + attr (placeholder_ref) push_symbol = "%placeholder" + + edge @body.lexical_scope -> placeholder_pop + edge placeholder_pop -> placeholder_ref + edge placeholder_ref -> @modifier.lexical_scope } @modifier [ModifierDefinition @params [ParametersDeclaration]] { @@ -1261,10 +1386,6 @@ inherit .parent_scope node @expr_stmt.defs } -@expr_stmt [ExpressionStatement @expr [Expression]] { - edge @expr.lexical_scope -> @expr_stmt.lexical_scope -} - ;;; Variable declaration statements @@ -1278,12 +1399,6 @@ inherit .parent_scope node @var_decl.defs } -@var_decl [VariableDeclarationStatement - value: [VariableDeclarationValue @expr [Expression]] -] { - edge @expr.lexical_scope -> @var_decl.lexical_scope -} - @var_decl [VariableDeclarationStatement [VariableDeclarationType @var_type [TypeName]] @name name: [Identifier] @@ -1315,12 +1430,6 @@ inherit .parent_scope node @tuple_decon.defs } -@tuple_decon [TupleDeconstructionStatement - @expr expression: [Expression] -] { - edge @expr.lexical_scope -> @tuple_decon.lexical_scope -} - @tuple_decon [TupleDeconstructionStatement [TupleDeconstructionElements [TupleDeconstructionElement @tuple_member [TupleMember variant: [UntypedTupleMember @@ -1364,10 +1473,6 @@ inherit .parent_scope ;; If conditionals -@stmt [Statement [IfStatement @condition condition: [Expression]]] { - edge @condition.lexical_scope -> @stmt.lexical_scope -} - @stmt [Statement [IfStatement @body body: [Statement]]] { edge @body.lexical_scope -> @stmt.lexical_scope if (version-matches "< 0.5.0") { @@ -1403,6 +1508,10 @@ inherit .parent_scope } @stmt [Statement [ForStatement @iter_expr iterator: [Expression]]] { + ; for the iterator expression we need an independent scope node that can + ; connect to both the for-statement *and* the definitions in the init + ; expression + node @iter_expr.lexical_scope edge @iter_expr.lexical_scope -> @stmt.lexical_scope edge @iter_expr.lexical_scope -> @stmt.init_defs } @@ -1420,10 +1529,6 @@ inherit .parent_scope ;; While loops -@stmt [Statement [WhileStatement @condition condition: [Expression]]] { - edge @condition.lexical_scope -> @stmt.lexical_scope -} - @stmt [Statement [WhileStatement @body body: [Statement]]] { edge @body.lexical_scope -> @stmt.lexical_scope if (version-matches "< 0.5.0") { @@ -1440,10 +1545,6 @@ inherit .parent_scope } } -@stmt [Statement [DoWhileStatement @condition condition: [Expression]]] { - edge @condition.lexical_scope -> @stmt.lexical_scope -} - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Error handling @@ -1451,10 +1552,6 @@ inherit .parent_scope ;;; Try-catch statements -@stmt [Statement [TryStatement @expr expression: [Expression]]] { - edge @expr.lexical_scope -> @stmt.lexical_scope -} - @stmt [Statement [TryStatement @body body: [Block]]] { edge @body.lexical_scope -> @stmt.lexical_scope } @@ -1508,11 +1605,6 @@ inherit .parent_scope ;;; Other statements ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Return -@stmt [Statement [ReturnStatement @expr [Expression]]] { - edge @expr.lexical_scope -> @stmt.lexical_scope -} - ;;; Emit @stmt [Statement [EmitStatement @event_ident [IdentifierPath] @@ -1559,12 +1651,6 @@ inherit .parent_scope edge typeof -> @type_name.output } -@state_var [StateVariableDefinition - value: [StateVariableDefinitionValue @expr [Expression]] -] { - edge @expr.lexical_scope -> @state_var.lexical_scope -} - ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Enum definitions @@ -1577,17 +1663,23 @@ inherit .parent_scope } @enum [EnumDefinition @name name: [Identifier]] { - node def - attr (def) node_definition = @name - attr (def) definiens_node = @enum - - edge @enum.def -> def + attr (@enum.def) node_definition = @name + attr (@enum.def) definiens_node = @enum node member attr (member) pop_symbol = "." - edge def -> member + edge @enum.def -> member edge member -> @enum.members + + ; Path to resolve the built-in type for enums (which is the same as for integer types) + node type + attr (type) pop_symbol = "%type" + node type_enum_type + attr (type_enum_type) push_symbol = "%typeIntType" + edge @enum.def -> type + edge type -> type_enum_type + edge type_enum_type -> @enum.lexical_scope } @enum [EnumDefinition @@ -1612,26 +1704,48 @@ inherit .parent_scope } @struct [StructDefinition @name name: [Identifier]] { + ; Since we use structs to define built-in types and some of them (ie. array) + ; have have a parametric type, we define two distinct paths to define a + ; struct: + ; 1. the normal, non parametric path, should drop scopes in the scope stack first of all + ; 2. the parametric path, that pops a scope to resolve the parametric type + ; Both of these connect to the node that pops the struct identifier symbol + + ; First the normal path + node struct_drop + attr (struct_drop) type = "drop_scopes" + edge @struct.def -> struct_drop + + ; Second path, pops the scope + node typed_params + attr (typed_params) pop_scoped_symbol = "<>" + edge @struct.def -> typed_params + + ; Connect both to the struct identifier node def attr (def) node_definition = @name attr (def) definiens_node = @struct + edge struct_drop -> def + edge typed_params -> def - edge @struct.def -> def + ; On the other end, to properly close the second path we need to jump to the popped scope + ; (this is why on the other path we drop scopes) + edge @struct.lexical_scope -> JUMP_TO_SCOPE_NODE + ; Now connect normally to the struct members node type_def attr (type_def) pop_symbol = "@typeof" - node member attr (member) pop_symbol = "." - edge def -> type_def edge type_def -> member edge member -> @struct.members -} -@struct [StructDefinition [StructMembers @member item: [StructMember]]] { - node @member.lexical_scope - edge @member.lexical_scope -> @struct.lexical_scope + ; Bind member names when using construction with named arguments + node param_names + attr (param_names) pop_symbol = "@param_names" + edge def -> param_names + edge param_names -> @struct.members } @struct [StructDefinition [StructMembers @@ -1643,7 +1757,7 @@ inherit .parent_scope edge @struct.members -> def - edge @type_name.type_ref -> @member.lexical_scope + edge @type_name.type_ref -> @struct.lexical_scope node typeof attr (typeof) push_symbol = "@typeof" @@ -1735,7 +1849,6 @@ inherit .parent_scope @constant [ConstantDefinition @type_name type_name: [TypeName] @name name: [Identifier] - @value value: [Expression] ] { node def attr (def) node_definition = @name @@ -1743,7 +1856,6 @@ inherit .parent_scope edge @constant.def -> def - edge @value.lexical_scope -> @constant.lexical_scope edge @type_name.type_ref -> @constant.lexical_scope } @@ -1765,25 +1877,18 @@ inherit .parent_scope ;;; Expressions ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; Expressions have two important scoped variables: +;; - @expr.lexical_scope should be set by the enclosing node to provide a scope +;; for name resolution +;; - @expr.output is a node provided by the expression and represents the output +;; of the expression for chaining eg. with a member access + @expr [Expression] { - node @expr.lexical_scope - ;; this is an output scope for use in member access + ;; this is an output scope for use in member access (and other uses) node @expr.output } -;; General case for nested expressions -@expr [Expression variant: [_ @child [Expression]]] { - edge @child.lexical_scope -> @expr.lexical_scope -} - -;; Tuple expressions -@tuple_expr [Expression [TupleExpression - items: [TupleValues [TupleValue @expr [Expression]]] -]] { - edge @expr.lexical_scope -> @tuple_expr.lexical_scope -} - -;; primary expressions +;; Identifier expressions @expr [Expression @name ( variant: [Identifier] | variant: [SuperKeyword] | variant: [ThisKeyword] )] { @@ -1811,6 +1916,12 @@ inherit .parent_scope edge member -> @operand.output edge @expr.output -> @name.ref + + ; Shortcut path for expressions inside contracts with using X for * directives + node star + attr (star) push_symbol = "@*" + edge member -> star + edge star -> @expr.lexical_scope } ;; Special case: member accesses to `super` are tagged with "super" to rank @@ -1826,11 +1937,17 @@ inherit .parent_scope @expr [Expression [IndexAccessExpression @operand operand: [Expression] ]] { + node index_call + attr (index_call) push_symbol = "()" node index - attr (index) push_symbol = "[]" + attr (index) push_symbol = "%index" + node index_member + attr (index_member) push_symbol = "." - edge @expr.output -> index - edge index -> @operand.output + edge @expr.output -> index_call + edge index_call -> index + edge index -> index_member + edge index_member -> @operand.output } ;; Type expressions @@ -1838,6 +1955,30 @@ inherit .parent_scope edge @type.type_ref -> @type_expr.lexical_scope } +@type_expr [Expression [TypeExpression [TypeName [ElementaryType ([IntKeyword] | [UintKeyword])]]]] { + ; For integer types the type's type is fixed + node typeof + attr (typeof) push_symbol = "@typeof" + node type + attr (type) push_symbol = "%typeIntType" + + edge @type_expr.output -> typeof + edge typeof -> type + edge type -> @type_expr.lexical_scope +} + +@type_expr [Expression [TypeExpression [TypeName @id_path [IdentifierPath]]]] { + ; For other identifiers, resolve it through a pseudo-member `%type` + node typeof + attr (typeof) push_symbol = "@typeof" + node type + attr (type) push_symbol = "%type" + + edge @type_expr.output -> typeof + edge typeof -> type + edge type -> @id_path.push_begin +} + ;; New expressions @new_expr [Expression [NewExpression @type [TypeName]]] { @@ -1855,17 +1996,9 @@ inherit .parent_scope attr (@args.refs) push_symbol = "@param_names" } -@args [ArgumentsDeclaration [PositionalArgumentsDeclaration - [PositionalArguments @argument [Expression]] -]] { - edge @argument.lexical_scope -> @args.lexical_scope -} - -@named_arg [NamedArgument @name [Identifier] [Colon] @value [Expression]] { +@named_arg [NamedArgument @name [Identifier] [Colon] [Expression]] { node @named_arg.lexical_scope - edge @value.lexical_scope -> @named_arg.lexical_scope - node @named_arg.ref attr (@named_arg.ref) node_reference = @name } @@ -1896,11 +2029,28 @@ inherit .parent_scope ;;; Call options -@expr [Expression [CallOptionsExpression options: [CallOptions @named_arg [NamedArgument]]]] { +@expr [Expression [CallOptionsExpression @operand [Expression] @options [CallOptions]]] { + edge @expr.output -> @operand.output + + node @options.refs + attr (@options.refs) push_symbol = "@param_names" + + node call_options + attr (call_options) push_symbol = "%callOptions" + + edge @options.refs -> call_options + edge call_options -> @expr.lexical_scope +} + +@expr [Expression [CallOptionsExpression + @options [CallOptions @named_arg [NamedArgument]] +]] { edge @named_arg.lexical_scope -> @expr.lexical_scope + edge @named_arg.ref -> @options.refs } + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Yul ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins.rs b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins.rs index 84fa153e90..492dbe0f36 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins.rs +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins.rs @@ -4,11 +4,39 @@ use semver::Version; #[allow(unused_variables)] pub fn get_contents(version: &Version) -> &'static str { - if *version < Version::new(0, 5, 0) { + if *version < Version::new(0, 4, 17) { include_str!("./built_ins/0.4.11.sol") - } else if *version < Version::new(0, 8, 0) { + } else if *version < Version::new(0, 4, 22) { + include_str!("./built_ins/0.4.17.sol") + } else if *version < Version::new(0, 5, 0) { + include_str!("./built_ins/0.4.22.sol") + } else if *version < Version::new(0, 5, 3) { include_str!("./built_ins/0.5.0.sol") - } else { + } else if *version < Version::new(0, 6, 0) { + include_str!("./built_ins/0.5.3.sol") + } else if *version < Version::new(0, 6, 2) { + include_str!("./built_ins/0.6.0.sol") + } else if *version < Version::new(0, 6, 7) { + include_str!("./built_ins/0.6.2.sol") + } else if *version < Version::new(0, 6, 8) { + include_str!("./built_ins/0.6.7.sol") + } else if *version < Version::new(0, 7, 0) { + include_str!("./built_ins/0.6.8.sol") + } else if *version < Version::new(0, 8, 0) { + include_str!("./built_ins/0.7.0.sol") + } else if *version < Version::new(0, 8, 2) { include_str!("./built_ins/0.8.0.sol") + } else if *version < Version::new(0, 8, 7) { + include_str!("./built_ins/0.8.2.sol") + } else if *version < Version::new(0, 8, 11) { + include_str!("./built_ins/0.8.7.sol") + } else if *version < Version::new(0, 8, 18) { + include_str!("./built_ins/0.8.11.sol") + } else if *version < Version::new(0, 8, 24) { + include_str!("./built_ins/0.8.18.sol") + } else if *version < Version::new(0, 8, 26) { + include_str!("./built_ins/0.8.24.sol") + } else { + include_str!("./built_ins/0.8.26.sol") } } diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.4.11.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.4.11.sol index 01facdfd34..282a1cb7e5 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.4.11.sol +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.4.11.sol @@ -3,15 +3,82 @@ contract $BuiltIns$ { function addmod(uint x, uint y, uint k) public returns (uint); function assert(bool condition) public; - function revert(string memory reason) public; - struct $BuiltIn$Address { + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function keccak256(bytes memory) public returns (bytes32); + function log0(bytes32) public; + function log1(bytes32, bytes32) public; + function log2(bytes32, bytes32, bytes32) public; + function log3(bytes32, bytes32, bytes32, bytes32) public; + function log4(bytes32, bytes32, bytes32, bytes32, bytes32) public; + function mulmod(uint x, uint y, uint k) public returns (uint); + function require(bool condition) public; + function revert() public; + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + function sha3(bytes memory) public returns (bytes32); + function suicide(address payable recipient) public; + struct $abiType { + } + struct $address { uint256 balance; - function(uint256 amount) returns (bool) send; + function(bytes memory) returns (bool) call; + function(bytes memory) returns (bool, bytes memory) callcode; + function(bytes memory) returns (bool) delegatecall; + function(uint256) returns (bool) send; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function($element) returns (uint) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint timestamp; + function(uint) returns (bytes32) blockhash; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $functionExternal { + function(uint) returns ($function) gas; + function(uint) returns ($function) value; } - struct $BuiltIn$TxType { + struct $msgType { + bytes data; + uint256 gas; + address payable sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { uint gasprice; address payable origin; } + struct $typeContractType { + string name; + } + struct $typeInterfaceType { + string name; + } + struct $typeIntType { + } + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; uint now; - $BuiltIn$TxType tx; + $txType tx; } diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.4.17.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.4.17.sol new file mode 100644 index 0000000000..453f95ccf2 --- /dev/null +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.4.17.sol @@ -0,0 +1,85 @@ +// This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +contract $BuiltIns$ { + function addmod(uint x, uint y, uint k) public returns (uint); + function assert(bool condition) public; + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function keccak256(bytes memory) public returns (bytes32); + function log0(bytes32) public; + function log1(bytes32, bytes32) public; + function log2(bytes32, bytes32, bytes32) public; + function log3(bytes32, bytes32, bytes32, bytes32) public; + function log4(bytes32, bytes32, bytes32, bytes32, bytes32) public; + function mulmod(uint x, uint y, uint k) public returns (uint); + function require(bool condition) public; + function revert() public; + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + function sha3(bytes memory) public returns (bytes32); + function suicide(address payable recipient) public; + struct $abiType { + } + struct $address { + uint256 balance; + function(bytes memory) returns (bool) call; + function(bytes memory) returns (bool, bytes memory) callcode; + function(bytes memory) returns (bool) delegatecall; + function(uint256) returns (bool) send; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function($element) returns (uint) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint timestamp; + function(uint) returns (bytes32) blockhash; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $functionExternal { + $selector selector; + function(uint) returns ($function) gas; + function(uint) returns ($function) value; + } + struct $msgType { + bytes data; + uint256 gas; + address payable sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { + uint gasprice; + address payable origin; + } + struct $typeContractType { + string name; + } + struct $typeInterfaceType { + string name; + } + struct $typeIntType { + } + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; + uint now; + $txType tx; +} diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.4.22.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.4.22.sol new file mode 100644 index 0000000000..49d650431a --- /dev/null +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.4.22.sol @@ -0,0 +1,93 @@ +// This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +contract $BuiltIns$ { + function addmod(uint x, uint y, uint k) public returns (uint); + function assert(bool condition) public; + function blockhash(uint blockNumber) public returns (bytes32); + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function gasleft() public returns (uint256); + function keccak256(bytes memory) public returns (bytes32); + function log0(bytes32) public; + function log1(bytes32, bytes32) public; + function log2(bytes32, bytes32, bytes32) public; + function log3(bytes32, bytes32, bytes32, bytes32) public; + function log4(bytes32, bytes32, bytes32, bytes32, bytes32) public; + function mulmod(uint x, uint y, uint k) public returns (uint); + function require(bool condition) public; + function require(bool condition, string memory message) public; + function revert() public; + function revert(string memory reason) public; + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + function sha3(bytes memory) public returns (bytes32); + function suicide(address payable recipient) public; + struct $abiType { + function($args) returns (bytes memory) encode; + function($args) returns (bytes memory) encodePacked; + function(bytes4 selector, $args) returns (bytes memory) encodeWithSelector; + function(string memory, $args) returns (bytes memory) encodeWithSignature; + } + struct $address { + uint256 balance; + function(bytes memory) returns (bool) call; + function(bytes memory) returns (bool, bytes memory) callcode; + function(bytes memory) returns (bool) delegatecall; + function(uint256) returns (bool) send; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function($element) returns (uint) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint timestamp; + function(uint) returns (bytes32) blockhash; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $functionExternal { + $selector selector; + function(uint) returns ($function) gas; + function(uint) returns ($function) value; + } + struct $msgType { + bytes data; + uint256 gas; + address payable sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { + uint gasprice; + address payable origin; + } + struct $typeContractType { + string name; + } + struct $typeInterfaceType { + string name; + } + struct $typeIntType { + } + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; + uint now; + $txType tx; +} diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.5.0.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.5.0.sol index 2308b12c25..c722b7c163 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.5.0.sol +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.5.0.sol @@ -3,17 +3,88 @@ contract $BuiltIns$ { function addmod(uint x, uint y, uint k) public returns (uint); function assert(bool condition) public; + function blockhash(uint blockNumber) public returns (bytes32); + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function gasleft() public returns (uint256); + function keccak256(bytes memory) public returns (bytes32); + function log0(bytes32) public; + function log1(bytes32, bytes32) public; + function log2(bytes32, bytes32, bytes32) public; + function log3(bytes32, bytes32, bytes32, bytes32) public; + function log4(bytes32, bytes32, bytes32, bytes32, bytes32) public; + function mulmod(uint x, uint y, uint k) public returns (uint); function require(bool condition) public; function require(bool condition, string memory message) public; + function revert() public; function revert(string memory reason) public; - struct $BuiltIn$Address { + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + struct $abiType { + function(bytes memory, $args) returns ($args) decode; + function($args) returns (bytes memory) encode; + function($args) returns (bytes memory) encodePacked; + function(bytes4 selector, $args) returns (bytes memory) encodeWithSelector; + function(string memory, $args) returns (bytes memory) encodeWithSignature; + } + struct $address { uint256 balance; - function(uint256 amount) returns (bool) send; + function(bytes memory) returns (bool, bytes memory) call; + function(bytes memory) returns (bool, bytes memory) delegatecall; + function(uint256) returns (bool) send; + function(bytes memory) returns (bool, bytes memory) staticcall; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function($element) returns (uint) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint timestamp; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $functionExternal { + $selector selector; + function(uint) returns ($function) gas; + function(uint) returns ($function) value; } - struct $BuiltIn$TxType { + struct $msgType { + bytes data; + address payable sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { uint gasprice; address payable origin; } + struct $typeContractType { + string name; + } + struct $typeInterfaceType { + string name; + } + struct $typeIntType { + } + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; uint now; - $BuiltIn$TxType tx; + $txType tx; } diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.5.3.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.5.3.sol new file mode 100644 index 0000000000..49de4c27d9 --- /dev/null +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.5.3.sol @@ -0,0 +1,92 @@ +// This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +contract $BuiltIns$ { + function addmod(uint x, uint y, uint k) public returns (uint); + function assert(bool condition) public; + function blockhash(uint blockNumber) public returns (bytes32); + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function gasleft() public returns (uint256); + function keccak256(bytes memory) public returns (bytes32); + function log0(bytes32) public; + function log1(bytes32, bytes32) public; + function log2(bytes32, bytes32, bytes32) public; + function log3(bytes32, bytes32, bytes32, bytes32) public; + function log4(bytes32, bytes32, bytes32, bytes32, bytes32) public; + function mulmod(uint x, uint y, uint k) public returns (uint); + function require(bool condition) public; + function require(bool condition, string memory message) public; + function revert() public; + function revert(string memory reason) public; + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + struct $abiType { + function(bytes memory, $args) returns ($args) decode; + function($args) returns (bytes memory) encode; + function($args) returns (bytes memory) encodePacked; + function(bytes4 selector, $args) returns (bytes memory) encodeWithSelector; + function(string memory, $args) returns (bytes memory) encodeWithSignature; + } + struct $address { + uint256 balance; + function(bytes memory) returns (bool, bytes memory) call; + function(bytes memory) returns (bool, bytes memory) delegatecall; + function(uint256) returns (bool) send; + function(bytes memory) returns (bool, bytes memory) staticcall; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function($element) returns (uint) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint timestamp; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $functionExternal { + $selector selector; + function(uint) returns ($function) gas; + function(uint) returns ($function) value; + } + struct $msgType { + bytes data; + address payable sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { + uint gasprice; + address payable origin; + } + struct $typeContractType { + string name; + bytes creationCode; + bytes runtimeCode; + } + struct $typeInterfaceType { + string name; + } + struct $typeIntType { + } + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; + uint now; + $txType tx; +} diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.6.0.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.6.0.sol new file mode 100644 index 0000000000..706f342a98 --- /dev/null +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.6.0.sol @@ -0,0 +1,93 @@ +// This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +contract $BuiltIns$ { + function addmod(uint x, uint y, uint k) public returns (uint); + function assert(bool condition) public; + function blockhash(uint blockNumber) public returns (bytes32); + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function gasleft() public returns (uint256); + function keccak256(bytes memory) public returns (bytes32); + function log0(bytes32) public; + function log1(bytes32, bytes32) public; + function log2(bytes32, bytes32, bytes32) public; + function log3(bytes32, bytes32, bytes32, bytes32) public; + function log4(bytes32, bytes32, bytes32, bytes32, bytes32) public; + function mulmod(uint x, uint y, uint k) public returns (uint); + function require(bool condition) public; + function require(bool condition, string memory message) public; + function revert() public; + function revert(string memory reason) public; + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + struct $abiType { + function(bytes memory, $args) returns ($args) decode; + function($args) returns (bytes memory) encode; + function($args) returns (bytes memory) encodePacked; + function(bytes4 selector, $args) returns (bytes memory) encodeWithSelector; + function(string memory, $args) returns (bytes memory) encodeWithSignature; + } + struct $address { + uint256 balance; + function(bytes memory) returns (bool, bytes memory) call; + function(bytes memory) returns (bool, bytes memory) delegatecall; + function(uint256) returns (bool) send; + function(bytes memory) returns (bool, bytes memory) staticcall; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function() returns ($element) push; + function($element) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint timestamp; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $functionExternal { + $selector selector; + function(uint) returns ($function) gas; + function(uint) returns ($function) value; + } + struct $msgType { + bytes data; + address payable sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { + uint gasprice; + address payable origin; + } + struct $typeContractType { + string name; + bytes creationCode; + bytes runtimeCode; + } + struct $typeInterfaceType { + string name; + } + struct $typeIntType { + } + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; + uint now; + $txType tx; +} diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.6.2.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.6.2.sol new file mode 100644 index 0000000000..bbedd35ca0 --- /dev/null +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.6.2.sol @@ -0,0 +1,98 @@ +// This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +contract $BuiltIns$ { + function addmod(uint x, uint y, uint k) public returns (uint); + function assert(bool condition) public; + function blockhash(uint blockNumber) public returns (bytes32); + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function gasleft() public returns (uint256); + function keccak256(bytes memory) public returns (bytes32); + function log0(bytes32) public; + function log1(bytes32, bytes32) public; + function log2(bytes32, bytes32, bytes32) public; + function log3(bytes32, bytes32, bytes32, bytes32) public; + function log4(bytes32, bytes32, bytes32, bytes32, bytes32) public; + function mulmod(uint x, uint y, uint k) public returns (uint); + function require(bool condition) public; + function require(bool condition, string memory message) public; + function revert() public; + function revert(string memory reason) public; + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + struct $abiType { + function(bytes memory, $args) returns ($args) decode; + function($args) returns (bytes memory) encode; + function($args) returns (bytes memory) encodePacked; + function(bytes4 selector, $args) returns (bytes memory) encodeWithSelector; + function(string memory, $args) returns (bytes memory) encodeWithSignature; + } + struct $address { + uint256 balance; + function(bytes memory) returns (bool, bytes memory) call; + function(bytes memory) returns (bool, bytes memory) delegatecall; + function(uint256) returns (bool) send; + function(bytes memory) returns (bool, bytes memory) staticcall; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function() returns ($element) push; + function($element) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint timestamp; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $callOptions { + uint gas; + uint salt; + uint value; + } + struct $functionExternal { + $selector selector; + function(uint) returns ($function) gas; + function(uint) returns ($function) value; + } + struct $msgType { + bytes data; + address payable sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { + uint gasprice; + address payable origin; + } + struct $typeContractType { + string name; + bytes creationCode; + bytes runtimeCode; + } + struct $typeInterfaceType { + string name; + } + struct $typeIntType { + } + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; + uint now; + $txType tx; +} diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.6.7.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.6.7.sol new file mode 100644 index 0000000000..1bb40d1749 --- /dev/null +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.6.7.sol @@ -0,0 +1,100 @@ +// This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +contract $BuiltIns$ { + function addmod(uint x, uint y, uint k) public returns (uint); + function assert(bool condition) public; + function blockhash(uint blockNumber) public returns (bytes32); + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function gasleft() public returns (uint256); + function keccak256(bytes memory) public returns (bytes32); + function log0(bytes32) public; + function log1(bytes32, bytes32) public; + function log2(bytes32, bytes32, bytes32) public; + function log3(bytes32, bytes32, bytes32, bytes32) public; + function log4(bytes32, bytes32, bytes32, bytes32, bytes32) public; + function mulmod(uint x, uint y, uint k) public returns (uint); + function require(bool condition) public; + function require(bool condition, string memory message) public; + function revert() public; + function revert(string memory reason) public; + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + struct $abiType { + function(bytes memory, $args) returns ($args) decode; + function($args) returns (bytes memory) encode; + function($args) returns (bytes memory) encodePacked; + function(bytes4 selector, $args) returns (bytes memory) encodeWithSelector; + function(string memory, $args) returns (bytes memory) encodeWithSignature; + } + struct $address { + uint256 balance; + function(bytes memory) returns (bool, bytes memory) call; + function(bytes memory) returns (bool, bytes memory) delegatecall; + function(uint256) returns (bool) send; + function(bytes memory) returns (bool, bytes memory) staticcall; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function() returns ($element) push; + function($element) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint timestamp; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $callOptions { + uint gas; + uint salt; + uint value; + } + struct $functionExternal { + $selector selector; + function(uint) returns ($function) gas; + function(uint) returns ($function) value; + } + struct $msgType { + bytes data; + address payable sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { + uint gasprice; + address payable origin; + } + struct $typeContractType { + string name; + bytes creationCode; + bytes runtimeCode; + bytes4 interfaceId; + } + struct $typeInterfaceType { + string name; + bytes4 interfaceId; + } + struct $typeIntType { + } + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; + uint now; + $txType tx; +} diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.6.8.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.6.8.sol new file mode 100644 index 0000000000..51bc2829fd --- /dev/null +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.6.8.sol @@ -0,0 +1,102 @@ +// This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +contract $BuiltIns$ { + function addmod(uint x, uint y, uint k) public returns (uint); + function assert(bool condition) public; + function blockhash(uint blockNumber) public returns (bytes32); + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function gasleft() public returns (uint256); + function keccak256(bytes memory) public returns (bytes32); + function log0(bytes32) public; + function log1(bytes32, bytes32) public; + function log2(bytes32, bytes32, bytes32) public; + function log3(bytes32, bytes32, bytes32, bytes32) public; + function log4(bytes32, bytes32, bytes32, bytes32, bytes32) public; + function mulmod(uint x, uint y, uint k) public returns (uint); + function require(bool condition) public; + function require(bool condition, string memory message) public; + function revert() public; + function revert(string memory reason) public; + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + struct $abiType { + function(bytes memory, $args) returns ($args) decode; + function($args) returns (bytes memory) encode; + function($args) returns (bytes memory) encodePacked; + function(bytes4 selector, $args) returns (bytes memory) encodeWithSelector; + function(string memory, $args) returns (bytes memory) encodeWithSignature; + } + struct $address { + uint256 balance; + function(bytes memory) returns (bool, bytes memory) call; + function(bytes memory) returns (bool, bytes memory) delegatecall; + function(uint256) returns (bool) send; + function(bytes memory) returns (bool, bytes memory) staticcall; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function() returns ($element) push; + function($element) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint timestamp; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $callOptions { + uint gas; + uint salt; + uint value; + } + struct $functionExternal { + $selector selector; + function(uint) returns ($function) gas; + function(uint) returns ($function) value; + } + struct $msgType { + bytes data; + address payable sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { + uint gasprice; + address payable origin; + } + struct $typeContractType { + string name; + bytes creationCode; + bytes runtimeCode; + bytes4 interfaceId; + } + struct $typeInterfaceType { + string name; + bytes4 interfaceId; + } + struct $typeIntType { + int min; + int max; + } + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; + uint now; + $txType tx; +} diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.7.0.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.7.0.sol new file mode 100644 index 0000000000..ce5c90338a --- /dev/null +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.7.0.sol @@ -0,0 +1,99 @@ +// This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +contract $BuiltIns$ { + function addmod(uint x, uint y, uint k) public returns (uint); + function assert(bool condition) public; + function blockhash(uint blockNumber) public returns (bytes32); + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function gasleft() public returns (uint256); + function keccak256(bytes memory) public returns (bytes32); + function log0(bytes32) public; + function log1(bytes32, bytes32) public; + function log2(bytes32, bytes32, bytes32) public; + function log3(bytes32, bytes32, bytes32, bytes32) public; + function log4(bytes32, bytes32, bytes32, bytes32, bytes32) public; + function mulmod(uint x, uint y, uint k) public returns (uint); + function require(bool condition) public; + function require(bool condition, string memory message) public; + function revert() public; + function revert(string memory reason) public; + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + struct $abiType { + function(bytes memory, $args) returns ($args) decode; + function($args) returns (bytes memory) encode; + function($args) returns (bytes memory) encodePacked; + function(bytes4 selector, $args) returns (bytes memory) encodeWithSelector; + function(string memory, $args) returns (bytes memory) encodeWithSignature; + } + struct $address { + uint256 balance; + function(bytes memory) returns (bool, bytes memory) call; + function(bytes memory) returns (bool, bytes memory) delegatecall; + function(uint256) returns (bool) send; + function(bytes memory) returns (bool, bytes memory) staticcall; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function() returns ($element) push; + function($element) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint timestamp; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $callOptions { + uint gas; + uint salt; + uint value; + } + struct $functionExternal { + $selector selector; + } + struct $msgType { + bytes data; + address payable sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { + uint gasprice; + address payable origin; + } + struct $typeContractType { + string name; + bytes creationCode; + bytes runtimeCode; + bytes4 interfaceId; + } + struct $typeInterfaceType { + string name; + bytes4 interfaceId; + } + struct $typeIntType { + int min; + int max; + } + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; + $txType tx; +} diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.0.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.0.sol index 494cd74c52..67a4546951 100644 --- a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.0.sol +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.0.sol @@ -3,18 +3,95 @@ contract $BuiltIns$ { function addmod(uint x, uint y, uint k) public returns (uint); function assert(bool condition) public; + function blockhash(uint blockNumber) public returns (bytes32); + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function gasleft() public returns (uint256); + function keccak256(bytes memory) public returns (bytes32); + function mulmod(uint x, uint y, uint k) public returns (uint); function require(bool condition) public; function require(bool condition, string memory message) public; + function revert() public; function revert(string memory reason) public; - struct $BuiltIn$Address { + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + struct $abiType { + function(bytes memory, $args) returns ($args) decode; + function($args) returns (bytes memory) encode; + function($args) returns (bytes memory) encodePacked; + function(bytes4 selector, $args) returns (bytes memory) encodeWithSelector; + function(string memory, $args) returns (bytes memory) encodeWithSignature; + } + struct $address { uint256 balance; bytes code; - function(uint256 amount) returns (bool) send; + bytes32 codehash; + function(bytes memory) returns (bool, bytes memory) call; + function(bytes memory) returns (bool, bytes memory) delegatecall; + function(uint256) returns (bool) send; + function(bytes memory) returns (bool, bytes memory) staticcall; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function() returns ($element) push; + function($element) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + uint chainid; + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint timestamp; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $callOptions { + uint gas; + uint salt; + uint value; } - struct $BuiltIn$TxType { + struct $functionExternal { + $selector selector; + } + struct $msgType { + bytes data; + address sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { uint gasprice; - address payable origin; + address origin; + } + struct $typeContractType { + string name; + bytes creationCode; + bytes runtimeCode; + bytes4 interfaceId; + } + struct $typeInterfaceType { + string name; + bytes4 interfaceId; + } + struct $typeIntType { + int min; + int max; } - uint now; - $BuiltIn$TxType tx; + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; + $txType tx; } diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.11.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.11.sol new file mode 100644 index 0000000000..a5a050182f --- /dev/null +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.11.sol @@ -0,0 +1,100 @@ +// This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +contract $BuiltIns$ { + function addmod(uint x, uint y, uint k) public returns (uint); + function assert(bool condition) public; + function blockhash(uint blockNumber) public returns (bytes32); + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function gasleft() public returns (uint256); + function keccak256(bytes memory) public returns (bytes32); + function mulmod(uint x, uint y, uint k) public returns (uint); + function require(bool condition) public; + function require(bool condition, string memory message) public; + function revert() public; + function revert(string memory reason) public; + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + struct $abiType { + function(bytes memory, $args) returns ($args) decode; + function($args) returns (bytes memory) encode; + function(function(), $args) returns (bytes memory) encodeCall; + function($args) returns (bytes memory) encodePacked; + function(bytes4 selector, $args) returns (bytes memory) encodeWithSelector; + function(string memory, $args) returns (bytes memory) encodeWithSignature; + } + struct $address { + uint256 balance; + bytes code; + bytes32 codehash; + function(bytes memory) returns (bool, bytes memory) call; + function(bytes memory) returns (bool, bytes memory) delegatecall; + function(uint256) returns (bool) send; + function(bytes memory) returns (bool, bytes memory) staticcall; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function() returns ($element) push; + function($element) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + uint basefee; + uint chainid; + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint timestamp; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $callOptions { + uint gas; + uint salt; + uint value; + } + struct $functionExternal { + $address address; + $selector selector; + } + struct $msgType { + bytes data; + address sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { + uint gasprice; + address origin; + } + struct $typeContractType { + string name; + bytes creationCode; + bytes runtimeCode; + bytes4 interfaceId; + } + struct $typeInterfaceType { + string name; + bytes4 interfaceId; + } + struct $typeIntType { + int min; + int max; + } + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; + $txType tx; +} diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.18.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.18.sol new file mode 100644 index 0000000000..8fd9b32c01 --- /dev/null +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.18.sol @@ -0,0 +1,101 @@ +// This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +contract $BuiltIns$ { + function addmod(uint x, uint y, uint k) public returns (uint); + function assert(bool condition) public; + function blockhash(uint blockNumber) public returns (bytes32); + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function gasleft() public returns (uint256); + function keccak256(bytes memory) public returns (bytes32); + function mulmod(uint x, uint y, uint k) public returns (uint); + function require(bool condition) public; + function require(bool condition, string memory message) public; + function revert() public; + function revert(string memory reason) public; + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + struct $abiType { + function(bytes memory, $args) returns ($args) decode; + function($args) returns (bytes memory) encode; + function(function(), $args) returns (bytes memory) encodeCall; + function($args) returns (bytes memory) encodePacked; + function(bytes4 selector, $args) returns (bytes memory) encodeWithSelector; + function(string memory, $args) returns (bytes memory) encodeWithSignature; + } + struct $address { + uint256 balance; + bytes code; + bytes32 codehash; + function(bytes memory) returns (bool, bytes memory) call; + function(bytes memory) returns (bool, bytes memory) delegatecall; + function(uint256) returns (bool) send; + function(bytes memory) returns (bool, bytes memory) staticcall; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function() returns ($element) push; + function($element) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + uint basefee; + uint chainid; + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint prevrandao; + uint timestamp; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $callOptions { + uint gas; + uint salt; + uint value; + } + struct $functionExternal { + $address address; + $selector selector; + } + struct $msgType { + bytes data; + address sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { + uint gasprice; + address origin; + } + struct $typeContractType { + string name; + bytes creationCode; + bytes runtimeCode; + bytes4 interfaceId; + } + struct $typeInterfaceType { + string name; + bytes4 interfaceId; + } + struct $typeIntType { + int min; + int max; + } + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; + $txType tx; +} diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.2.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.2.sol new file mode 100644 index 0000000000..c3be365f51 --- /dev/null +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.2.sol @@ -0,0 +1,98 @@ +// This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +contract $BuiltIns$ { + function addmod(uint x, uint y, uint k) public returns (uint); + function assert(bool condition) public; + function blockhash(uint blockNumber) public returns (bytes32); + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function gasleft() public returns (uint256); + function keccak256(bytes memory) public returns (bytes32); + function mulmod(uint x, uint y, uint k) public returns (uint); + function require(bool condition) public; + function require(bool condition, string memory message) public; + function revert() public; + function revert(string memory reason) public; + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + struct $abiType { + function(bytes memory, $args) returns ($args) decode; + function($args) returns (bytes memory) encode; + function($args) returns (bytes memory) encodePacked; + function(bytes4 selector, $args) returns (bytes memory) encodeWithSelector; + function(string memory, $args) returns (bytes memory) encodeWithSignature; + } + struct $address { + uint256 balance; + bytes code; + bytes32 codehash; + function(bytes memory) returns (bool, bytes memory) call; + function(bytes memory) returns (bool, bytes memory) delegatecall; + function(uint256) returns (bool) send; + function(bytes memory) returns (bool, bytes memory) staticcall; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function() returns ($element) push; + function($element) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + uint chainid; + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint timestamp; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $callOptions { + uint gas; + uint salt; + uint value; + } + struct $functionExternal { + $address address; + $selector selector; + } + struct $msgType { + bytes data; + address sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { + uint gasprice; + address origin; + } + struct $typeContractType { + string name; + bytes creationCode; + bytes runtimeCode; + bytes4 interfaceId; + } + struct $typeInterfaceType { + string name; + bytes4 interfaceId; + } + struct $typeIntType { + int min; + int max; + } + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; + $txType tx; +} diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.24.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.24.sol new file mode 100644 index 0000000000..d461e13b67 --- /dev/null +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.24.sol @@ -0,0 +1,103 @@ +// This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +contract $BuiltIns$ { + function addmod(uint x, uint y, uint k) public returns (uint); + function assert(bool condition) public; + function blockhash(uint blockNumber) public returns (bytes32); + function blobhash(uint index) public returns (bytes32); + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function gasleft() public returns (uint256); + function keccak256(bytes memory) public returns (bytes32); + function mulmod(uint x, uint y, uint k) public returns (uint); + function require(bool condition) public; + function require(bool condition, string memory message) public; + function revert() public; + function revert(string memory reason) public; + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + struct $abiType { + function(bytes memory, $args) returns ($args) decode; + function($args) returns (bytes memory) encode; + function(function(), $args) returns (bytes memory) encodeCall; + function($args) returns (bytes memory) encodePacked; + function(bytes4 selector, $args) returns (bytes memory) encodeWithSelector; + function(string memory, $args) returns (bytes memory) encodeWithSignature; + } + struct $address { + uint256 balance; + bytes code; + bytes32 codehash; + function(bytes memory) returns (bool, bytes memory) call; + function(bytes memory) returns (bool, bytes memory) delegatecall; + function(uint256) returns (bool) send; + function(bytes memory) returns (bool, bytes memory) staticcall; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function() returns ($element) push; + function($element) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + uint basefee; + uint blobbasefee; + uint chainid; + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint prevrandao; + uint timestamp; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $callOptions { + uint gas; + uint salt; + uint value; + } + struct $functionExternal { + $address address; + $selector selector; + } + struct $msgType { + bytes data; + address sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { + uint gasprice; + address origin; + } + struct $typeContractType { + string name; + bytes creationCode; + bytes runtimeCode; + bytes4 interfaceId; + } + struct $typeInterfaceType { + string name; + bytes4 interfaceId; + } + struct $typeIntType { + int min; + int max; + } + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; + $txType tx; +} diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.26.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.26.sol new file mode 100644 index 0000000000..51b4ea13a5 --- /dev/null +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.26.sol @@ -0,0 +1,104 @@ +// This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +contract $BuiltIns$ { + function addmod(uint x, uint y, uint k) public returns (uint); + function assert(bool condition) public; + function blockhash(uint blockNumber) public returns (bytes32); + function blobhash(uint index) public returns (bytes32); + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function gasleft() public returns (uint256); + function keccak256(bytes memory) public returns (bytes32); + function mulmod(uint x, uint y, uint k) public returns (uint); + function require(bool condition) public; + function require(bool condition, string memory message) public; + function require(bool condition, Error error) public; + function revert() public; + function revert(string memory reason) public; + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + struct $abiType { + function(bytes memory, $args) returns ($args) decode; + function($args) returns (bytes memory) encode; + function(function(), $args) returns (bytes memory) encodeCall; + function($args) returns (bytes memory) encodePacked; + function(bytes4 selector, $args) returns (bytes memory) encodeWithSelector; + function(string memory, $args) returns (bytes memory) encodeWithSignature; + } + struct $address { + uint256 balance; + bytes code; + bytes32 codehash; + function(bytes memory) returns (bool, bytes memory) call; + function(bytes memory) returns (bool, bytes memory) delegatecall; + function(uint256) returns (bool) send; + function(bytes memory) returns (bool, bytes memory) staticcall; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function() returns ($element) push; + function($element) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + uint basefee; + uint blobbasefee; + uint chainid; + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint prevrandao; + uint timestamp; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $callOptions { + uint gas; + uint salt; + uint value; + } + struct $functionExternal { + $address address; + $selector selector; + } + struct $msgType { + bytes data; + address sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { + uint gasprice; + address origin; + } + struct $typeContractType { + string name; + bytes creationCode; + bytes runtimeCode; + bytes4 interfaceId; + } + struct $typeInterfaceType { + string name; + bytes4 interfaceId; + } + struct $typeIntType { + int min; + int max; + } + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; + $txType tx; +} diff --git a/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.7.sol b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.7.sol new file mode 100644 index 0000000000..0ca8106588 --- /dev/null +++ b/crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.7.sol @@ -0,0 +1,99 @@ +// This file is generated automatically by infrastructure scripts. Please don't edit by hand. + +contract $BuiltIns$ { + function addmod(uint x, uint y, uint k) public returns (uint); + function assert(bool condition) public; + function blockhash(uint blockNumber) public returns (bytes32); + function ecrecover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) public returns (address); + function gasleft() public returns (uint256); + function keccak256(bytes memory) public returns (bytes32); + function mulmod(uint x, uint y, uint k) public returns (uint); + function require(bool condition) public; + function require(bool condition, string memory message) public; + function revert() public; + function revert(string memory reason) public; + function ripemd160(bytes memory) public returns (bytes20); + function selfdestruct(address payable recipient) public; + function sha256(bytes memory) public returns (bytes32); + struct $abiType { + function(bytes memory, $args) returns ($args) decode; + function($args) returns (bytes memory) encode; + function($args) returns (bytes memory) encodePacked; + function(bytes4 selector, $args) returns (bytes memory) encodeWithSelector; + function(string memory, $args) returns (bytes memory) encodeWithSignature; + } + struct $address { + uint256 balance; + bytes code; + bytes32 codehash; + function(bytes memory) returns (bool, bytes memory) call; + function(bytes memory) returns (bool, bytes memory) delegatecall; + function(uint256) returns (bool) send; + function(bytes memory) returns (bool, bytes memory) staticcall; + function(uint256) transfer; + } + struct $array { + uint length; + function(uint) returns ($element) $index; + function() returns ($element) push; + function($element) push; + function() pop; + } + struct $arrayFixed { + uint length; + function(uint) returns ($element) $index; + } + struct $blockType { + uint basefee; + uint chainid; + address payable coinbase; + uint difficulty; + uint gaslimit; + uint number; + uint timestamp; + } + struct $bytes { + function($args) returns (bytes memory) concat; + } + struct $callOptions { + uint gas; + uint salt; + uint value; + } + struct $functionExternal { + $address address; + $selector selector; + } + struct $msgType { + bytes data; + address sender; + bytes4 sig; + uint value; + } + struct $string { + function($args) returns (string memory) concat; + } + struct $txType { + uint gasprice; + address origin; + } + struct $typeContractType { + string name; + bytes creationCode; + bytes runtimeCode; + bytes4 interfaceId; + } + struct $typeInterfaceType { + string name; + bytes4 interfaceId; + } + struct $typeIntType { + int min; + int max; + } + $function $placeholder; + $abiType abi; + $blockType block; + $msgType msg; + $txType tx; +} diff --git a/crates/solidity/outputs/cargo/crate/src/lib.rs b/crates/solidity/outputs/cargo/crate/src/lib.rs index 086cd6d549..515f523f68 100644 --- a/crates/solidity/outputs/cargo/crate/src/lib.rs +++ b/crates/solidity/outputs/cargo/crate/src/lib.rs @@ -1,3 +1,46 @@ mod generated; pub use generated::*; + +#[cfg(feature = "__experimental_bindings_api")] +pub fn transform_built_ins_node(node: &generated::cst::Node) -> generated::cst::Node { + use std::rc::Rc; + + use generated::cst::{Edge, Node, NonterminalNode, TerminalNode}; + + use crate::cst::TerminalKind; + + match node { + Node::Nonterminal(nonterminal) => { + let NonterminalNode { + kind, + text_len, + children, + } = nonterminal.as_ref(); + let children = children + .iter() + .map(|edge| Edge { + label: edge.label, + node: transform_built_ins_node(&edge.node), + }) + .collect(); + let nonterminal = Rc::new(NonterminalNode { + kind: *kind, + text_len: *text_len, + children, + }); + Node::Nonterminal(nonterminal) + } + Node::Terminal(terminal) => { + let TerminalNode { kind, text } = terminal.as_ref(); + let terminal = match terminal.as_ref().kind { + TerminalKind::Identifier => Rc::new(TerminalNode { + kind: *kind, + text: text.replace('$', "%"), + }), + _ => Rc::clone(terminal), + }; + Node::Terminal(terminal) + } + } +} diff --git a/crates/solidity/outputs/cargo/tests/src/bindings.rs b/crates/solidity/outputs/cargo/tests/src/bindings.rs index 64b16595de..c346ab6afb 100644 --- a/crates/solidity/outputs/cargo/tests/src/bindings.rs +++ b/crates/solidity/outputs/cargo/tests/src/bindings.rs @@ -3,7 +3,9 @@ use std::sync::Arc; use anyhow::Result; use semver::Version; use slang_solidity::bindings::{self, Bindings}; +use slang_solidity::cst::TextIndex; use slang_solidity::parser::Parser; +use slang_solidity::transform_built_ins_node; use crate::resolver::TestsPathResolver; @@ -17,6 +19,10 @@ pub fn create_bindings(version: &Version) -> Result { built_ins_parse_output.is_valid(), "built-ins parse without errors" ); - bindings.add_system_file("built_ins.sol", built_ins_parse_output.create_tree_cursor()); + + let built_ins_cursor = transform_built_ins_node(&built_ins_parse_output.tree()) + .cursor_with_offset(TextIndex::ZERO); + + bindings.add_system_file("built_ins.sol", built_ins_cursor); Ok(bindings) } diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_assertions/generated/arrays.rs b/crates/solidity/outputs/cargo/tests/src/bindings_assertions/generated/arrays.rs index b0b4a18448..c907eafd7d 100644 --- a/crates/solidity/outputs/cargo/tests/src/bindings_assertions/generated/arrays.rs +++ b/crates/solidity/outputs/cargo/tests/src/bindings_assertions/generated/arrays.rs @@ -4,6 +4,11 @@ use anyhow::Result; use crate::bindings_assertions::runner::run; +#[test] +fn fixed() -> Result<()> { + run("arrays", "fixed") +} + #[test] fn nested_custom() -> Result<()> { run("arrays", "nested_custom") diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_assertions/generated/contracts.rs b/crates/solidity/outputs/cargo/tests/src/bindings_assertions/generated/contracts.rs index 2ab7e295da..a3603d5024 100644 --- a/crates/solidity/outputs/cargo/tests/src/bindings_assertions/generated/contracts.rs +++ b/crates/solidity/outputs/cargo/tests/src/bindings_assertions/generated/contracts.rs @@ -4,6 +4,11 @@ use anyhow::Result; use crate::bindings_assertions::runner::run; +#[test] +fn constructor_invocation() -> Result<()> { + run("contracts", "constructor_invocation") +} + #[test] fn diamond() -> Result<()> { run("contracts", "diamond") diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_assertions/generated/mod.rs b/crates/solidity/outputs/cargo/tests/src/bindings_assertions/generated/mod.rs index b4fb7405f4..f50520d789 100644 --- a/crates/solidity/outputs/cargo/tests/src/bindings_assertions/generated/mod.rs +++ b/crates/solidity/outputs/cargo/tests/src/bindings_assertions/generated/mod.rs @@ -13,6 +13,7 @@ mod functions; mod imports; mod interfaces; mod mappings; +mod modifiers; mod scoping; mod user_types; mod variables; diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_assertions/generated/modifiers.rs b/crates/solidity/outputs/cargo/tests/src/bindings_assertions/generated/modifiers.rs new file mode 100644 index 0000000000..bd63a004e6 --- /dev/null +++ b/crates/solidity/outputs/cargo/tests/src/bindings_assertions/generated/modifiers.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_assertions::runner::run; + +#[test] +fn placeholder() -> Result<()> { + run("modifiers", "placeholder") +} diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/arrays.rs b/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/arrays.rs new file mode 100644 index 0000000000..63fdbbc1cb --- /dev/null +++ b/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/arrays.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 indexing() -> Result<()> { + run("arrays", "indexing") +} diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/built_ins.rs b/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/built_ins.rs index 24ed6f0f12..328c698ec2 100644 --- a/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/built_ins.rs +++ b/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/built_ins.rs @@ -4,6 +4,26 @@ use anyhow::Result; use crate::bindings_output::runner::run; +#[test] +fn address() -> Result<()> { + run("built_ins", "address") +} + +#[test] +fn array_push() -> Result<()> { + run("built_ins", "array_push") +} + +#[test] +fn arrays() -> Result<()> { + run("built_ins", "arrays") +} + +#[test] +fn function_type() -> Result<()> { + run("built_ins", "function_type") +} + #[test] fn functions() -> Result<()> { run("built_ins", "functions") @@ -13,3 +33,13 @@ fn functions() -> Result<()> { fn global_properties() -> Result<()> { run("built_ins", "global_properties") } + +#[test] +fn shadowing() -> Result<()> { + run("built_ins", "shadowing") +} + +#[test] +fn type_expr() -> Result<()> { + run("built_ins", "type_expr") +} diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/expressions.rs b/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/expressions.rs index e13cdcdb8c..a23eba4c12 100644 --- a/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/expressions.rs +++ b/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/expressions.rs @@ -4,6 +4,11 @@ use anyhow::Result; use crate::bindings_output::runner::run; +#[test] +fn call_options() -> Result<()> { + run("expressions", "call_options") +} + #[test] fn emit_named_args() -> Result<()> { run("expressions", "emit_named_args") 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 index e2e4d9a80c..75d90a18e8 100644 --- 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 @@ -8,3 +8,13 @@ use crate::bindings_output::runner::run; fn call() -> Result<()> { run("function_types", "call") } + +#[test] +fn externals() -> Result<()> { + run("function_types", "externals") +} + +#[test] +fn reference() -> Result<()> { + run("function_types", "reference") +} 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 21535aaec2..ba2bdc21a4 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 @@ -1,5 +1,6 @@ // This file is generated automatically by infrastructure scripts. Please don't edit by hand. +mod arrays; mod built_ins; mod contracts; mod control; diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/structs.rs b/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/structs.rs index 3dbddea8d6..407534d917 100644 --- a/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/structs.rs +++ b/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/structs.rs @@ -9,6 +9,11 @@ fn declaration() -> Result<()> { run("structs", "declaration") } +#[test] +fn named_params_construction() -> Result<()> { + run("structs", "named_params_construction") +} + #[test] fn nested() -> Result<()> { run("structs", "nested") 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 index 3f7367e71c..2019c4c6d1 100644 --- a/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/using.rs +++ b/crates/solidity/outputs/cargo/tests/src/bindings_output/generated/using.rs @@ -39,6 +39,11 @@ fn in_library() -> Result<()> { run("using", "in_library") } +#[test] +fn star() -> Result<()> { + run("using", "star") +} + #[test] fn top_level() -> Result<()> { run("using", "top_level") 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 index 37f5d7efe9..7c04a26878 100644 --- a/crates/solidity/outputs/cargo/tests/src/bindings_output/graph/graphviz.rs +++ b/crates/solidity/outputs/cargo/tests/src/bindings_output/graph/graphviz.rs @@ -10,7 +10,13 @@ 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()); + + // special nodes, outside of any source part result.push("ROOT_NODE".to_string()); + result.push( + "JUMP_TO_SCOPE_NODE [label = \"\", shape = circle, style = filled, color = purple]" + .to_string(), + ); for (index, part) in parsed_parts.iter().enumerate() { let title = if part.parse_output.is_valid() { @@ -40,39 +46,34 @@ struct DotSubGraph<'a> { 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 special_node(node: GraphNodeRef) -> bool { + node.index() <= 1 +} +impl<'a> DotSubGraph<'a> { fn node_id(&self, node: GraphNodeRef) -> String { - if node == self.root_node() { + let index = node.index(); + if index == 0 { // special case: ROOT_NODE "ROOT_NODE".to_string() + } else if index == 1 { + // special case: JUMP_TO_SCOPE_NODE + "JUMP_TO_SCOPE_NODE".to_string() } else { - format!( - "{graph_id}N{index}", - graph_id = self.graph_id, - index = node.index() - ) + format!("{graph_id}N{index}", graph_id = self.graph_id,) } } } 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 + // we need to print edges connecting to the special nodes 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 { + if special_node(node) || special_node(sink) { writeln!(f, "{node_id} -> {sink_id}", sink_id = self.node_id(sink))?; } } @@ -87,13 +88,13 @@ impl<'a> fmt::Display for DotSubGraph<'a> { )?; for node in self.graph.iter_nodes() { - if node == root { - // we already rendered the ROOT NODE and all its edges + if special_node(node) { + // we already rendered the special nodes all its edges continue; } let graph_node = &self.graph[node]; - let node_label = if let Some(symbol) = graph_node.attributes.get("symbol") { + let mut 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() @@ -101,7 +102,6 @@ impl<'a> fmt::Display for DotSubGraph<'a> { format!("{}", node.index()) }; - let node_label = format!("\"{node_label}\""); let node_type = graph_node .attributes .get("type") @@ -109,34 +109,61 @@ impl<'a> fmt::Display for DotSubGraph<'a> { let node_id = self.node_id(node); match node_type { - Some("push_symbol") => { + Some("push_symbol" | "push_scoped_symbol") => { let extra_attrs = if graph_node.attributes.get("is_reference").is_some() { - ", penwidth = 2, color = \"limegreen\", fontcolor = \"limegreen\"" + ", penwidth = 2, color = limegreen, fontcolor = limegreen" } else { - ", color = \"lightgreen\", fontcolor = \"lightgreen\"" + ", color = lightgreen, fontcolor = lightgreen, style = dashed" }; + if node_type == Some("push_scoped_symbol") { + node_label += " \u{25ef}"; + } writeln!( f, - "\t{node_id} [label = {node_label}, shape = \"invhouse\"{extra_attrs}]" + "\t{node_id} [label = \"{node_label}\", shape = invhouse{extra_attrs}]" )?; + if let Some(scope) = graph_node + .attributes + .get("scope") + .and_then(|scope| scope.as_graph_node_ref().ok()) + { + writeln!( + f, + "\t{node_id} -> {scope_id} [style = dashed]", + scope_id = self.node_id(scope) + )?; + } } - Some("pop_symbol") => { + Some("pop_symbol" | "pop_scoped_symbol") => { let extra_attrs = if graph_node.attributes.get("is_definition").is_some() { - ", penwidth = 2, color = \"red\", fontcolor = \"red\"" + ", penwidth = 2, color = red, fontcolor = red" } else { - ", color = \"coral\", fontcolor = \"coral\"" + ", color = coral, fontcolor = coral, style = dashed" }; + if node_type == Some("pop_scoped_symbol") { + node_label += " \u{2b24}"; + } writeln!( f, - "\t{node_id} [label = {node_label}, shape = \"house\"{extra_attrs}]" + "\t{node_id} [label = \"{node_label}\", shape = house{extra_attrs}]" )?; } - _ => writeln!(f, "\t{node_id} [label = {node_label}]")?, + Some("drop_scopes") => { + writeln!(f, "\t{node_id} [label = \"DROP\", shape = box]")?; + } + _ => { + let extra_attrs = if graph_node.attributes.get("is_exported").is_some() { + ", shape = circle, width = 1, penwidth = 2, fixedsize = true, color = purple" + } else { + "" + }; + writeln!(f, "\t{node_id} [label = \"{node_label}\"{extra_attrs}]")?; + } } for (sink, _edge) in graph_node.iter_edges() { - if sink == root { - // we already rendered the edges going to ROOT NODE + if special_node(sink) { + // we already rendered the edges going to special nodes continue; } writeln!(f, "\t{node_id} -> {sink_id}", sink_id = self.node_id(sink))?; diff --git a/crates/solidity/testing/snapshots/bindings_assertions/arrays/fixed.sol b/crates/solidity/testing/snapshots/bindings_assertions/arrays/fixed.sol new file mode 100644 index 0000000000..5ce6c200c4 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_assertions/arrays/fixed.sol @@ -0,0 +1,9 @@ +contract Test { + function test() public { + uint[5] memory values; + values.pop(); + // ^ref:! -- fixed size arrays should not bind pop/push + values.push(1); + // ^ref:! -- fixed size arrays should not bind pop/push + } +} diff --git a/crates/solidity/testing/snapshots/bindings_assertions/contracts/constructor_invocation.sol b/crates/solidity/testing/snapshots/bindings_assertions/contracts/constructor_invocation.sol new file mode 100644 index 0000000000..f54e0f15a0 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_assertions/contracts/constructor_invocation.sol @@ -0,0 +1,21 @@ +contract A { + // ^def:1 + function A(int x) {} + // ^def:2 + + constructor(int y) {} + // ^def:3 +} + +contract Test { + function foo() public { + new A({x: 2}); + // ^ref:1 + // ^ref:2 (< 0.5.0) + // ^ref:! (>= 0.5.0) + new A({y: 2}); + // ^ref:1 + // ^ref:3 (>= 0.4.22) + // ^ref:! (< 0.4.22) + } +} diff --git a/crates/solidity/testing/snapshots/bindings_assertions/contracts/visibility.sol b/crates/solidity/testing/snapshots/bindings_assertions/contracts/visibility.sol index 24ab5cf880..2ee13f21d2 100644 --- a/crates/solidity/testing/snapshots/bindings_assertions/contracts/visibility.sol +++ b/crates/solidity/testing/snapshots/bindings_assertions/contracts/visibility.sol @@ -10,6 +10,11 @@ contract First { return choice; // ^ref:3 } + function internal_get_choice() private returns (Choice) { + // ^def:6 + return choice; + // ^ref:3 + } } contract Second { @@ -24,10 +29,12 @@ contract Second { return choice; // ^ref:5 } - function get_first_choice() public returns (First.Choice) { - return First.get_choice(); - // ^ref:1 - // ^ref:! -- cannot access a member function through the contract type + function get_first_choice() public { + First.Choice c = First.internal_get_choice(); + // ^ref:1 + // ^ref:! -- cannot access a private/internal function through the contract type + bytes4 sel = First.get_choice.selector; + // ^ref:4 -- we can reference the public function to get the selector } function other_choice() public returns (First.Choice) { return First.choice; diff --git a/crates/solidity/testing/snapshots/bindings_assertions/interfaces/visibility.sol b/crates/solidity/testing/snapshots/bindings_assertions/interfaces/visibility.sol index 6309ddf876..eedaa096cd 100644 --- a/crates/solidity/testing/snapshots/bindings_assertions/interfaces/visibility.sol +++ b/crates/solidity/testing/snapshots/bindings_assertions/interfaces/visibility.sol @@ -22,9 +22,11 @@ contract Test { //