How to get the tree structure data of class/property/method in tree-sitter:
I can only match the class like below:
const Parser = require("tree-sitter")
const JavaScript = require("tree-sitter-javascript")
const { Query } = Parser
const parser = new Parser()
parser.setLanguage(JavaScript)
const query = new Query(
JavaScript,
`
(class_declaration name: (identifier) @class-name)
`
);
const tree = parser.parse(`
class Person {}
const TestPerson = class {}
class Person2 {}
const TestPerson2 = class {}
`);
const matches = query.matches(tree.rootNode);
matches.forEach(item => {
console.log(item.captures[0])
})
there I can get the classnames of a file.
but you see the GitHub page: I want to get the tree structure data of AST:
1、please help with how to match the AST tree data?
2、you see the snapshot display a 3-layer depth tree data, how to control the matched tree data depth?
Normally, this is usally achieved by programmatically iterate through the syntax tree instead of direct matching. If you really want go matching, then I think the answer by @Prabhat is the one for you.
If you want alternative way by iterating the AST, here's the solution:
const Parser = require('tree-sitter');
const JavaScript = require('tree-sitter-javascript');
const parser = new Parser();
parser.setLanguage(JavaScript);
const code = `INSERT YOUR CODE HERE`;
// Parse the JavaScript code
const tree = parser.parse(code);
// AST type to readable name map
const treeTypeNameMap = {
"class_declaration": "class",
"method_definition": "method",
"function_declaration": "function"
}
// Nodes that we consider to increment the depth level.
// For example, when we enter a new class body, or new statement block.
const depthNodes = [
"class_body", "statement_block"
];
// Recursively traverse the syntax tree up to a certain depth
function findClassesAndMethods(node, currentDepth = 0, maxDepth = 3) {
// If we reached the maximum depth, return
if (currentDepth >= maxDepth) {
return;
}
let nextDepth = currentDepth;
// Only increment depth level if we encounter a new class body or statement block
if (depthNodes.includes(node.type)) {
nextDepth += 1;
} else if (node.type in treeTypeNameMap) {
const name = node.childForFieldName("name").text;
console.log("-".repeat(currentDepth), treeTypeNameMap[node.type], name);
}
node.children.forEach(child => findClassesAndMethods(child, nextDepth, maxDepth))
}
// Start traversing from the root node
findClassesAndMethods(tree.rootNode);
Example input:
class C {
A() {
{
class AInner {}
}
class B {
}
}
}
class A {
constructor() {}
B() {
class C {
}
}
}
And its output:
class C
- method A
-- class B
class A
- method constructor
- method B
-- class C