diff --git a/lib/binding_web/binding.c b/lib/binding_web/binding.c index d020da7c..8adaec75 100644 --- a/lib/binding_web/binding.c +++ b/lib/binding_web/binding.c @@ -622,8 +622,11 @@ void ts_query_matches_wasm( } } + bool did_exceed_match_limit = + ts_query_cursor_did_exceed_match_limit(scratch_query_cursor); TRANSFER_BUFFER[0] = (const void *)(match_count); TRANSFER_BUFFER[1] = result.contents; + TRANSFER_BUFFER[2] = (const void *)(did_exceed_match_limit); } void ts_query_captures_wasm( @@ -667,6 +670,9 @@ void ts_query_captures_wasm( } } + bool did_exceed_match_limit = + ts_query_cursor_did_exceed_match_limit(scratch_query_cursor); TRANSFER_BUFFER[0] = (const void *)(capture_count); TRANSFER_BUFFER[1] = result.contents; + TRANSFER_BUFFER[2] = (const void *)(did_exceed_match_limit); } diff --git a/lib/binding_web/binding.js b/lib/binding_web/binding.js index 62b147f1..490874ac 100644 --- a/lib/binding_web/binding.js +++ b/lib/binding_web/binding.js @@ -945,6 +945,7 @@ class Query { this.setProperties = setProperties; this.assertedProperties = assertedProperties; this.refutedProperties = refutedProperties; + this.exceededMatchLimit = false; } delete() { @@ -969,7 +970,9 @@ class Query { const rawCount = getValue(TRANSFER_BUFFER, 'i32'); const startAddress = getValue(TRANSFER_BUFFER + SIZE_OF_INT, 'i32'); + const didExceedMatchLimit = getValue(TRANSFER_BUFFER + 2 * SIZE_OF_INT, 'i32'); const result = new Array(rawCount); + this.exceededMatchLimit = !!didExceedMatchLimit; let filteredCount = 0; let address = startAddress; @@ -1014,7 +1017,9 @@ class Query { const count = getValue(TRANSFER_BUFFER, 'i32'); const startAddress = getValue(TRANSFER_BUFFER + SIZE_OF_INT, 'i32'); + const didExceedMatchLimit = getValue(TRANSFER_BUFFER + 2 * SIZE_OF_INT, 'i32'); const result = []; + this.exceededMatchLimit = !!didExceedMatchLimit; const captures = []; let address = startAddress; @@ -1048,6 +1053,10 @@ class Query { predicatesForPattern(patternIndex) { return this.predicates[patternIndex] } + + didExceedMatchLimit() { + return this.exceededMatchLimit; + } } function getText(tree, startIndex, endIndex) { diff --git a/lib/binding_web/test/query-test.js b/lib/binding_web/test/query-test.js index 77937a45..b7b2e053 100644 --- a/lib/binding_web/test/query-test.js +++ b/lib/binding_web/test/query-test.js @@ -238,6 +238,26 @@ describe("Query", () => { refutedProperties: { bar: "baz" }, }, ]); + assert.ok(!query.didExceedMatchLimit()); + }); + + it("detects queries with too many permutations to track", () => { + tree = parser.parse(` + [ + hello, hello, hello, hello, hello, hello, hello, hello, hello, hello, + hello, hello, hello, hello, hello, hello, hello, hello, hello, hello, + hello, hello, hello, hello, hello, hello, hello, hello, hello, hello, + hello, hello, hello, hello, hello, hello, hello, hello, hello, hello, + hello, hello, hello, hello, hello, hello, hello, hello, hello, hello, + ]; + `); + + query = JavaScript.query(` + (array (identifier) @pre (identifier) @post) + `); + + const captures = query.captures(tree.rootNode); + assert.ok(query.didExceedMatchLimit()); }); });