diff --git a/Cargo.toml b/Cargo.toml index b411eea19..f75116a7b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -68,7 +68,6 @@ slang_solidity = { path = "crates/solidity/outputs/cargo/slang_solidity", versio slang_solidity_node_addon = { path = "crates/solidity/outputs/cargo/slang_solidity_node_addon", version = "0.15.0" } solidity_cargo_tests = { path = "crates/solidity/outputs/cargo/tests", version = "0.15.0" } solidity_language = { path = "crates/solidity/inputs/language", version = "0.15.0" } -solidity_stack_graph = { path = "crates/solidity/inputs/graph" } solidity_npm_package = { path = "crates/solidity/outputs/npm/package", version = "0.15.0" } solidity_spec = { path = "crates/solidity/outputs/spec", version = "0.15.0" } solidity_testing_sanctuary = { path = "crates/solidity/testing/sanctuary", version = "0.15.0" } diff --git a/crates/codegen/runtime/cargo/src/runtime/bindings/mod.rs b/crates/codegen/runtime/cargo/src/runtime/bindings/mod.rs index 9a715a7a7..e6a1ceb5e 100644 --- a/crates/codegen/runtime/cargo/src/runtime/bindings/mod.rs +++ b/crates/codegen/runtime/cargo/src/runtime/bindings/mod.rs @@ -1,7 +1,7 @@ #[path = "generated/binding_rules.rs"] mod binding_rules; -use metaslang_graph_builder::ast; +use metaslang_graph_builder::{ast, ParseError}; pub use metaslang_graph_builder::functions::Functions; pub use metaslang_graph_builder::{ExecutionConfig, ExecutionError, NoCancellation, Variables}; @@ -9,3 +9,7 @@ use crate::cst::KindTypes; pub type File = ast::File; pub type Graph = metaslang_graph_builder::graph::Graph; + +pub fn get_stack_graph_builder() -> Result { + File::from_str(binding_rules::BINDING_RULES_SOURCE) +} diff --git a/crates/solidity/inputs/graph/Cargo.toml b/crates/solidity/inputs/graph/Cargo.toml deleted file mode 100644 index 058b63ceb..000000000 --- a/crates/solidity/inputs/graph/Cargo.toml +++ /dev/null @@ -1,10 +0,0 @@ -[package] -name = "solidity_stack_graph" -description = "Stack Graph builder for Solidity" -version.workspace = true -rust-version.workspace = true -edition.workspace = true -publish = false - -[lints] -workspace = true diff --git a/crates/solidity/inputs/graph/src/lib.rs b/crates/solidity/inputs/graph/src/lib.rs deleted file mode 100644 index e69de29bb..000000000 diff --git a/crates/solidity/inputs/graph/stack-graphs.msgb b/crates/solidity/inputs/graph/stack-graphs.msgb deleted file mode 100644 index c1a7db0f9..000000000 --- a/crates/solidity/inputs/graph/stack-graphs.msgb +++ /dev/null @@ -1,363 +0,0 @@ -attribute node_definition = node => type = "pop_symbol", node_symbol = node, is_definition -attribute node_reference = node => type = "push_symbol", node_symbol = node, is_reference -attribute node_symbol = node => symbol = (source-text node), source_node = node -attribute pop_symbol = symbol => type = "pop_symbol", symbol = symbol -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 - -;; Generalities -;; - we will define two nodes for all meaningful CST nodes -;; - a lexical_scope node which will connect "upwards" towards the root of the CST -;; - a defs node to access the definitions reachable from each node (usually connecting "downwards") -;; - the pair will not be created for every CST node, as there is a lot of redundancy in the tree -;; - identifier nodes that are part of the definition of an artifact -;; will create graph nodes with the node_definition attributes -;; - identifier nodes that are references will create graph nodes with the node_reference attributes - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Source unit (aka .sol file) -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -@source_unit [SourceUnit] { - node @source_unit.lexical_scope - node @source_unit.defs -} - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Contract definitions -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -@contract [ContractDefinition] { - node @contract.lexical_scope - node @contract.defs -} - -@contract [ContractDefinition ... @name name: [Identifier] ...] { - node def - attr (def) node_definition = @name - - edge @contract.lexical_scope -> def - edge @contract.defs -> def -} - -;; Connect the contract to its containing source unit -@source_unit [SourceUnit ... [SourceUnitMembers - ... - [SourceUnitMember @contract [ContractDefinition]] - ... -] ...] { - edge @source_unit.defs -> @contract.defs - edge @contract.lexical_scope -> @source_unit.lexical_scope -} - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Interface definitions -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -@interface [InterfaceDefinition] { - node @interface.lexical_scope - node @interface.defs -} - -@interface [InterfaceDefinition ... @name name: [Identifier] ...] { - node def - attr (def) node_definition = @name - - edge @interface.lexical_scope -> def - edge @interface.defs -> def -} - -;; Connect the interface to its containing source unit -@source_unit [SourceUnit [SourceUnitMembers - ... - [SourceUnitMember @interface [InterfaceDefinition]] - ... -]] { - edge @source_unit.defs -> @interface.defs - edge @interface.lexical_scope -> @source_unit.lexical_scope -} - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Library definitions -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -@library [LibraryDefinition] { - node @library.lexical_scope - node @library.defs -} - -@library [LibraryDefinition ... @name name: [Identifier] ...] { - node def - attr (def) node_definition = @name - - edge @library.lexical_scope -> def - edge @library.defs -> def -} - -;; Connect the library to its containing source unit -@source_unit [SourceUnit [SourceUnitMembers - ... - [SourceUnitMember @library [LibraryDefinition]] - ... -]] { - edge @source_unit.defs -> @library.defs - edge @library.lexical_scope -> @source_unit.lexical_scope -} - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Function definitions -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -@function [FunctionDefinition] { - node @function.lexical_scope - node @function.defs -} - -@function [FunctionDefinition ... name: [FunctionName ... @name [Identifier] ...] ...] { - node def - attr (def) node_definition = @name - - edge @function.lexical_scope -> def - edge @function.defs -> def -} - -@param [Parameter] { - node @param.lexical_scope - node @param.defs -} - -@param [Parameter ... @name [Identifier]] { - node def - attr (def) node_definition = @name - - edge @param.lexical_scope -> def - edge @param.defs -> def -} - -;; Connect the parameters to the functions they belong to -@function [FunctionDefinition - ... - parameters: [_ ... parameters: [Parameters ... @param item: [Parameter] ...] ...] - ... -] { - edge @function.lexical_scope -> @param.defs - edge @function.defs -> @param.defs -} - -;; Connect the function to the contract/interface/library they belong to -[SourceUnitMember @unit_member variant: [_ - ... - members: [_ - ... - item: [_ @function variant: [FunctionDefinition]] - ... - ] - ... - ] -] { - edge @unit_member.lexical_scope -> @function.defs - edge @unit_member.defs -> @function.defs - edge @function.lexical_scope -> @unit_member.lexical_scope -} - -@body [FunctionBody] { - node @body.lexical_scope - node @body.defs -} - -;; Connect the function body to the function definition -@function [FunctionDefinition ... @body body: [FunctionBody] ...] { - edge @body.lexical_scope -> @function.lexical_scope - edge @function.defs -> @body.defs -} - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Blocks -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -@block [Block] { - node @block.lexical_scope - node @block.defs -} - -@stmt [Statement] { - node @stmt.lexical_scope - node @stmt.defs -} - -@block [Block ... statements: [_ ... @stmt [Statement]...] ...] { - edge @stmt.lexical_scope -> @block.lexical_scope - edge @block.defs -> @stmt.defs -} - -@body [FunctionBody @block variant: [Block]] { - edge @block.lexical_scope -> @body.lexical_scope - edge @body.defs -> @block.defs -} - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Declaration Statements -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -@stmt [Statement [VariableDeclarationStatement ... @name name: [Identifier] ...]] { - node def - attr (def) node_definition = @name - - edge @stmt.lexical_scope -> def - edge @stmt.defs -> def -} - -@stmt [Statement [TupleDeconstructionStatement - ... - [TupleDeconstructionElements - ... - item: [_ member: [_ variant: [_ ... @name name: [Identifier]]]] - ... - ] - ... -]] { - node def - attr (def) node_definition = @name - - edge @stmt.lexical_scope -> def - edge @stmt.defs -> def -} - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; State Variables -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -@state_var [StateVariableDefinition] { - node @state_var.lexical_scope - node @state_var.defs -} - -@state_var [StateVariableDefinition ... @name name: [Identifier] ...] { - node def - attr (def) node_definition = @name - - edge @state_var.lexical_scope -> def - edge @state_var.defs -> def -} - -[SourceUnitMember @unit_member variant: [_ - ... - members: [_ - ... - item: [_ @state_var variant: [StateVariableDefinition]] - ... - ] - ... - ] -] { - edge @unit_member.lexical_scope -> @state_var.defs - edge @unit_member.defs -> @state_var.defs - edge @state_var.lexical_scope -> @unit_member.lexical_scope -} - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Structure definitions -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -@struct [StructDefinition] { - node @struct.lexical_scope - node @struct.defs -} - -@struct [StructDefinition ... @name name: [Identifier] ...] { - node def - attr (def) node_definition = @name - - edge @struct.lexical_scope -> def - edge @struct.defs -> def -} - -;; Connect the struct to the contract/interface/library they belong to -[SourceUnitMember @unit_member variant: [_ - ... - members: [_ - ... - item: [_ @struct variant: [StructDefinition]] - ... - ] - ... - ] -] { - edge @unit_member.lexical_scope -> @struct.defs - edge @unit_member.defs -> @struct.defs -} - -@member [StructMember] { - node @member.lexical_scope - node @member.defs -} - -@member item: [StructMember ... @name name: [Identifier] ...] { - node member - attr (member) pop_symbol = "." - edge @member.defs -> member - - node def - attr (def) node_definition = @name - edge member -> def -} - -;; TODO: missing connection between the struct field declarations and the struct - - -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; -;;; Expressions -;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; - -@expr [Expression] { - node @expr.lexical_scope -} - -@expr [Expression ... @name variant: [Identifier]] { - node ref - attr (ref) node_reference = @name - - edge ref -> @expr.lexical_scope -} - -@expr [Expression ... variant: [_ ... @child [Expression] ...] ...] { - edge @child.lexical_scope -> @expr.lexical_scope -} - -@stmt [Statement ... variant: [_ ... @expr [Expression] ...] ...] { - edge @expr.lexical_scope -> @stmt.lexical_scope -} - -@member [MemberAccess] { - node @member.lexical_scope -} - -@member [MemberAccess @name [Identifier]] { - node ref - attr (ref) node_reference = @name - - edge ref -> @member.lexical_scope -} - -[MemberAccessExpression - ... - @expr operand: [Expression] - ... - @member member: [MemberAccess] - ... -] { - node member - attr (member) push_symbol = "." - - edge @member.lexical_scope -> member - edge member -> @expr.lexical_scope -} \ No newline at end of file diff --git a/crates/solidity/inputs/language/bindings/rules.msgb b/crates/solidity/inputs/language/bindings/rules.msgb index 4254c5826..9466adb5f 100644 --- a/crates/solidity/inputs/language/bindings/rules.msgb +++ b/crates/solidity/inputs/language/bindings/rules.msgb @@ -1 +1,363 @@ -// TODO(#982): add rules for Solidity here... +attribute node_definition = node => type = "pop_symbol", node_symbol = node, is_definition +attribute node_reference = node => type = "push_symbol", node_symbol = node, is_reference +attribute node_symbol = node => symbol = (source-text node), source_node = node +attribute pop_symbol = symbol => type = "pop_symbol", symbol = symbol +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 + +;; Generalities +;; - we will define two nodes for all meaningful CST nodes +;; - a lexical_scope node which will connect "upwards" towards the root of the CST +;; - a defs node to access the definitions reachable from each node (usually connecting "downwards") +;; - the pair will not be created for every CST node, as there is a lot of redundancy in the tree +;; - identifier nodes that are part of the definition of an artifact +;; will create graph nodes with the node_definition attributes +;; - identifier nodes that are references will create graph nodes with the node_reference attributes + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Source unit (aka .sol file) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@source_unit [SourceUnit] { + node @source_unit.lexical_scope + node @source_unit.defs +} + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Contract definitions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@contract [ContractDefinition] { + node @contract.lexical_scope + node @contract.defs +} + +@contract [ContractDefinition ... @name name: [Identifier] ...] { + node def + attr (def) node_definition = @name + + edge @contract.lexical_scope -> def + edge @contract.defs -> def +} + +;; Connect the contract to its containing source unit +@source_unit [SourceUnit ... [SourceUnitMembers + ... + [SourceUnitMember @contract [ContractDefinition]] + ... +] ...] { + edge @source_unit.defs -> @contract.defs + edge @contract.lexical_scope -> @source_unit.lexical_scope +} + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Interface definitions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@interface [InterfaceDefinition] { + node @interface.lexical_scope + node @interface.defs +} + +@interface [InterfaceDefinition ... @name name: [Identifier] ...] { + node def + attr (def) node_definition = @name + + edge @interface.lexical_scope -> def + edge @interface.defs -> def +} + +;; Connect the interface to its containing source unit +@source_unit [SourceUnit [SourceUnitMembers + ... + [SourceUnitMember @interface [InterfaceDefinition]] + ... +]] { + edge @source_unit.defs -> @interface.defs + edge @interface.lexical_scope -> @source_unit.lexical_scope +} + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Library definitions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@library [LibraryDefinition] { + node @library.lexical_scope + node @library.defs +} + +@library [LibraryDefinition ... @name name: [Identifier] ...] { + node def + attr (def) node_definition = @name + + edge @library.lexical_scope -> def + edge @library.defs -> def +} + +;; Connect the library to its containing source unit +@source_unit [SourceUnit [SourceUnitMembers + ... + [SourceUnitMember @library [LibraryDefinition]] + ... +]] { + edge @source_unit.defs -> @library.defs + edge @library.lexical_scope -> @source_unit.lexical_scope +} + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Function definitions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@function [FunctionDefinition] { + node @function.lexical_scope + node @function.defs +} + +@function [FunctionDefinition ... name: [FunctionName ... @name [Identifier] ...] ...] { + node def + attr (def) node_definition = @name + + edge @function.lexical_scope -> def + edge @function.defs -> def +} + +@param [Parameter] { + node @param.lexical_scope + node @param.defs +} + +@param [Parameter ... @name [Identifier]] { + node def + attr (def) node_definition = @name + + edge @param.lexical_scope -> def + edge @param.defs -> def +} + +;; Connect the parameters to the functions they belong to +@function [FunctionDefinition + ... + parameters: [_ ... parameters: [Parameters ... @param item: [Parameter] ...] ...] + ... +] { + edge @function.lexical_scope -> @param.defs + edge @function.defs -> @param.defs +} + +;; Connect the function to the contract/interface/library they belong to +[SourceUnitMember @unit_member variant: [_ + ... + members: [_ + ... + item: [_ @function variant: [FunctionDefinition]] + ... + ] + ... + ] +] { + edge @unit_member.lexical_scope -> @function.defs + edge @unit_member.defs -> @function.defs + edge @function.lexical_scope -> @unit_member.lexical_scope +} + +@body [FunctionBody] { + node @body.lexical_scope + node @body.defs +} + +;; Connect the function body to the function definition +@function [FunctionDefinition ... @body body: [FunctionBody] ...] { + edge @body.lexical_scope -> @function.lexical_scope + edge @function.defs -> @body.defs +} + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Blocks +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@block [Block] { + node @block.lexical_scope + node @block.defs +} + +@stmt [Statement] { + node @stmt.lexical_scope + node @stmt.defs +} + +@block [Block ... statements: [_ ... @stmt [Statement]...] ...] { + edge @stmt.lexical_scope -> @block.lexical_scope + edge @block.defs -> @stmt.defs +} + +@body [FunctionBody @block variant: [Block]] { + edge @block.lexical_scope -> @body.lexical_scope + edge @body.defs -> @block.defs +} + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Declaration Statements +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@stmt [Statement [VariableDeclarationStatement ... @name name: [Identifier] ...]] { + node def + attr (def) node_definition = @name + + edge @stmt.lexical_scope -> def + edge @stmt.defs -> def +} + +@stmt [Statement [TupleDeconstructionStatement + ... + [TupleDeconstructionElements + ... + item: [_ member: [_ variant: [_ ... @name name: [Identifier]]]] + ... + ] + ... +]] { + node def + attr (def) node_definition = @name + + edge @stmt.lexical_scope -> def + edge @stmt.defs -> def +} + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; State Variables +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@state_var [StateVariableDefinition] { + node @state_var.lexical_scope + node @state_var.defs +} + +@state_var [StateVariableDefinition ... @name name: [Identifier] ...] { + node def + attr (def) node_definition = @name + + edge @state_var.lexical_scope -> def + edge @state_var.defs -> def +} + +[SourceUnitMember @unit_member variant: [_ + ... + members: [_ + ... + item: [_ @state_var variant: [StateVariableDefinition]] + ... + ] + ... + ] +] { + edge @unit_member.lexical_scope -> @state_var.defs + edge @unit_member.defs -> @state_var.defs + edge @state_var.lexical_scope -> @unit_member.lexical_scope +} + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Structure definitions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@struct [StructDefinition] { + node @struct.lexical_scope + node @struct.defs +} + +@struct [StructDefinition ... @name name: [Identifier] ...] { + node def + attr (def) node_definition = @name + + edge @struct.lexical_scope -> def + edge @struct.defs -> def +} + +;; Connect the struct to the contract/interface/library they belong to +[SourceUnitMember @unit_member variant: [_ + ... + members: [_ + ... + item: [_ @struct variant: [StructDefinition]] + ... + ] + ... + ] +] { + edge @unit_member.lexical_scope -> @struct.defs + edge @unit_member.defs -> @struct.defs +} + +@member [StructMember] { + node @member.lexical_scope + node @member.defs +} + +@member item: [StructMember ... @name name: [Identifier] ...] { + node member + attr (member) pop_symbol = "." + edge @member.defs -> member + + node def + attr (def) node_definition = @name + edge member -> def +} + +;; TODO: missing connection between the struct field declarations and the struct + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Expressions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@expr [Expression] { + node @expr.lexical_scope +} + +@expr [Expression ... @name variant: [Identifier]] { + node ref + attr (ref) node_reference = @name + + edge ref -> @expr.lexical_scope +} + +@expr [Expression ... variant: [_ ... @child [Expression] ...] ...] { + edge @child.lexical_scope -> @expr.lexical_scope +} + +@stmt [Statement ... variant: [_ ... @expr [Expression] ...] ...] { + edge @expr.lexical_scope -> @stmt.lexical_scope +} + +@member [MemberAccess] { + node @member.lexical_scope +} + +@member [MemberAccess @name [Identifier]] { + node ref + attr (ref) node_reference = @name + + edge ref -> @member.lexical_scope +} + +[MemberAccessExpression + ... + @expr operand: [Expression] + ... + @member member: [MemberAccess] + ... +] { + node member + attr (member) push_symbol = "." + + edge @member.lexical_scope -> member + edge member -> @expr.lexical_scope +} diff --git a/crates/solidity/outputs/cargo/slang_solidity/src/generated/bindings/generated/binding_rules.rs b/crates/solidity/outputs/cargo/slang_solidity/src/generated/bindings/generated/binding_rules.rs index 49adbd148..7715b748c 100644 --- a/crates/solidity/outputs/cargo/slang_solidity/src/generated/bindings/generated/binding_rules.rs +++ b/crates/solidity/outputs/cargo/slang_solidity/src/generated/bindings/generated/binding_rules.rs @@ -3,6 +3,368 @@ #[allow(clippy::needless_raw_string_hashes)] #[allow(dead_code)] // TODO(#982): use to create the graph pub const BINDING_RULES_SOURCE: &str = r#####" - // TODO(#982): add rules for Solidity here... + attribute node_definition = node => type = "pop_symbol", node_symbol = node, is_definition +attribute node_reference = node => type = "push_symbol", node_symbol = node, is_reference +attribute node_symbol = node => symbol = (source-text node), source_node = node +attribute pop_symbol = symbol => type = "pop_symbol", symbol = symbol +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 + +;; Generalities +;; - we will define two nodes for all meaningful CST nodes +;; - a lexical_scope node which will connect "upwards" towards the root of the CST +;; - a defs node to access the definitions reachable from each node (usually connecting "downwards") +;; - the pair will not be created for every CST node, as there is a lot of redundancy in the tree +;; - identifier nodes that are part of the definition of an artifact +;; will create graph nodes with the node_definition attributes +;; - identifier nodes that are references will create graph nodes with the node_reference attributes + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Source unit (aka .sol file) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@source_unit [SourceUnit] { + node @source_unit.lexical_scope + node @source_unit.defs +} + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Contract definitions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@contract [ContractDefinition] { + node @contract.lexical_scope + node @contract.defs +} + +@contract [ContractDefinition ... @name name: [Identifier] ...] { + node def + attr (def) node_definition = @name + + edge @contract.lexical_scope -> def + edge @contract.defs -> def +} + +;; Connect the contract to its containing source unit +@source_unit [SourceUnit ... [SourceUnitMembers + ... + [SourceUnitMember @contract [ContractDefinition]] + ... +] ...] { + edge @source_unit.defs -> @contract.defs + edge @contract.lexical_scope -> @source_unit.lexical_scope +} + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Interface definitions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@interface [InterfaceDefinition] { + node @interface.lexical_scope + node @interface.defs +} + +@interface [InterfaceDefinition ... @name name: [Identifier] ...] { + node def + attr (def) node_definition = @name + + edge @interface.lexical_scope -> def + edge @interface.defs -> def +} + +;; Connect the interface to its containing source unit +@source_unit [SourceUnit [SourceUnitMembers + ... + [SourceUnitMember @interface [InterfaceDefinition]] + ... +]] { + edge @source_unit.defs -> @interface.defs + edge @interface.lexical_scope -> @source_unit.lexical_scope +} + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Library definitions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@library [LibraryDefinition] { + node @library.lexical_scope + node @library.defs +} + +@library [LibraryDefinition ... @name name: [Identifier] ...] { + node def + attr (def) node_definition = @name + + edge @library.lexical_scope -> def + edge @library.defs -> def +} + +;; Connect the library to its containing source unit +@source_unit [SourceUnit [SourceUnitMembers + ... + [SourceUnitMember @library [LibraryDefinition]] + ... +]] { + edge @source_unit.defs -> @library.defs + edge @library.lexical_scope -> @source_unit.lexical_scope +} + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Function definitions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@function [FunctionDefinition] { + node @function.lexical_scope + node @function.defs +} + +@function [FunctionDefinition ... name: [FunctionName ... @name [Identifier] ...] ...] { + node def + attr (def) node_definition = @name + + edge @function.lexical_scope -> def + edge @function.defs -> def +} + +@param [Parameter] { + node @param.lexical_scope + node @param.defs +} + +@param [Parameter ... @name [Identifier]] { + node def + attr (def) node_definition = @name + + edge @param.lexical_scope -> def + edge @param.defs -> def +} + +;; Connect the parameters to the functions they belong to +@function [FunctionDefinition + ... + parameters: [_ ... parameters: [Parameters ... @param item: [Parameter] ...] ...] + ... +] { + edge @function.lexical_scope -> @param.defs + edge @function.defs -> @param.defs +} + +;; Connect the function to the contract/interface/library they belong to +[SourceUnitMember @unit_member variant: [_ + ... + members: [_ + ... + item: [_ @function variant: [FunctionDefinition]] + ... + ] + ... + ] +] { + edge @unit_member.lexical_scope -> @function.defs + edge @unit_member.defs -> @function.defs + edge @function.lexical_scope -> @unit_member.lexical_scope +} + +@body [FunctionBody] { + node @body.lexical_scope + node @body.defs +} + +;; Connect the function body to the function definition +@function [FunctionDefinition ... @body body: [FunctionBody] ...] { + edge @body.lexical_scope -> @function.lexical_scope + edge @function.defs -> @body.defs +} + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Blocks +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@block [Block] { + node @block.lexical_scope + node @block.defs +} + +@stmt [Statement] { + node @stmt.lexical_scope + node @stmt.defs +} + +@block [Block ... statements: [_ ... @stmt [Statement]...] ...] { + edge @stmt.lexical_scope -> @block.lexical_scope + edge @block.defs -> @stmt.defs +} + +@body [FunctionBody @block variant: [Block]] { + edge @block.lexical_scope -> @body.lexical_scope + edge @body.defs -> @block.defs +} + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Declaration Statements +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@stmt [Statement [VariableDeclarationStatement ... @name name: [Identifier] ...]] { + node def + attr (def) node_definition = @name + + edge @stmt.lexical_scope -> def + edge @stmt.defs -> def +} + +@stmt [Statement [TupleDeconstructionStatement + ... + [TupleDeconstructionElements + ... + item: [_ member: [_ variant: [_ ... @name name: [Identifier]]]] + ... + ] + ... +]] { + node def + attr (def) node_definition = @name + + edge @stmt.lexical_scope -> def + edge @stmt.defs -> def +} + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; State Variables +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@state_var [StateVariableDefinition] { + node @state_var.lexical_scope + node @state_var.defs +} + +@state_var [StateVariableDefinition ... @name name: [Identifier] ...] { + node def + attr (def) node_definition = @name + + edge @state_var.lexical_scope -> def + edge @state_var.defs -> def +} + +[SourceUnitMember @unit_member variant: [_ + ... + members: [_ + ... + item: [_ @state_var variant: [StateVariableDefinition]] + ... + ] + ... + ] +] { + edge @unit_member.lexical_scope -> @state_var.defs + edge @unit_member.defs -> @state_var.defs + edge @state_var.lexical_scope -> @unit_member.lexical_scope +} + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Structure definitions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@struct [StructDefinition] { + node @struct.lexical_scope + node @struct.defs +} + +@struct [StructDefinition ... @name name: [Identifier] ...] { + node def + attr (def) node_definition = @name + + edge @struct.lexical_scope -> def + edge @struct.defs -> def +} + +;; Connect the struct to the contract/interface/library they belong to +[SourceUnitMember @unit_member variant: [_ + ... + members: [_ + ... + item: [_ @struct variant: [StructDefinition]] + ... + ] + ... + ] +] { + edge @unit_member.lexical_scope -> @struct.defs + edge @unit_member.defs -> @struct.defs +} + +@member [StructMember] { + node @member.lexical_scope + node @member.defs +} + +@member item: [StructMember ... @name name: [Identifier] ...] { + node member + attr (member) pop_symbol = "." + edge @member.defs -> member + + node def + attr (def) node_definition = @name + edge member -> def +} + +;; TODO: missing connection between the struct field declarations and the struct + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;;; Expressions +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +@expr [Expression] { + node @expr.lexical_scope +} + +@expr [Expression ... @name variant: [Identifier]] { + node ref + attr (ref) node_reference = @name + + edge ref -> @expr.lexical_scope +} + +@expr [Expression ... variant: [_ ... @child [Expression] ...] ...] { + edge @child.lexical_scope -> @expr.lexical_scope +} + +@stmt [Statement ... variant: [_ ... @expr [Expression] ...] ...] { + edge @expr.lexical_scope -> @stmt.lexical_scope +} + +@member [MemberAccess] { + node @member.lexical_scope +} + +@member [MemberAccess @name [Identifier]] { + node ref + attr (ref) node_reference = @name + + edge ref -> @member.lexical_scope +} + +[MemberAccessExpression + ... + @expr operand: [Expression] + ... + @member member: [MemberAccess] + ... +] { + node member + attr (member) push_symbol = "." + + edge @member.lexical_scope -> member + edge member -> @expr.lexical_scope +} "#####; diff --git a/crates/solidity/outputs/cargo/slang_solidity/src/generated/bindings/mod.rs b/crates/solidity/outputs/cargo/slang_solidity/src/generated/bindings/mod.rs index 479ac6462..21ba7b153 100644 --- a/crates/solidity/outputs/cargo/slang_solidity/src/generated/bindings/mod.rs +++ b/crates/solidity/outputs/cargo/slang_solidity/src/generated/bindings/mod.rs @@ -3,11 +3,15 @@ #[path = "generated/binding_rules.rs"] mod binding_rules; -use metaslang_graph_builder::ast; pub use metaslang_graph_builder::functions::Functions; +use metaslang_graph_builder::{ast, ParseError}; pub use metaslang_graph_builder::{ExecutionConfig, ExecutionError, NoCancellation, Variables}; use crate::cst::KindTypes; pub type File = ast::File; pub type Graph = metaslang_graph_builder::graph::Graph; + +pub fn get_stack_graph_builder() -> Result { + File::from_str(binding_rules::BINDING_RULES_SOURCE) +} diff --git a/crates/solidity/outputs/cargo/tests/src/graph_output/mod.rs b/crates/solidity/outputs/cargo/tests/src/graph_output/mod.rs index ddca5968c..6b971a520 100644 --- a/crates/solidity/outputs/cargo/tests/src/graph_output/mod.rs +++ b/crates/solidity/outputs/cargo/tests/src/graph_output/mod.rs @@ -3,7 +3,7 @@ use infra_utils::cargo::CargoWorkspace; use infra_utils::paths::FileWalker; use semver::Version; use slang_solidity::bindings::{ - ExecutionConfig, File as GraphBuilderFile, Functions, Graph, NoCancellation, Variables, + get_stack_graph_builder, ExecutionConfig, Functions, Graph, NoCancellation, Variables, }; use slang_solidity::language::Language; use std::fmt; @@ -31,10 +31,7 @@ fn run(file_name: &str) -> Result<()> { let parse_output = language.parse(Language::ROOT_KIND, &input); assert!(parse_output.is_valid()); - let msgb_path = - CargoWorkspace::locate_source_crate("solidity_stack_graph")?.join("stack-graphs.msgb"); - let msgb_source = fs::read_to_string(&msgb_path)?; - let graph_builder = GraphBuilderFile::from_str(&msgb_source)?; + let graph_builder = get_stack_graph_builder()?; let functions = Functions::stdlib(); let variables = Variables::new(); diff --git a/crates/testlang/outputs/cargo/slang_testlang/src/generated/bindings/mod.rs b/crates/testlang/outputs/cargo/slang_testlang/src/generated/bindings/mod.rs index 479ac6462..21ba7b153 100644 --- a/crates/testlang/outputs/cargo/slang_testlang/src/generated/bindings/mod.rs +++ b/crates/testlang/outputs/cargo/slang_testlang/src/generated/bindings/mod.rs @@ -3,11 +3,15 @@ #[path = "generated/binding_rules.rs"] mod binding_rules; -use metaslang_graph_builder::ast; pub use metaslang_graph_builder::functions::Functions; +use metaslang_graph_builder::{ast, ParseError}; pub use metaslang_graph_builder::{ExecutionConfig, ExecutionError, NoCancellation, Variables}; use crate::cst::KindTypes; pub type File = ast::File; pub type Graph = metaslang_graph_builder::graph::Graph; + +pub fn get_stack_graph_builder() -> Result { + File::from_str(binding_rules::BINDING_RULES_SOURCE) +}