diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 007ca4a..26dad4b 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -17,7 +17,7 @@ jobs: strategy: fail-fast: false matrix: - rust: [beta, stable, nightly, 1.60.0] + rust: [beta, stable, nightly, 1.63.0] steps: - uses: actions/checkout@v2 - uses: dtolnay/rust-toolchain@master diff --git a/.vscode/settings.json b/.vscode/settings.json index 5749753..5956f4d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -2,5 +2,6 @@ "editor.formatOnSave": true, "rust-analyzer.cargo.features": [ // "syn" + "tree-sitter" ] } \ No newline at end of file diff --git a/Cargo.toml b/Cargo.toml index 07bfea1..b6b2f2c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,7 @@ rustdoc-types = { version = "0.11.0", optional = true } serde_json = { version = "1.0.82", optional = true } smallvec = { version = "1.9.0", optional = true } syn = { version = "1.0.98", features = ["full"], optional = true } +tree-sitter = { version = "0.20.9", optional = true } [features] kdl = ["dep:kdl", "miette"] # KDL's error has miette @@ -45,3 +46,4 @@ rustversion = "1.0.7" serde_json = "1.0.82" expect-test = "1.3.0" fxhash = "0.2.1" +tree-sitter-c = "0.20.2" diff --git a/src/hand_impls/mod.rs b/src/hand_impls/mod.rs index 2cb51e7..d4cf2e2 100644 --- a/src/hand_impls/mod.rs +++ b/src/hand_impls/mod.rs @@ -12,4 +12,5 @@ cfg_mod! { (serde_json "serde_json") (smallvec "smallvec") (syn "syn") + (tree_sitter "tree-sitter") } diff --git a/src/hand_impls/tree_sitter.rs b/src/hand_impls/tree_sitter.rs new file mode 100644 index 0000000..dae6ee0 --- /dev/null +++ b/src/hand_impls/tree_sitter.rs @@ -0,0 +1,38 @@ +use tree_sitter::{Node, Tree}; + +use crate::Debug; + +impl Debug for Tree { + fn fmt(&self, f: &mut crate::Formatter) { + f.debug_tuple("Tree").field(&self.root_node()).finish() + } +} + +impl Debug for Node<'_> { + fn fmt(&self, f: &mut crate::Formatter) { + // d.field("kind", &self.kind()); + + match self.child_count() { + 0 => f.debug_tuple("Node").field(&self.kind()).finish(), + 1 => f + .debug_struct("Node") + .field("kind", &self.kind()) + .field("child", &self.child(0).unwrap()) + .finish(), + _ => f + .debug_struct("Node") + .field("kind", &self.kind()) + .field("children", &Children(*self)) + .finish(), + } + } +} + +struct Children<'a>(Node<'a>); + +impl Debug for Children<'_> { + fn fmt(&self, f: &mut crate::Formatter) { + let mut walk = self.0.walk(); // This isn't very efficient, but eh + f.debug_list().entries(self.0.children(&mut walk)).finish() + } +} diff --git a/tests/it/main.rs b/tests/it/main.rs index 0cd6a73..3ab6bd9 100644 --- a/tests/it/main.rs +++ b/tests/it/main.rs @@ -4,8 +4,10 @@ mod derive; mod fxhash; mod kdl; mod motivating; +#[cfg(feature = "rustdoc_types")] mod rustdoc_types; mod serde_json; mod std; mod syn; +mod tree_sitter; mod ui; diff --git a/tests/it/tree_sitter.rs b/tests/it/tree_sitter.rs new file mode 100644 index 0000000..c263e57 --- /dev/null +++ b/tests/it/tree_sitter.rs @@ -0,0 +1,69 @@ +#![cfg(feature = "tree-sitter")] + +use debug3::pprint; + +use expect_test::{expect, Expect}; +use tree_sitter::Parser; + +fn check(input: &str, expected: Expect) { + let mut parser = Parser::new(); + parser.set_language(tree_sitter_c::language()).unwrap(); + let parsed = parser.parse(input, None).unwrap(); + let pp = pprint(&parsed); + expected.assert_eq(&pp); +} + +#[test] +fn basic() { + check("int double(int x) { return x * x; }", expect![[r#" + Tree( + Node { + kind: "translation_unit", + child: Node { + kind: "function_definition", + children: [ + Node("primitive_type"), + Node { + kind: "function_declarator", + children: [ + Node("identifier"), + Node { + kind: "parameter_list", + children: [ + Node("("), + Node { + kind: "parameter_declaration", + children: [Node("primitive_type"), Node("identifier")], + }, + Node(")"), + ], + }, + ], + }, + Node { + kind: "compound_statement", + children: [ + Node("{"), + Node { + kind: "return_statement", + children: [ + Node("return"), + Node { + kind: "binary_expression", + children: [ + Node("identifier"), + Node("*"), + Node("identifier"), + ], + }, + Node(";"), + ], + }, + Node("}"), + ], + }, + ], + }, + }, + )"#]]); +}