Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Integrate Graph Builder from tree-sitter-graph #918

Merged
merged 1 commit into from
May 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
290 changes: 241 additions & 49 deletions Cargo.lock

Large diffs are not rendered by default.

17 changes: 12 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ members = [
"crates/infra/utils",

"crates/metaslang/cst",
"crates/metaslang/graph_builder",

"crates/solidity/inputs/language",
"crates/solidity/outputs/cargo/slang_solidity_node_addon",
Expand Down Expand Up @@ -60,6 +61,7 @@ codegen_testing = { path = "crates/codegen/testing" }
infra_cli = { path = "crates/infra/cli" }
infra_utils = { path = "crates/infra/utils" }

metaslang_graph_builder = { path = "crates/metaslang/graph_builder" }
metaslang_cst = { path = "crates/metaslang/cst" }

slang_solidity = { path = "crates/solidity/outputs/cargo/slang_solidity" }
Expand Down Expand Up @@ -90,11 +92,14 @@ clap = { version = "4.5.4", features = ["derive", "wrap_help"] }
clap_complete = { version = "4.5.2" }
console = { version = "0.15.8" }
derive-new = { version = "0.6.0" }
env_logger = { version = "0.11.3" }
ignore = { version = "0.4.22" }
indexmap = { version = "2.2.6", features = ["serde"] }
indicatif = { version = "0.17.8", features = ["in_memory"] }
indoc = { version = "2.0.5" }
Inflector = { version = "0.11.4" }
itertools = { version = "0.10.5" }
itertools = { version = "0.13.0" }
log = { version = "0.4.14" }
markdown = { version = "0.3.0" }
napi = { version = "2.16.6", features = ["compat-mode", "napi8", "serde-json"] }
napi-build = { version = "2.1.3" }
Expand All @@ -106,14 +111,16 @@ proc-macro2 = { version = "1.0.82" }
quote = { version = "1.0.36" }
rayon = { version = "1.10.0" }
regex = { version = "1.10.4" }
reqwest = { version = "0.11.27", features = ["blocking"] }
reqwest = { version = "0.12.4", features = ["blocking"] }
semver = { version = "1.0.23", features = ["serde"] }
serde = { version = "1.0.201", features = ["derive", "rc"] }
serde_json = { version = "1.0.117", features = ["preserve_order"] }
similar-asserts = { version = "1.5.0" }
stack-graphs = { version = "0.12.0" }
strum = { version = "0.25.0" }
strum_macros = { version = "0.25.3" }
smallvec = { version = "1.7.0" }
stack-graphs = { version = "0.13.0" }
string-interner = { version = "0.17.0", default-features = false }
strum = { version = "0.26.2" }
strum_macros = { version = "0.26.2" }
syn = { version = "2.0.63", features = [
"fold",
"full",
Expand Down
3 changes: 3 additions & 0 deletions crates/codegen/runtime/cargo/src/runtime/generated/kinds.rs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions crates/codegen/runtime/cargo/src/runtime/kinds.rs.jinja2
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use napi_derive::napi;
strum_macros::AsRefStr,
strum_macros::Display,
strum_macros::EnumString,
strum_macros::IntoStaticStr,
)]
#[cfg_attr(feature = "slang_napi_interfaces", /* derives `Clone` and `Copy` */ napi(string_enum, namespace = "kinds"))]
#[cfg_attr(not(feature = "slang_napi_interfaces"), derive(Clone, Copy))]
Expand Down Expand Up @@ -41,6 +42,7 @@ impl metaslang_cst::NonTerminalKind for NonTerminalKind {}
strum_macros::AsRefStr,
strum_macros::Display,
strum_macros::EnumString,
strum_macros::IntoStaticStr,
)]
#[strum(serialize_all = "snake_case")]
#[cfg_attr(feature = "slang_napi_interfaces", /* derives `Clone` and `Copy` */ napi(string_enum, namespace = "kinds"))]
Expand Down Expand Up @@ -82,6 +84,7 @@ impl metaslang_cst::EdgeLabel for EdgeLabel {}
strum_macros::AsRefStr,
strum_macros::Display,
strum_macros::EnumString,
strum_macros::IntoStaticStr,
)]
#[cfg_attr(feature = "slang_napi_interfaces", /* derives `Clone` and `Copy` */ napi(string_enum, namespace = "kinds"))]
#[cfg_attr(not(feature = "slang_napi_interfaces"), derive(Clone, Copy))]
Expand Down
4 changes: 2 additions & 2 deletions crates/codegen/runtime/cargo/src/runtime/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,8 @@ pub mod query {
use super::metaslang_cst::KindTypes;

pub type Query = query::Query<KindTypes>;
pub type QueryResult = query::QueryResult<KindTypes>;
pub type QueryResultIterator = query::QueryResultIterator<KindTypes>;
pub type QueryMatch = query::QueryMatch<KindTypes>;
pub type QueryMatchIterator = query::QueryMatchIterator<KindTypes>;
}

