tree-sitter / tree-sitter/node-tree-sitter
query fails to match+capture with predicates against alternating and repeating s-expressions
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 876
- Forks
- 172
- PR merge metrics
- No merged PRs in 30d
Description
I'm attempting to capture the value of required_prop and, where it equals "the right value", that of conditional_prop. My query does not yield the results I expect, and diverges from the output on the tree-sitter playground. I discovered different incorrect alternation behavior there in https://github.com/tree-sitter/tree-sitter/issues/1584, but I suspect node-tree-sitter is having its own problem with predicates as well.
index.js
import * as TreeSitter from 'tree-sitter';
import Python from 'tree-sitter-python';
const code = `
class One(args):
required_prop = 'i will match, because conditional_prop may be omitted'
class Two(args):
required_prop = 'i will match, because conditional_prop can be anything'
conditional_prop = 'i do not have the correct value to be captured'
class Three(args):
required_prop = 'i will match, as will conditional_prop'
conditional_prop = 'the right value'
class Four(args):
conditional_prop = 'the right value'
required_prop = 'i will also match along with conditional_prop'
`;
const query = `(class_definition
name: (identifier) @ref
body: (block [
(expression_statement
(assignment
left: (identifier) @required
right: (string) @required_val)
(#match? @required "required_prop")
)
(_)
(expression_statement
(assignment
left: (identifier) @conditional
right: (string) @conditional_val
(#match? @conditional "conditional_prop")
(#match? @conditional_val "the right value")
))
]+))`;
(() => {
const parser = TreeSitter.default();
parser.setLanguage(Python);
const tree = parser.parse(code);
const matches = new TreeSitter.Query(parser.getLanguage(), query).matches(tree.rootNode);
matches.forEach(m => {
m.captures.forEach(c => console.log(c.name, tree.getText(c.node)));
console.log();
});
})();
package.json
{
"name": "tree-sitter-query-testing",
"version": "1.0.0",
"description": "",
"type": "module",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"tree-sitter": "^0.20.0",
"tree-sitter-python": "^0.19.0"
}
}
I expect all classes to match, and all required_props to be captured. With the query as-is, the only matches are Three and Four (output is capture name and text):
> node index.js
ref Three
required required_prop
required_val 'i will match, as will conditional_prop'
conditional conditional_prop
conditional_val 'the right value'
ref Four
conditional conditional_prop
conditional_val 'the right value'
required required_prop
required_val 'i will also match along with conditional_prop'
In the playground, removing the repetition + on the prop alternation yields the expected results, but in node-tree-sitter instead nothing matches.
Removing both conditional predicates allows all @required and @required_vals to be captured, but no @conditional or @conditional_vals are found in spite of there being seven expression_statements that meet its definition in the program.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the reproduction in index.js and its tree-sitter and tree-sitter-python versions in package.json. Run the query against the supplied Python code, then compare node-tree-sitter's results with the tree-sitter playground, focusing on repeated alternation and predicate handling. Done means all four classes match and the expected required and conditional captures are returned.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, nodejs
- Domain
- tooling
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100