From 4303ab99c984e25d9022a069fef250bdb42930ee Mon Sep 17 00:00:00 2001 From: Amaan Qureshi Date: Tue, 13 Feb 2024 15:37:35 -0500 Subject: [PATCH] fix: properly handle Query.matches when filtering out results --- cli/src/tests/query_test.rs | 20 ++++++++++++++++++++ lib/binding_web/binding.js | 9 +++++---- lib/binding_web/test/query-test.js | 17 +++++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/cli/src/tests/query_test.rs b/cli/src/tests/query_test.rs index 17b262ff..74cf464e 100644 --- a/cli/src/tests/query_test.rs +++ b/cli/src/tests/query_test.rs @@ -3020,6 +3020,26 @@ fn test_query_captures_with_predicates() { (QueryProperty::new("name", Some("something"), None), false), ] ); + + let source = "const a = window.b"; + let mut parser = Parser::new(); + parser.set_language(&language).unwrap(); + let tree = parser.parse(source, None).unwrap(); + + let query = Query::new( + &language, + r#"((identifier) @variable.builtin + (#match? @variable.builtin "^(arguments|module|console|window|document)$") + (#is-not? local)) + "#, + ) + .unwrap(); + + let mut cursor = QueryCursor::new(); + let matches = cursor.matches(&query, tree.root_node(), source.as_bytes()); + let matches = collect_matches(matches, &query, source); + + assert_eq!(matches, &[(0, vec![("variable.builtin", "window")])]); }); } diff --git a/lib/binding_web/binding.js b/lib/binding_web/binding.js index 817cc48d..ce98f1b2 100644 --- a/lib/binding_web/binding.js +++ b/lib/binding_web/binding.js @@ -1182,13 +1182,14 @@ class Query { const captures = new Array(captureCount); address = unmarshalCaptures(this, node.tree, address, captures); if (this.textPredicates[pattern].every((p) => p(captures))) { - result[filteredCount++] = {pattern, captures}; + result[filteredCount] = {pattern, captures}; const setProperties = this.setProperties[pattern]; - if (setProperties) result[i].setProperties = setProperties; + if (setProperties) result[filteredCount].setProperties = setProperties; const assertedProperties = this.assertedProperties[pattern]; - if (assertedProperties) result[i].assertedProperties = assertedProperties; + if (assertedProperties) result[filteredCount].assertedProperties = assertedProperties; const refutedProperties = this.refutedProperties[pattern]; - if (refutedProperties) result[i].refutedProperties = refutedProperties; + if (refutedProperties) result[filteredCount].refutedProperties = refutedProperties; + filteredCount++; } } result.length = filteredCount; diff --git a/lib/binding_web/test/query-test.js b/lib/binding_web/test/query-test.js index ec9882f1..73c7d34f 100644 --- a/lib/binding_web/test/query-test.js +++ b/lib/binding_web/test/query-test.js @@ -107,6 +107,23 @@ describe('Query', () => { {pattern: 0, captures: [{name: 'name', text: 'gross'}]}, ]); }); + + it('handles multiple matches where the first one is filtered', () => { + tree = parser.parse(` + const a = window.b; + `); + + query = JavaScript.query(` + ((identifier) @variable.builtin + (#match? @variable.builtin "^(arguments|module|console|window|document)$") + (#is-not? local)) + `); + + const matches = query.matches(tree.rootNode); + assert.deepEqual(formatMatches(matches), [ + {pattern: 0, captures: [{name: 'variable.builtin', text: 'window'}]}, + ]); + }); }); describe('.captures', () => {