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

query fails to match+capture with predicates against alternating and repeating s-expressions #98

Open
dmfay opened this issue Jan 13, 2022 · 0 comments

Comments

@dmfay
Copy link

dmfay commented Jan 13, 2022

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 tree-sitter/tree-sitter#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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant