go-tree-sitter icon indicating copy to clipboard operation
go-tree-sitter copied to clipboard

Handle predicates

Open PKuebler opened this issue 2 years ago • 1 comments

Hello,

I have made a first attempt to teach the module predicates. I used the javascript example from issue #77 as a guideline.

Unfortunately the structure differs between the go-tree-sitter and the NodeJS version. In the NodeJS version the text is already present at each node.

To avoid breaking changes, I put it into a separate function that has to be executed separately.

The code changes are divided into 2 areas. The validation of the query takes place during the query creation, because there is an error handling. The application takes place later.

Still needed input

  • What is the best way to do the error handling. The existing error handling does not provide the space for information.
  • I am having a hard time adding tests since the previous tests generate anything. Would it be ok if I define test cases with their own input?

I am very uncomfortable that I have to ask you this, would it be possible to add the label hacktoberfest-accepted to the pull request?

Example

match, _ := qc.NextMatch()
match = qc.FilterPredicates(match, src)
if len(m.Captures) == 0 {
	continue
}

Complete Example

parser := sitter.NewParser()
parser.SetLanguage(javascript.GetLanguage())

fmt.Printf("Start with %s\n", test.Src)

src, err := os.ReadFile("test.js")
if err != nil {
	panic(err)
}

query, err := os.ReadFile("query.scm")
if err != nil {
	panic(err)
}

tree := parser.Parse(nil, src)
n := tree.RootNode()

q, _ := sitter.NewQuery(query, javascript.GetLanguage())
qc := sitter.NewQueryCursor()
qc.Exec(q, n)

for {
	m, ok := qc.NextMatch()
	if !ok {
		break
	}

	m = qc.FilterPredicates(m, src)
	if len(m.Captures) == 0 {
		continue
	}

	fmt.Printf(result, "  pattern: %d\n", m.PatternIndex)

	for _, c := range m.Captures {
		captureName := q.CaptureNameForId(c.Index)

		fmt.Printf(result, "    capture: %d", c.Index)
		fmt.Printf(result, " - %s", captureName)
		start := c.Node.StartPoint()
		end := c.Node.EndPoint()
		text := c.Node.Content(src)
		fmt.Printf(result, ", start: (%d, %d), end: (%d, %d), text: `%s`\n", start.Row, start.Column, end.Row, end.Column, text)
	}
}

PKuebler avatar Oct 04 '22 14:10 PKuebler

hi @PKuebler! great work! let me review it in detail later this week.

smacker avatar Oct 11 '22 13:10 smacker

What is the best way to do the error handling. The existing error handling does not provide the space for information.

I see you panic in the code. The signature of the functions allows passing an error in the second argument. What is your concern about using it?

I am having a hard time adding tests since the previous tests generate anything. Would it be ok if I define test cases with their own input?

Yes, sure. You can define your own test cases.

Thanks again for taking this initiative!

smacker avatar Oct 23 '22 10:10 smacker

I got more into test grammar and was able to find ways to write the tests with it after all.

PKuebler avatar Oct 24 '22 14:10 PKuebler

This is amazing work. Thank you @PKuebler so much!

smacker avatar Feb 23 '23 05:02 smacker