From de9302faad4350654fcab19962d490da8ee2db37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustavo=20Gir=C3=A1ldez?= Date: Thu, 14 Nov 2024 13:09:21 -0500 Subject: [PATCH] Complete built-ins support for Solidity (#1125) This PR adds support for the remaining built-ins in Solidity plus other bug fixes and missing binding cases: * Built-in types (both visible to the user and those used to create namespace like definitions such as `tx.origin`) are declared by prefixing them with `$` and renamed by transforming the CST tree and replacing `$` by `%` before adding them to the stack graph. Because `%` is not a valid identifier character, this ensures user code cannot accidentally clash. **This transformation process is explicit and must be done manually by the user of the bindings API.** This has a potential drawback: if the user is given the transformed CST tree, they cannot `unparse()` it and obtain a valid Solidity file; if the user is given the untransformed CST tree, the cursors they obtain from the bindings API will not apply directly to their tree. An alternative is to perform the transformation inside the rules and only for system (aka built-in) files. That would restrict the visibility to the stack graph only, at the expense of performance. * `type()` expressions bind to an internal `%typeIntType`/`%typeContractType`/`%typeInterfaceType` which allows binding members such as `name`, `min`/`max` and `creationCode`. * Added all global variables, built-in type members and functions and enable them on the Solidity versions they were introduced (or disable them if they were removed). * Make external and public functions in contracts and interfaces accessible through the enclosing type to be able to retrieve their `.selector`. * Arrays push a special scoped symbol `<>` that allows delay-resolving the element type. We use this to correctly bind `push()` and the `[]` operator to bind correctly. * Bind field names when constructing structs using named arguments. * Call options parameter names are bound to a special `%callOptions` built-in type. * The placeholder `_` modifier operator only binds inside a modifier body. * Minor optimization and clean up of the graph rules by making the `lexical_scope` scoped variable inheritable and removing unnecessarily created intermediate scopes. * All built-in variables and functions can be shadowed by user defined variables and functions of the same name. * Support binding constructor parameters with the old syntax in Solidity < 0.5.0. * Support `using X for *` directive. --- .../bindings/src/builder/functions.rs | 4 +- crates/metaslang/bindings/src/builder/mod.rs | 18 + crates/metaslang/bindings/src/lib.rs | 32 +- crates/metaslang/bindings/src/resolver/mod.rs | 16 +- .../inputs/language/bindings/rules.msgb | 442 ++++++++++++------ .../inputs/language/src/definition.rs | 355 +++++++++++++- .../cargo/crate/generated/public_api.txt | 1 + .../bindings/generated/binding_rules.rs | 442 ++++++++++++------ .../generated/bindings/generated/built_ins.rs | 34 +- .../bindings/generated/built_ins/0.4.11.sol | 77 ++- .../bindings/generated/built_ins/0.4.17.sol | 85 ++++ .../bindings/generated/built_ins/0.4.22.sol | 93 ++++ .../bindings/generated/built_ins/0.5.0.sol | 79 +++- .../bindings/generated/built_ins/0.5.3.sol | 92 ++++ .../bindings/generated/built_ins/0.6.0.sol | 93 ++++ .../bindings/generated/built_ins/0.6.2.sol | 98 ++++ .../bindings/generated/built_ins/0.6.7.sol | 100 ++++ .../bindings/generated/built_ins/0.6.8.sol | 102 ++++ .../bindings/generated/built_ins/0.7.0.sol | 99 ++++ .../bindings/generated/built_ins/0.8.0.sol | 89 +++- .../bindings/generated/built_ins/0.8.11.sol | 100 ++++ .../bindings/generated/built_ins/0.8.18.sol | 101 ++++ .../bindings/generated/built_ins/0.8.2.sol | 98 ++++ .../bindings/generated/built_ins/0.8.24.sol | 103 ++++ .../bindings/generated/built_ins/0.8.26.sol | 104 +++++ .../bindings/generated/built_ins/0.8.7.sol | 99 ++++ .../solidity/outputs/cargo/crate/src/lib.rs | 43 ++ .../outputs/cargo/tests/src/bindings.rs | 8 +- .../bindings_assertions/generated/arrays.rs | 5 + .../generated/contracts.rs | 5 + .../src/bindings_assertions/generated/mod.rs | 1 + .../generated/modifiers.rs | 10 + .../src/bindings_output/generated/arrays.rs | 10 + .../bindings_output/generated/built_ins.rs | 30 ++ .../bindings_output/generated/expressions.rs | 5 + .../generated/function_types.rs | 10 + .../src/bindings_output/generated/mod.rs | 1 + .../src/bindings_output/generated/structs.rs | 5 + .../src/bindings_output/generated/using.rs | 5 + .../src/bindings_output/graph/graphviz.rs | 91 ++-- .../bindings_assertions/arrays/fixed.sol | 9 + .../contracts/constructor_invocation.sol | 21 + .../contracts/visibility.sol | 15 +- .../interfaces/visibility.sol | 10 +- .../modifiers/placeholder.sol | 6 + .../indexing/generated/0.4.11-success.txt | 39 ++ .../bindings_output/arrays/indexing/input.sol | 12 + .../address/generated/0.4.11-failure.txt | 62 +++ .../address/generated/0.5.0-success.txt | 62 +++ .../built_ins/address/input.sol | 10 + .../array_push/generated/0.4.11-failure.txt | 29 ++ .../array_push/generated/0.6.0-success.txt | 29 ++ .../built_ins/array_push/input.sol | 7 + .../arrays/generated/0.4.11-success.txt | 76 +++ .../arrays/generated/0.6.0-success.txt | 76 +++ .../built_ins/arrays/input.sol | 21 + .../generated/0.4.11-failure.txt | 88 ++++ .../generated/0.4.21-failure.txt | 88 ++++ .../function_type/generated/0.8.4-success.txt | 88 ++++ .../built_ins/function_type/input.sol | 22 + .../functions/generated/0.4.11-failure.txt | 142 +++++- .../functions/generated/0.4.21-failure.txt | 169 +++++++ .../functions/generated/0.4.22-failure.txt | 169 +++++++ .../functions/generated/0.5.0-failure.txt | 169 +++++++ .../functions/generated/0.5.0-success.txt | 29 -- .../functions/generated/0.8.13-failure.txt | 166 +++++++ .../functions/generated/0.8.24-success.txt | 166 +++++++ .../functions/generated/0.8.27-success.txt | 166 +++++++ .../functions/generated/0.8.4-failure.txt | 166 +++++++ .../functions/generated/0.8.4-success.txt | 26 -- .../built_ins/functions/input.sol | 29 ++ .../generated/0.4.11-failure.txt | 125 +++++ .../generated/0.4.11-success.txt | 34 -- .../generated/0.8.0-failure.txt | 125 +++++ .../generated/0.8.18-failure.txt | 125 +++++ .../generated/0.8.24-success.txt | 125 +++++ .../generated/0.8.7-failure.txt | 125 +++++ .../built_ins/global_properties/input.sol | 23 +- .../shadowing/generated/0.4.11-failure.txt | 40 ++ .../shadowing/generated/0.6.0-failure.txt | 40 ++ .../shadowing/generated/0.7.1-success.txt | 36 ++ .../built_ins/shadowing/input.sol | 14 + .../type_expr/generated/0.4.11-failure.txt | 165 +++++++ .../type_expr/generated/0.5.3-failure.txt | 124 +++++ .../type_expr/generated/0.6.7-failure.txt | 124 +++++ .../type_expr/generated/0.6.8-success.txt | 124 +++++ .../built_ins/type_expr/input.sol | 28 ++ .../generated/0.4.11-failure.txt | 24 +- .../generated/0.4.22-success.txt | 22 +- .../generated/0.5.0-success.txt | 30 ++ .../constructor_invocation/input.sol | 2 + .../generated/0.4.11-failure.txt | 2 +- ...{0.4.22-failure.txt => 0.4.22-success.txt} | 2 +- ...{0.4.11-failure.txt => 0.4.11-success.txt} | 2 +- ...{0.4.11-failure.txt => 0.4.11-success.txt} | 6 +- .../super_scope/generated/0.4.16-failure.txt | 2 +- .../{0.6.0-failure.txt => 0.6.0-success.txt} | 2 +- ...{0.4.11-failure.txt => 0.4.11-success.txt} | 2 +- .../generated/0.4.16-failure.txt | 2 +- .../{0.6.0-failure.txt => 0.6.0-success.txt} | 2 +- .../enums/sample/generated/0.6.8-success.txt | 84 ++++ .../custom_types/generated/0.4.22-failure.txt | 50 ++ .../call_options/generated/0.4.11-failure.txt | 43 ++ .../call_options/generated/0.6.2-success.txt | 41 ++ .../expressions/call_options/input.sol | 10 + .../generated/0.4.22-failure.txt | 40 ++ .../type_expr/generated/0.5.3-failure.txt | 2 +- .../type_expr/generated/0.6.8-success.txt | 35 ++ .../externals/generated/0.4.11-failure.txt | 25 + .../externals/generated/0.4.21-failure.txt | 25 + .../externals/generated/0.8.4-success.txt | 25 + .../function_types/externals/input.sol | 7 + .../reference/generated/0.4.11-success.txt | 38 ++ .../function_types/reference/input.sol | 11 + .../{0.6.0-failure.txt => 0.6.0-success.txt} | 6 +- ...{0.4.11-failure.txt => 0.4.11-success.txt} | 2 +- ...{0.4.11-failure.txt => 0.4.11-success.txt} | 2 +- .../{0.6.0-failure.txt => 0.6.0-success.txt} | 4 +- ...{0.4.11-failure.txt => 0.4.11-success.txt} | 2 +- .../generated/0.4.11-success.txt | 39 ++ .../named_params_construction/input.sol | 10 + .../{0.6.0-failure.txt => 0.6.0-success.txt} | 18 +- .../using/star/generated/0.4.11-success.txt | 45 ++ .../bindings_output/using/star/input.sol | 15 + 124 files changed, 6888 insertions(+), 520 deletions(-) create mode 100644 crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.4.17.sol create mode 100644 crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.4.22.sol create mode 100644 crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.5.3.sol create mode 100644 crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.6.0.sol create mode 100644 crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.6.2.sol create mode 100644 crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.6.7.sol create mode 100644 crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.6.8.sol create mode 100644 crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.7.0.sol create mode 100644 crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.11.sol create mode 100644 crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.18.sol create mode 100644 crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.2.sol create mode 100644 crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.24.sol create mode 100644 crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.26.sol create mode 100644 crates/solidity/outputs/cargo/crate/src/generated/bindings/generated/built_ins/0.8.7.sol create mode 100644 crates/solidity/outputs/cargo/tests/src/bindings_assertions/generated/modifiers.rs create mode 100644 crates/solidity/outputs/cargo/tests/src/bindings_output/generated/arrays.rs create mode 100644 crates/solidity/testing/snapshots/bindings_assertions/arrays/fixed.sol create mode 100644 crates/solidity/testing/snapshots/bindings_assertions/contracts/constructor_invocation.sol create mode 100644 crates/solidity/testing/snapshots/bindings_assertions/modifiers/placeholder.sol create mode 100644 crates/solidity/testing/snapshots/bindings_output/arrays/indexing/generated/0.4.11-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/arrays/indexing/input.sol create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/address/generated/0.4.11-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/address/generated/0.5.0-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/address/input.sol create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/array_push/generated/0.4.11-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/array_push/generated/0.6.0-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/array_push/input.sol create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/arrays/generated/0.4.11-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/arrays/generated/0.6.0-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/arrays/input.sol create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/function_type/generated/0.4.11-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/function_type/generated/0.4.21-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/function_type/generated/0.8.4-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/function_type/input.sol create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/functions/generated/0.4.21-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/functions/generated/0.4.22-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/functions/generated/0.5.0-failure.txt delete mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/functions/generated/0.5.0-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/functions/generated/0.8.13-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/functions/generated/0.8.24-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/functions/generated/0.8.27-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/functions/generated/0.8.4-failure.txt delete mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/functions/generated/0.8.4-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/global_properties/generated/0.4.11-failure.txt delete mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/global_properties/generated/0.4.11-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/global_properties/generated/0.8.0-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/global_properties/generated/0.8.18-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/global_properties/generated/0.8.24-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/global_properties/generated/0.8.7-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/shadowing/generated/0.4.11-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/shadowing/generated/0.6.0-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/shadowing/generated/0.7.1-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/shadowing/input.sol create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/type_expr/generated/0.4.11-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/type_expr/generated/0.5.3-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/type_expr/generated/0.6.7-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/type_expr/generated/0.6.8-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/built_ins/type_expr/input.sol create mode 100644 crates/solidity/testing/snapshots/bindings_output/contracts/constructor_invocation/generated/0.5.0-success.txt rename crates/solidity/testing/snapshots/bindings_output/contracts/constructor_modifier/generated/{0.4.22-failure.txt => 0.4.22-success.txt} (97%) rename crates/solidity/testing/snapshots/bindings_output/contracts/public_getters/generated/{0.4.11-failure.txt => 0.4.11-success.txt} (98%) rename crates/solidity/testing/snapshots/bindings_output/contracts/super_linearisation/generated/{0.4.11-failure.txt => 0.4.11-success.txt} (91%) rename crates/solidity/testing/snapshots/bindings_output/contracts/super_scope/generated/{0.6.0-failure.txt => 0.6.0-success.txt} (94%) rename crates/solidity/testing/snapshots/bindings_output/contracts/this_scope/generated/{0.4.11-failure.txt => 0.4.11-success.txt} (92%) rename crates/solidity/testing/snapshots/bindings_output/contracts/virtual_methods/generated/{0.6.0-failure.txt => 0.6.0-success.txt} (97%) create mode 100644 crates/solidity/testing/snapshots/bindings_output/enums/sample/generated/0.6.8-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/errors/custom_types/generated/0.4.22-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/expressions/call_options/generated/0.4.11-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/expressions/call_options/generated/0.6.2-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/expressions/call_options/input.sol create mode 100644 crates/solidity/testing/snapshots/bindings_output/expressions/revert_named_args/generated/0.4.22-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/expressions/type_expr/generated/0.6.8-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/function_types/externals/generated/0.4.11-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/function_types/externals/generated/0.4.21-failure.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/function_types/externals/generated/0.8.4-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/function_types/externals/input.sol create mode 100644 crates/solidity/testing/snapshots/bindings_output/function_types/reference/generated/0.4.11-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/function_types/reference/input.sol rename crates/solidity/testing/snapshots/bindings_output/modifiers/diamond/generated/{0.6.0-failure.txt => 0.6.0-success.txt} (91%) rename crates/solidity/testing/snapshots/bindings_output/modifiers/inherited/generated/{0.4.11-failure.txt => 0.4.11-success.txt} (94%) rename crates/solidity/testing/snapshots/bindings_output/modifiers/simple/generated/{0.4.11-failure.txt => 0.4.11-success.txt} (97%) rename crates/solidity/testing/snapshots/bindings_output/modifiers/virtual_modifier/generated/{0.6.0-failure.txt => 0.6.0-success.txt} (91%) rename crates/solidity/testing/snapshots/bindings_output/modifiers/with_args/generated/{0.4.11-failure.txt => 0.4.11-success.txt} (98%) create mode 100644 crates/solidity/testing/snapshots/bindings_output/structs/named_params_construction/generated/0.4.11-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/structs/named_params_construction/input.sol rename crates/solidity/testing/snapshots/bindings_output/structs/sample/generated/{0.6.0-failure.txt => 0.6.0-success.txt} (96%) create mode 100644 crates/solidity/testing/snapshots/bindings_output/using/star/generated/0.4.11-success.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/using/star/input.sol 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 { //