diff --git a/lib/binding_web/binding.c b/lib/binding_web/binding.c
index 9db2bc5f..845314b2 100644
--- a/lib/binding_web/binding.c
+++ b/lib/binding_web/binding.c
@@ -184,6 +184,18 @@ TSTree *ts_parser_parse_wasm(
return ts_parser_parse(self, old_tree, input);
}
+void ts_parser_included_ranges_wasm(TSParser *self) {
+ uint32_t range_count = 0;
+ const TSRange *ranges = ts_parser_included_ranges(self, &range_count);
+ TSRange *copied_ranges = malloc(sizeof(TSRange) * range_count);
+ memcpy(copied_ranges, ranges, sizeof(TSRange) * range_count);
+ for (unsigned i = 0; i < range_count; i++) {
+ marshal_range(&copied_ranges[i]);
+ }
+ TRANSFER_BUFFER[0] = range_count ? (const void *)range_count : NULL;
+ TRANSFER_BUFFER[1] = copied_ranges;
+}
+
/**********************/
/* Section - Language */
/**********************/
diff --git a/lib/binding_web/binding.js b/lib/binding_web/binding.js
index c870f33d..fafc885c 100644
--- a/lib/binding_web/binding.js
+++ b/lib/binding_web/binding.js
@@ -1,3 +1,8 @@
+/* eslint-disable-next-line spaced-comment */
+///
+/* eslint-disable-next-line spaced-comment */
+///
+
const C = Module;
const INTERNAL = {};
const SIZE_OF_INT = 4;
@@ -121,17 +126,19 @@ class ParserImpl {
}
getIncludedRanges() {
- const count = C._malloc(SIZE_OF_INT);
- const rangeAddress = C._ts_parser_included_ranges(this[0], count);
- count = getValue(count, 'i32');
+ C._ts_parser_included_ranges_wasm(this[0]);
+ const count = getValue(TRANSFER_BUFFER, 'i32');
+ const buffer = getValue(TRANSFER_BUFFER + SIZE_OF_INT, 'i32');
const result = new Array(count);
if (count > 0) {
- let address = rangeAddress;
+ let address = buffer;
for (let i = 0; i < count; i++) {
result[i] = unmarshalRange(address);
address += SIZE_OF_RANGE;
}
+ C._free(buffer);
}
+ return result;
}
getTimeoutMicros() {
@@ -1500,10 +1507,11 @@ function marshalPoint(address, point) {
}
function unmarshalPoint(address) {
- return {
- row: getValue(address, 'i32'),
- column: getValue(address + SIZE_OF_INT, 'i32'),
+ const result = {
+ row: getValue(address, 'i32') >>> 0,
+ column: getValue(address + SIZE_OF_INT, 'i32') >>> 0,
};
+ return result;
}
function marshalRange(address, range) {
@@ -1517,8 +1525,8 @@ function unmarshalRange(address) {
const result = {};
result.startPosition = unmarshalPoint(address); address += SIZE_OF_POINT;
result.endPosition = unmarshalPoint(address); address += SIZE_OF_POINT;
- result.startIndex = getValue(address, 'i32'); address += SIZE_OF_INT;
- result.endIndex = getValue(address, 'i32');
+ result.startIndex = getValue(address, 'i32') >>> 0; address += SIZE_OF_INT;
+ result.endIndex = getValue(address, 'i32') >>> 0;
return result;
}
diff --git a/lib/binding_web/exports.txt b/lib/binding_web/exports.txt
index 68bbd47e..7507c51f 100644
--- a/lib/binding_web/exports.txt
+++ b/lib/binding_web/exports.txt
@@ -53,6 +53,8 @@
"ts_parser_parse_wasm",
"ts_parser_reset",
"ts_parser_set_language",
+"ts_parser_set_included_ranges",
+"ts_parser_included_ranges_wasm",
"ts_parser_set_timeout_micros",
"ts_parser_timeout_micros",
"ts_query_capture_count",
diff --git a/lib/binding_web/package.json b/lib/binding_web/package.json
index 62a1022c..0b2dfbc4 100644
--- a/lib/binding_web/package.json
+++ b/lib/binding_web/package.json
@@ -27,6 +27,7 @@
},
"homepage": "https://github.com/tree-sitter/tree-sitter/tree/master/lib/binding_web",
"devDependencies": {
+ "@types/emscripten": "^1.39.10",
"chai": "^4.3.7",
"eslint": ">=8.56.0",
"eslint-config-google": "^0.14.0",
diff --git a/lib/binding_web/test/parser-test.js b/lib/binding_web/test/parser-test.js
index 3af59e11..cf087599 100644
--- a/lib/binding_web/test/parser-test.js
+++ b/lib/binding_web/test/parser-test.js
@@ -83,6 +83,44 @@ describe('Parser', () => {
});
});
+ describe('one included range', () => {
+ it('parses the text within a range', () => {
+ parser.setLanguage(HTML);
+ const sourceCode = 'hi';
+ const htmlTree = parser.parse(sourceCode);
+ const scriptContentNode = htmlTree.rootNode.child(1).child(1);
+ assert.equal(scriptContentNode.type, 'raw_text');
+
+ parser.setLanguage(JavaScript);
+ assert.deepEqual(parser.getIncludedRanges(), [{
+ startIndex: 0,
+ endIndex: 2147483647,
+ startPosition: {row: 0, column: 0},
+ endPosition: {row: 4294967295, column: 2147483647},
+ }]);
+ const ranges = [{
+ startIndex: scriptContentNode.startIndex,
+ endIndex: scriptContentNode.endIndex,
+ startPosition: scriptContentNode.startPosition,
+ endPosition: scriptContentNode.endPosition,
+ }];
+ const jsTree = parser.parse(
+ sourceCode,
+ null,
+ {includedRanges: ranges},
+ );
+ assert.deepEqual(parser.getIncludedRanges(), ranges);
+
+ assert.equal(
+ jsTree.rootNode.toString(),
+ '(program (expression_statement (call_expression ' +
+ 'function: (member_expression object: (identifier) property: (property_identifier)) ' +
+ 'arguments: (arguments (string (string_fragment))))))',
+ );
+ assert.deepEqual(jsTree.rootNode.startPosition, {row: 0, column: sourceCode.indexOf('console')});
+ });
+ });
+
describe('multiple included ranges', () => {
it('parses the text within multiple ranges', () => {
parser.setLanguage(JavaScript);
diff --git a/lib/binding_web/tree-sitter-web.d.ts b/lib/binding_web/tree-sitter-web.d.ts
index 6bf1af20..dc984bf1 100644
--- a/lib/binding_web/tree-sitter-web.d.ts
+++ b/lib/binding_web/tree-sitter-web.d.ts
@@ -150,7 +150,7 @@ declare module 'web-tree-sitter' {
rootNodeWithOffset(offsetBytes: number, offsetExtent: Point): SyntaxNode;
copy(): Tree;
delete(): void;
- edit(delta: Edit): Tree;
+ edit(edit: Edit): Tree;
walk(): TreeCursor;
getChangedRanges(other: Tree): Range[];
getIncludedRanges(): Range[];