Skip to content

Commit 367418b

Browse files
committed
feat: improve type-checking
1 parent 6910a5f commit 367418b

File tree

10 files changed

+114
-34
lines changed

10 files changed

+114
-34
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
.cache
12
*.pyc
23
*.log
34
lib-cov

index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -581,7 +581,7 @@ Query.prototype._init = function() {
581581
if (steps[SECOND] !== PREDICATE_STEP_TYPE.CAPTURE) throw new Error(
582582
`First argument of \`#${operator}\` predicate must be a capture. Got "${steps[1].value}".`
583583
);
584-
stringValues = [];
584+
const stringValues = [];
585585
for (let k = THIRD; k < 2 * stepsLength; k += 2) {
586586
if (steps[k] !== PREDICATE_STEP_TYPE.STRING) throw new Error(
587587
`Arguments to \`#${operator}\` predicate must be a strings.".`

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
},
3535
"devDependencies": {
3636
"@types/node": "^22.7.8",
37+
"@types/tmp": "^0.2.6",
3738
"node-gyp": "^10.2.0",
3839
"prebuildify": "^6.0.1",
3940
"tmp": "^0.2.3",

test/lookahead_iterable_test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
const Parser = require("..");
1+
/** @type {typeof import('tree-sitter')} */
2+
const Parser = require("../index.js");
23
const Rust = require("tree-sitter-rust");
34
const assert = require('node:assert');
45
const { describe, it } = require('node:test');

test/node_test.js

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
const Parser = require("..");
1+
/** @type {typeof import('tree-sitter')} */
2+
const Parser = require("../index.js");
3+
24
const C = require('tree-sitter-c');
35
const EmbeddedTemplate = require('tree-sitter-embedded-template');
46
const JavaScript = require('tree-sitter-javascript');
@@ -18,6 +20,9 @@ const JSON_EXAMPLE = `
1820
]
1921
`
2022

23+
/**
24+
* @param {import('tree-sitter').Tree} tree
25+
*/
2126
function getAllNodes(tree) {
2227
const result = [];
2328
let visitedChildren = false;
@@ -38,10 +43,12 @@ function getAllNodes(tree) {
3843
}
3944

4045
describe("Node", () => {
46+
/** @type {import('tree-sitter')} */
4147
let parser;
4248

4349
beforeEach(() => {
44-
parser = new Parser().setLanguage(JavaScript);
50+
parser = new Parser();
51+
parser.setLanguage(JavaScript);
4552
});
4653

4754
describe("subclasses", () => {
@@ -57,8 +64,10 @@ describe("Node", () => {
5764
`);
5865

5966
const classNode = tree.rootNode.firstChild;
67+
// @ts-ignore
6068
assert.deepEqual(classNode.fields, ['bodyNode', 'decoratorNodes', 'nameNode'])
6169

70+
// @ts-ignore
6271
const methodNode = classNode.bodyNode.firstNamedChild;
6372
assert.equal(methodNode.constructor.name, 'MethodDefinitionNode');
6473
assert.equal(methodNode.nameNode.text, 'b');
@@ -455,10 +464,12 @@ describe("Node", () => {
455464
assert.equal("+", sumNode.descendantForIndex(4, 4).type);
456465

457466
assert.throws(() => {
467+
// @ts-ignore
458468
sumNode.descendantForIndex(1, {});
459469
}, /Character index must be a number/);
460470

461471
assert.throws(() => {
472+
// @ts-ignore
462473
sumNode.descendantForIndex();
463474
}, /Character index must be a number/);
464475
});
@@ -492,10 +503,12 @@ describe("Node", () => {
492503
);
493504

494505
assert.throws(() => {
506+
// @ts-ignore
495507
sumNode.descendantForPosition(1, {});
496508
}, /Point must be a {row, column} object/);
497509

498510
assert.throws(() => {
511+
// @ts-ignore
499512
sumNode.descendantForPosition();
500513
}, /Point must be a {row, column} object/);
501514
});
@@ -594,6 +607,7 @@ describe("Node", () => {
594607
const tree = parser.parse("a + 1 * b * 2 + c + 3");
595608
const number = tree.rootNode.descendantForIndex(4)
596609

610+
// @ts-ignore
597611
assert.throws(() => number.closest({ a: 1 }), /Argument must be a string or array of strings/)
598612
});
599613
});

test/parser_test.js

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
const Parser = require("..");
1+
/** @type {typeof import('tree-sitter')} */
2+
const Parser = require("../index.js");
23
const HTML = require('tree-sitter-html');
34
const JavaScript = require('tree-sitter-javascript');
45
const JSON = require('tree-sitter-json');
@@ -7,6 +8,7 @@ const assert = require('node:assert');
78
const { afterEach, beforeEach, describe, it } = require('node:test');
89

910
describe("Parser", () => {
11+
/** @type {import('tree-sitter')} */
1012
let parser;
1113

1214
beforeEach(() => {
@@ -61,6 +63,7 @@ describe("Parser", () => {
6163
describe("when given a truthy value that isn't a function", () => {
6264
it("raises an exception", () => {
6365
assert.throws(
66+
// @ts-ignore
6467
() => parser.setLogger("5"),
6568
/Logger callback must .* function .* falsy/
6669
);
@@ -75,6 +78,10 @@ describe("Parser", () => {
7578
thrownError = new Error("dang.");
7679

7780
originalConsoleError = console.error;
81+
/**
82+
* @param {string} message
83+
* @param {Error} error
84+
*/
7885
console.error = (message, error) => {
7986
errorMessages.push([message, error]);
8087
};
@@ -109,6 +116,7 @@ describe("Parser", () => {
109116
return;
110117
}
111118

119+
/** @param {string} s */
112120
const hasZeroIndexedRow = s => s.indexOf("position: 0,") !== -1;
113121

114122
const tmp = require("tmp");
@@ -171,8 +179,11 @@ describe("Parser", () => {
171179

172180
describe("when the given input is not a function", () => {
173181
it("throws an exception", () => {
182+
// @ts-ignore
174183
assert.throws(() => parser.parse(null), /Input.*function/);
184+
// @ts-ignore
175185
assert.throws(() => parser.parse(5), /Input.*function/);
186+
// @ts-ignore
176187
assert.throws(() => parser.parse({}), /Input.*function/);
177188
});
178189
});
@@ -600,6 +611,10 @@ describe("Parser", () => {
600611
});
601612

602613
describe('parsing with a newly included range', () => {
614+
/**
615+
* @param {number} startIndex
616+
* @param {number} endIndex
617+
*/
603618
function simpleRange(startIndex, endIndex) {
604619
return {
605620
startIndex,

test/query_test.js

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
1-
const fs = require("fs");
2-
const Parser = require("..");
1+
/** @type {typeof import('tree-sitter')} */
2+
const Parser = require("../index.js");
3+
34
const C = require("tree-sitter-c");
45
const Java = require("tree-sitter-java");
56
const JavaScript = require("tree-sitter-javascript");
67
const JSON = require("tree-sitter-json");
78
const Python = require("tree-sitter-python");
89
const Ruby = require("tree-sitter-ruby");
9-
const Rust = require("tree-sitter-rust");
1010
const assert = require('node:assert');
1111
const { describe, it } = require('node:test');
12-
const { Query, QueryCursor } = Parser
12+
const { Query } = Parser
1313

1414
describe("Query", () => {
1515

@@ -279,6 +279,11 @@ describe("Query", () => {
279279
)
280280
`);
281281

282+
/**
283+
* @param {import('tree-sitter').Tree} tree
284+
* @param {string} queryText
285+
* @param {number} expectedCount
286+
*/
282287
let expectCount = (tree, queryText, expectedCount) => {
283288
query = new Query(JavaScript, queryText);
284289
captures = query.captures(tree.rootNode);
@@ -513,6 +518,7 @@ describe("Query", () => {
513518

514519
describe(".isPatternGuaranteedAtStep", () => {
515520
it("returns true if the given pattern is guaranteed to match at the given step", () => {
521+
/** @type {Array<{description: string, language: any, pattern: string, resultsBySubstring: Array<[string, boolean]>}>} */
516522
const rows = [
517523
{
518524
description: "no guaranteed steps",
@@ -874,6 +880,7 @@ describe("Query", () => {
874880

875881
describe(".isPatternNonLocal", () => {
876882
it("returns true if the given pattern has a single root node", () => {
883+
/** @type {Array<{ description: string, pattern: string, language: any, isNonLocal: boolean }>} */
877884
const rows = [
878885
{
879886
description: "simple token",
@@ -961,6 +968,7 @@ if (d) {
961968
}
962969
`;
963970

971+
/** @type {Array<{ description: string, depth: number, pattern: string, matches: Array<[number, Array<[string, string]>]> }>} */
964972
const rows = [
965973
{
966974
description: "depth 0: match translation unit",
@@ -1046,6 +1054,7 @@ if (d) {
10461054
}
10471055
}
10481056
`
1057+
/** @type {Array<{ depth: number, matches: Array<[number, Array<[string, string]>]> }>} */
10491058
const rows = [
10501059
{
10511060
depth: 0,
@@ -1071,7 +1080,6 @@ if (d) {
10711080
]
10721081
},
10731082
];
1074-
10751083
parser.setLanguage(C);
10761084
const tree = parser.parse(source);
10771085
const query = new Query(C, "(compound_statement) @capture");
@@ -1091,13 +1099,21 @@ if (d) {
10911099
});
10921100
});
10931101

1102+
/**
1103+
* @param {import('tree-sitter').Tree} tree
1104+
* @param {import('tree-sitter').QueryMatch[]} matches
1105+
*/
10941106
function formatMatches(tree, matches) {
10951107
return matches.map(({ pattern, captures }) => ({
10961108
pattern,
10971109
captures: formatCaptures(tree, captures),
10981110
}));
10991111
}
11001112

1113+
/**
1114+
* @param {import('tree-sitter').Tree} tree
1115+
* @param {(import('tree-sitter').QueryCapture & { text?: string })[]} captures
1116+
*/
11011117
function formatCaptures(tree, captures) {
11021118
return captures.map((c) => {
11031119
const node = c.node;

test/tree_test.js

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1-
const Parser = require("..");
1+
/** @type {typeof import('tree-sitter')} */
2+
const Parser = require("../index.js");
23
const JavaScript = require('tree-sitter-javascript');
34
const Rust = require('tree-sitter-rust');
45
const assert = require('node:assert');
56
const { beforeEach, describe, it } = require('node:test');
67

78
describe("Tree", () => {
9+
/** @type {import('tree-sitter')} */
810
let parser;
911

1012
beforeEach(() => {
@@ -13,7 +15,14 @@ describe("Tree", () => {
1315
});
1416

1517
describe('.edit', () => {
16-
let input, edit
18+
/** @type {string} */
19+
let input;
20+
21+
/** @type {import('tree-sitter').Edit} */
22+
let edit;
23+
24+
/** @type {import('tree-sitter').Tree} */
25+
let tree;
1726

1827
it('updates the positions of existing nodes', () => {
1928
input = 'abc + cde';
@@ -32,7 +41,7 @@ describe("Tree", () => {
3241
assert.equal(variableNode2.startIndex, 6);
3342
assert.equal(variableNode2.endIndex, 9);
3443

35-
([input, edit] = spliceInput(input, input.indexOf('bc'), 0, ' * '));
44+
[input, edit] = spliceInput(input, input.indexOf('bc'), 0, ' * ');
3645
assert.equal(input, 'a * bc + cde');
3746

3847
tree.edit(edit);
@@ -59,7 +68,7 @@ describe("Tree", () => {
5968

6069
const variableNode = tree.rootNode.firstChild.firstChild.lastChild;
6170

62-
([input, edit] = spliceInput(input, input.indexOf('δ'), 0, '👍 * '));
71+
[input, edit] = spliceInput(input, input.indexOf('δ'), 0, '👍 * ');
6372
assert.equal(input, 'αβ👍 * δ + cde');
6473

6574
tree.edit(edit);
@@ -78,6 +87,7 @@ describe("Tree", () => {
7887
const inputString = 'abc + def + ghi + jkl + mno';
7988
const tree = parser.parse(inputString);
8089

90+
// @ts-ignore
8191
assert.equal(tree.getEditedRange(), null)
8292

8393
tree.edit({
@@ -98,6 +108,7 @@ describe("Tree", () => {
98108
newEndPosition: { row: 0, column: 22 }
99109
});
100110

111+
// @ts-ignore
101112
assert.deepEqual(tree.getEditedRange(), {
102113
startIndex: 6,
103114
endIndex: 23,
@@ -148,6 +159,7 @@ describe("Tree", () => {
148159
const tree1 = parser.parse("abcdefg + hij");
149160

150161
assert.throws(() => {
162+
// @ts-ignore
151163
tree1.getChangedRanges({});
152164
}, /Argument must be a tree/);
153165
})
@@ -157,22 +169,6 @@ describe("Tree", () => {
157169
it("returns a cursor that can be used to walk the tree", () => {
158170
parser.setLanguage(Rust);
159171

160-
// let mut parser = Parser::new();
161-
// parser.set_language(&get_language("rust")).unwrap();
162-
//
163-
// let tree = parser
164-
// .parse(
165-
// "
166-
// struct Stuff {
167-
// a: A,
168-
// b: Option<B>,
169-
// }
170-
// ",
171-
// None,
172-
// )
173-
// .unwrap();
174-
//
175-
176172
const tree = parser.parse(`
177173
struct Stuff {
178174
a: A,
@@ -589,6 +585,10 @@ describe("Tree", () => {
589585
});
590586
});
591587

588+
/**
589+
* @param {import('tree-sitter').TreeCursor} cursor
590+
* @param {Object} params
591+
*/
592592
function assertCursorState(cursor, params) {
593593
assert.strictEqual(typeof cursor.nodeIsNamed, 'boolean');
594594
assert.strictEqual(typeof cursor.nodeIsMissing, 'boolean');
@@ -611,6 +611,14 @@ function assertCursorState(cursor, params) {
611611
assert.deepEqual(node.endIndex, params.endIndex);
612612
}
613613

614+
/**
615+
* @param {string} input
616+
* @param {number} startIndex
617+
* @param {number} lengthRemoved
618+
* @param {string} newText
619+
*
620+
* @returns {[string, import('tree-sitter').Edit]}
621+
*/
614622
function spliceInput(input, startIndex, lengthRemoved, newText) {
615623
const oldEndIndex = startIndex + lengthRemoved;
616624
const newEndIndex = startIndex + newText.length;
@@ -628,6 +636,9 @@ function spliceInput(input, startIndex, lengthRemoved, newText) {
628636
];
629637
}
630638

639+
/**
640+
* @param {string} text
641+
*/
631642
function getExtent(text) {
632643
let row = 0
633644
let index;

0 commit comments

Comments
 (0)