pub mod text_index {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use napi::Either;
use napi_derive::napi;

use crate::napi_interface::cst::{NAPINodeExtensions, NonTerminalNode, TerminalNode};
use crate::napi_interface::{NonTerminalKind, RustLabeledNode, RustNode, RustRuleNode, TerminalKind};
use crate::napi_interface::{NonTerminalKind, RustEdge, RustNode, RustNonTerminalNode, TerminalKind};

//
// Sequences:
Expand Down Expand Up @@ -273,7 +273,7 @@ pub fn select_separated(
//

struct Selector {
node: Rc<RustRuleNode>,
node: Rc<RustNonTerminalNode>,
index: usize,
}

Expand All @@ -300,7 +300,7 @@ impl Selector {
self.index += 1;
continue;
}
RustLabeledNode {
RustEdge {
node: RustNode::Terminal(terminal),
..
} if matches!(terminal.kind, TerminalKind::SKIPPED) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use napi_derive::napi;
use crate::napi_interface::cursor::Cursor;
use crate::napi_interface::text_index::TextIndex;
use crate::napi_interface::{
NonTerminalKind, RustNode, RustRuleNode, RustTextIndex, RustTokenNode, TerminalKind,
NonTerminalKind, RustNode, RustNonTerminalNode, RustTerminalNode, RustTextIndex, TerminalKind,
};

#[napi(namespace = "cst", string_enum)]
Expand All @@ -31,11 +31,11 @@ impl NAPINodeExtensions for RustNode {

#[derive(Debug)]
#[napi(namespace = "cst")]
pub struct NonTerminalNode(pub(crate) Rc<RustRuleNode>);
pub struct NonTerminalNode(pub(crate) Rc<RustNonTerminalNode>);

#[derive(Debug)]
#[napi(namespace = "cst")]
pub struct TerminalNode(pub(crate) Rc<RustTokenNode>);
pub struct TerminalNode(pub(crate) Rc<RustTerminalNode>);

#[napi(namespace = "cst")]
impl NonTerminalNode {
Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions crates/codegen/runtime/cargo/src/runtime/napi_interface/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,17 @@ pub mod text_index;
pub mod ast_selectors;

type RustCursor = crate::cursor::Cursor;
type RustLabeledNode = crate::cst::Edge;
type RustEdge = crate::cst::Edge;
type RustNode = crate::cst::Node;
type RustParseError = crate::parse_error::ParseError;
type RustParseOutput = crate::parse_output::ParseOutput;
type RustQuery = crate::query::Query;
type RustQueryResult = crate::query::QueryResult;
type RustQueryResultIterator = crate::query::QueryResultIterator;
type RustRuleNode = crate::cst::NonTerminalNode;
type RustQueryMatch = crate::query::QueryMatch;
type RustQueryMatchIterator = crate::query::QueryMatchIterator;
type RustNonTerminalNode = crate::cst::NonTerminalNode;
type RustTextIndex = crate::text_index::TextIndex;
type RustTextRange = crate::text_index::TextRange;
type RustTokenNode = crate::cst::TerminalNode;
type RustTerminalNode = crate::cst::TerminalNode;

type NonTerminalKind = crate::kinds::NonTerminalKind;
type TerminalKind = crate::kinds::TerminalKind;
Expand Down
28 changes: 14 additions & 14 deletions crates/codegen/runtime/cargo/src/runtime/napi_interface/query.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use napi::Env;
use napi_derive::napi;

use crate::napi_interface::cursor::Cursor;
use crate::napi_interface::{RustQuery, RustQueryResult, RustQueryResultIterator};
use crate::napi_interface::{RustQuery, RustQueryMatch, RustQueryMatchIterator};

#[napi(namespace = "query")]
pub struct Query(RustQuery);
Expand All @@ -26,30 +26,30 @@ impl Query {
#[napi(factory, catch_unwind)]
pub fn parse(text: String) -> napi::Result<Query> {
RustQuery::parse(text.as_str()).map_or_else(
|err| Err(napi::Error::from_reason(err)),
|err| Err(napi::Error::from_reason(err.message)),
|query| Ok(query.into()),
)
}
}

#[napi(namespace = "query")]
pub struct QueryResultIterator(RustQueryResultIterator);
pub struct QueryMatchIterator(RustQueryMatchIterator);

#[napi(object, namespace = "query")]
pub struct QueryResult {
pub struct QueryMatch {
pub query_number: u32,
#[napi(ts_type = "{ [key: string]: cursor.Cursor[] }")]
pub bindings: HashMap<String, Vec<ClassInstance<Cursor>>>,
}

impl QueryResult {
fn new(env: Env, result: RustQueryResult) -> napi::Result<Self> {
impl QueryMatch {
fn new(env: Env, result: RustQueryMatch) -> napi::Result<Self> {
#[allow(clippy::cast_possible_truncation)]
let query_number = result.query_number as u32;
// transfer all of the bindings eagerly on the assumption
// that they've all been explicitly requested.
let bindings = result
.bindings
.captures
.into_iter()
.map(|(key, values)| {
let instances = values
Expand All @@ -68,30 +68,30 @@ impl QueryResult {
}
}

impl From<RustQueryResultIterator> for QueryResultIterator {
fn from(value: RustQueryResultIterator) -> Self {
impl From<RustQueryMatchIterator> for QueryMatchIterator {
fn from(value: RustQueryMatchIterator) -> Self {
Self(value)
}
}

#[napi(namespace = "query")]
impl QueryResultIterator {
impl QueryMatchIterator {
#[napi(catch_unwind)]
pub fn next(&mut self, env: Env) -> napi::Result<Option<QueryResult>> {
pub fn next(&mut self, env: Env) -> napi::Result<Option<QueryMatch>> {
match self.0.next() {
Some(result) => Ok(Some(QueryResult::new(env, result)?)),
Some(result) => Ok(Some(QueryMatch::new(env, result)?)),
None => Ok(None),
}
}
}

#[napi(namespace = "cursor")]
impl Cursor {
#[napi(ts_return_type = "query.QueryResultIterator", catch_unwind)]
#[napi(ts_return_type = "query.QueryMatchIterator", catch_unwind)]
pub fn query(
&self,
#[napi(ts_arg_type = "Array<query.Query>")] queries: Vec<&Query>,
) -> QueryResultIterator {
) -> QueryMatchIterator {
self.0
.clone()
.query(queries.into_iter().map(|x| x.0.clone()).collect())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ use crate::napi_interface::{RustTextIndex, RustTextRange};
pub struct TextIndex {
pub utf8: u32,
pub utf16: u32,
pub char: u32,
pub line: u32,
pub column: u32,
}

impl From<RustTextIndex> for TextIndex {
Expand All @@ -17,7 +18,8 @@ impl From<RustTextIndex> for TextIndex {
Self {
utf8: value.utf8 as u32,
utf16: value.utf16 as u32,
char: value.char as u32,
line: value.line as u32,
column: value.column as u32,
}
}
}
Expand All @@ -27,7 +29,8 @@ impl From<TextIndex> for RustTextIndex {
Self {
utf8: value.utf8 as usize,
utf16: value.utf16 as usize,
char: value.char as usize,
line: value.line as usize,
column: value.column as usize,
}
}
}
Expand Down
8 changes: 6 additions & 2 deletions crates/codegen/runtime/cargo/src/runtime/parse_error.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::collections::BTreeSet;

use crate::kinds::TerminalKind;
use crate::text_index::{TextRange, TextRangeExtensions};
use crate::text_index::TextRange;

#[derive(Debug, PartialEq, Eq, Clone)]
pub struct ParseError {
Expand Down Expand Up @@ -69,7 +69,11 @@ pub(crate) fn render_error_report(
return format!("{kind}: {message}\n ─[{source_id}:0:0]");
}

let range = error.text_range.char();
let range = {
let start = source[..error.text_range.start.utf8].chars().count();
let end = source[..error.text_range.end.utf8].chars().count();
start..end
};

let mut builder = Report::build(kind, source_id, range.start)
.with_config(Config::default().with_color(with_color))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,14 +89,17 @@ impl<'s> ParserContext<'s> {
self.source[self.position.utf8..].chars().next()
}

pub fn peek_pair(&self) -> Option<(char, Option<char>)> {
let mut iter = self.source[self.position.utf8..].chars();
iter.next().map(|c| (c, iter.next()))
}

#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<char> {
self.undo_position = Some(self.position);

if let Some(c) = self.peek() {
self.position.utf8 += c.len_utf8();
self.position.utf16 += c.len_utf16();
self.position.char += 1;
if let Some((c, n)) = self.peek_pair() {
self.position.advance(c, n.as_ref());
Some(c)
} else {
None
Expand Down
Loading