From 85345f5dd84684f67221fcb1d2844f0738be9d6a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gustavo=20Gir=C3=A1ldez?= Date: Tue, 25 Jun 2024 13:53:57 -0400 Subject: [PATCH] Output bindings snapshots in addition to graph outputs --- Cargo.lock | 1 + .../runtime/cargo/src/runtime/bindings/mod.rs | 8 ++ .../src/generated/bindings/mod.rs | 8 ++ .../solidity/outputs/cargo/tests/Cargo.toml | 1 + .../cargo/tests/src/bindings_output/runner.rs | 101 ++++++++++++++++-- .../lexical/generated/local_vars.sol.txt | 26 +++++ .../lexical/generated/params.sol.txt | 23 ++++ .../lexical/generated/state_vars.sol.txt | 34 ++++++ .../src/generated/bindings/mod.rs | 8 ++ 9 files changed, 199 insertions(+), 11 deletions(-) create mode 100644 crates/solidity/testing/snapshots/bindings_output/lexical/generated/local_vars.sol.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/lexical/generated/params.sol.txt create mode 100644 crates/solidity/testing/snapshots/bindings_output/lexical/generated/state_vars.sol.txt diff --git a/Cargo.lock b/Cargo.lock index 5cd83d0437..01ae50cc96 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2172,6 +2172,7 @@ version = "0.15.0" dependencies = [ "Inflector", "anyhow", + "ariadne", "codegen_language_definition", "codegen_testing", "infra_utils", diff --git a/crates/codegen/runtime/cargo/src/runtime/bindings/mod.rs b/crates/codegen/runtime/cargo/src/runtime/bindings/mod.rs index a281d6d9e6..d986065fe4 100644 --- a/crates/codegen/runtime/cargo/src/runtime/bindings/mod.rs +++ b/crates/codegen/runtime/cargo/src/runtime/bindings/mod.rs @@ -220,3 +220,11 @@ impl Debug for Handle<'_> { f.debug_tuple("BindingsHandle").field(&self.handle).finish() } } + +impl PartialEq for Handle<'_> { + fn eq(&self, other: &Self) -> bool { + let our_owner: *const Bindings = self.owner; + let other_owner: *const Bindings = other.owner; + our_owner == other_owner && self.handle == other.handle + } +} 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 18805c412e..4e9409415a 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 @@ -222,3 +222,11 @@ impl Debug for Handle<'_> { f.debug_tuple("BindingsHandle").field(&self.handle).finish() } } + +impl PartialEq for Handle<'_> { + fn eq(&self, other: &Self) -> bool { + let our_owner: *const Bindings = self.owner; + let other_owner: *const Bindings = other.owner; + our_owner == other_owner && self.handle == other.handle + } +} diff --git a/crates/solidity/outputs/cargo/tests/Cargo.toml b/crates/solidity/outputs/cargo/tests/Cargo.toml index 2e9c1767f1..2387df5f16 100644 --- a/crates/solidity/outputs/cargo/tests/Cargo.toml +++ b/crates/solidity/outputs/cargo/tests/Cargo.toml @@ -13,6 +13,7 @@ solidity_language = { workspace = true } [dev-dependencies] anyhow = { workspace = true } +ariadne = { workspace = true } codegen_language_definition = { workspace = true } Inflector = { workspace = true } infra_utils = { workspace = true } diff --git a/crates/solidity/outputs/cargo/tests/src/bindings_output/runner.rs b/crates/solidity/outputs/cargo/tests/src/bindings_output/runner.rs index 6588227877..1ceb9de308 100644 --- a/crates/solidity/outputs/cargo/tests/src/bindings_output/runner.rs +++ b/crates/solidity/outputs/cargo/tests/src/bindings_output/runner.rs @@ -1,15 +1,17 @@ use std::fmt; -use std::fs::{self, create_dir_all}; -use std::path::PathBuf; +use std::fs::{self, create_dir_all, File}; +use std::ops::Range; +use std::path::{Path, PathBuf}; use anyhow::Result; +use ariadne::{Color, Config, Label, Report, ReportBuilder, ReportKind, Source}; use infra_utils::cargo::CargoWorkspace; use metaslang_graph_builder::stack_graph; use semver::Version; use slang_solidity::bindings::graph_builder::{ ExecutionConfig, Graph, NoCancellation, Value, Variables, }; -use slang_solidity::bindings::Bindings; +use slang_solidity::bindings::{Bindings, Handle}; use slang_solidity::language::Language; use slang_solidity::parse_output::ParseOutput; @@ -18,7 +20,7 @@ pub fn run(group_name: &str, file_name: &str) -> Result<()> { .join("bindings_output") .join(group_name); let input_path = data_dir.join(file_name); - let input = fs::read_to_string(input_path)?; + let input = fs::read_to_string(&input_path)?; // TODO: de-hardcode this and parse with different versions? let version = Language::SUPPORTED_VERSIONS.last().unwrap(); @@ -28,9 +30,19 @@ pub fn run(group_name: &str, file_name: &str) -> Result<()> { assert!(parse_output.is_valid()); let output_dir = data_dir.join("generated"); - let output_path = output_dir.join(format!("{file_name}.mmd")); create_dir_all(&output_dir)?; - output_graph(version, &parse_output, &output_path)?; + + let graph_output_path = output_dir.join(format!("{file_name}.mmd")); + output_graph(version, &parse_output, graph_output_path)?; + + let bindings_output_path = output_dir.join(format!("{file_name}.txt")); + output_bindings( + version, + &parse_output, + &input, + &input_path, + bindings_output_path, + )?; Ok(()) } @@ -42,11 +54,7 @@ const VARIABLE_DEBUG_ATTR: &str = "__variable"; const LOCATION_DEBUG_ATTR: &str = "__location"; const MATCH_DEBUG_ATTR: &str = "__match"; -fn output_graph( - version: &Version, - parse_output: &ParseOutput, - output_path: &PathBuf, -) -> Result<()> { +fn output_graph(version: &Version, parse_output: &ParseOutput, output_path: PathBuf) -> Result<()> { let graph_builder = Bindings::get_graph_builder()?; let tree = parse_output.create_tree_cursor(); @@ -119,3 +127,74 @@ fn print_graph_as_mermaid(graph: &Graph) -> impl fmt::Display + '_ { DisplayGraph(graph) } + +fn output_bindings( + version: &Version, + parse_output: &ParseOutput, + input: &str, + input_path: &Path, + output_path: PathBuf, +) -> Result<()> { + let mut bindings = Bindings::create(version.clone()); + bindings.add_file( + input_path.to_str().unwrap(), + parse_output.create_tree_cursor(), + )?; + + let file_id = input_path.file_name().unwrap().to_str().unwrap(); + let mut builder: ReportBuilder<'_, (&str, Range)> = Report::build( + ReportKind::Custom("References and definitions", Color::Unset), + file_id, + 0, + ) + .with_config(Config::default().with_color(false)); + + let mut definitions: Vec> = Vec::new(); + + for definition in bindings.all_definitions() { + let Some(cursor) = definition.get_cursor() else { + continue; + }; + + let range = { + let range = cursor.text_range(); + let start = input[..range.start.utf8].chars().count(); + let end = input[..range.end.utf8].chars().count(); + start..end + }; + + definitions.push(definition); + let message = format!("def: {}", definitions.len()); + builder = builder.with_label(Label::new((file_id, range)).with_message(message)); + } + + for reference in bindings.all_references() { + let Some(cursor) = reference.get_cursor() else { + continue; + }; + + let range = { + let range = cursor.text_range(); + let start = input[..range.start.utf8].chars().count(); + let end = input[..range.end.utf8].chars().count(); + start..end + }; + + let definition = reference.jump_to_definition(); + let message = match definition { + None => "unresolved".to_string(), + Some(definition) => { + let def_id = definitions.iter().position(|d| *d == definition).unwrap(); + format!("ref: {}", def_id + 1) + } + }; + + builder = builder.with_label(Label::new((file_id, range)).with_message(message)); + } + + let report = builder.finish(); + let output_file = File::create(output_path)?; + report.write((file_id, Source::from(input)), output_file)?; + + Ok(()) +} diff --git a/crates/solidity/testing/snapshots/bindings_output/lexical/generated/local_vars.sol.txt b/crates/solidity/testing/snapshots/bindings_output/lexical/generated/local_vars.sol.txt new file mode 100644 index 0000000000..6f0f443eaa --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/lexical/generated/local_vars.sol.txt @@ -0,0 +1,26 @@ +References and definitions: + ╭─[local_vars.sol:1:1] + │ + 1 │ contract Foo { + │ ─┬─ + │ ╰─── def: 1 + 2 │ function bar() returns (uint) { + │ ─┬─ + │ ╰─── def: 2 + 3 │ uint x = 10; + │ ┬ + │ ╰── def: 3 + │ + 6 │ return x + 2; + │ ┬ + │ ╰── ref: 3 + │ + 10 │ function baz() returns (int) { + │ ─┬─ + │ ╰─── def: 4 + 11 │ return w + x; + │ ┬ ┬ + │ ╰────── unresolved + │ │ + │ ╰── unresolved +────╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/lexical/generated/params.sol.txt b/crates/solidity/testing/snapshots/bindings_output/lexical/generated/params.sol.txt new file mode 100644 index 0000000000..f39f9ec74e --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/lexical/generated/params.sol.txt @@ -0,0 +1,23 @@ +References and definitions: + ╭─[params.sol:1:1] + │ + 1 │ contract Foo { + │ ─┬─ + │ ╰─── def: 1 + 2 │ function bar(uint z) returns (uint) { + │ ─┬─ ┬ + │ ╰────────── def: 2 + │ │ + │ ╰── def: 3 + │ + 5 │ return z + 1; + │ ┬ + │ ╰── ref: 3 + │ + 9 │ function baz() returns (int) { + │ ─┬─ + │ ╰─── def: 4 + 10 │ return z + 2; + │ ┬ + │ ╰── unresolved +────╯ diff --git a/crates/solidity/testing/snapshots/bindings_output/lexical/generated/state_vars.sol.txt b/crates/solidity/testing/snapshots/bindings_output/lexical/generated/state_vars.sol.txt new file mode 100644 index 0000000000..7ebdec1747 --- /dev/null +++ b/crates/solidity/testing/snapshots/bindings_output/lexical/generated/state_vars.sol.txt @@ -0,0 +1,34 @@ +References and definitions: + ╭─[state_vars.sol:1:1] + │ + 1 │ contract Foo { + │ ─┬─ + │ ╰─── def: 1 + 2 │ uint x; + │ ┬ + │ ╰── def: 2 + │ + 5 │ function bar() returns (uint) { + │ ─┬─ + │ ╰─── def: 3 + 6 │ return x; + │ ┬ + │ ╰── ref: 2 + │ + 10 │ function baz() returns (int) { + │ ─┬─ + │ ╰─── def: 4 + 11 │ return y; + │ ┬ + │ ╰── unresolved + │ + 16 │ contract Bar { + │ ─┬─ + │ ╰─── def: 5 + 17 │ function quux() returns (uint) { + │ ──┬─ + │ ╰─── def: 6 + 18 │ return x; + │ ┬ + │ ╰── unresolved +────╯ 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 18805c412e..4e9409415a 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 @@ -222,3 +222,11 @@ impl Debug for Handle<'_> { f.debug_tuple("BindingsHandle").field(&self.handle).finish() } } + +impl PartialEq for Handle<'_> { + fn eq(&self, other: &Self) -> bool { + let our_owner: *const Bindings = self.owner; + let other_owner: *const Bindings = other.owner; + our_owner == other_owner && self.handle == other.handle + } +}