feat(web): add missing API functions
Co-authored-by: Will Lillis <will.lillis24@gmail.com>
This commit is contained in:
parent
dcdd6ce2d2
commit
45fa028201
11 changed files with 436 additions and 35 deletions
|
|
@ -7,6 +7,7 @@ function languageURL(name) {
|
|||
module.exports = Parser.init().then(async () => ({
|
||||
Parser,
|
||||
languageURL,
|
||||
C: await Parser.Language.load(languageURL('c')),
|
||||
EmbeddedTemplate: await Parser.Language.load(languageURL('embedded-template')),
|
||||
HTML: await Parser.Language.load(languageURL('html')),
|
||||
JavaScript: await Parser.Language.load(languageURL('javascript')),
|
||||
|
|
|
|||
|
|
@ -4,6 +4,13 @@ let JavaScript;
|
|||
describe('Language', () => {
|
||||
before(async () => ({JavaScript, Rust} = await require('./helper')));
|
||||
|
||||
describe('.name, .version', () => {
|
||||
it('returns the name and version of the language', () => {
|
||||
assert.equal('javascript', JavaScript.name);
|
||||
assert.equal(15, JavaScript.version);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.fieldIdForName, .fieldNameForId', () => {
|
||||
it('converts between the string and integer representations of fields', () => {
|
||||
const nameId = JavaScript.fieldIdForName('name');
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
const {assert} = require('chai');
|
||||
let Parser; let JavaScript; let JSON; let EmbeddedTemplate; let Python;
|
||||
let Parser; let C; let JavaScript; let JSON; let EmbeddedTemplate; let Python;
|
||||
|
||||
const JSON_EXAMPLE = `
|
||||
|
||||
|
|
@ -35,7 +35,7 @@ describe('Node', () => {
|
|||
let parser; let tree;
|
||||
|
||||
before(async () =>
|
||||
({Parser, EmbeddedTemplate, JavaScript, JSON, Python} = await require('./helper')),
|
||||
({Parser, C, EmbeddedTemplate, JavaScript, JSON, Python} = await require('./helper')),
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
@ -620,17 +620,57 @@ describe('Node', () => {
|
|||
|
||||
describe('.fieldNameForChild(index)', () => {
|
||||
it('returns the field of a child or null', () => {
|
||||
tree = parser.parse('let a = 5');
|
||||
parser.setLanguage(C);
|
||||
tree = parser.parse('int w = x + /* y is special! */ y;');
|
||||
|
||||
const noField = tree.rootNode.fieldNameForChild(0);
|
||||
const name = tree.rootNode.firstChild.children[1].fieldNameForChild(0);
|
||||
const value = tree.rootNode.firstChild.children[1].fieldNameForChild(2);
|
||||
const overflow = tree.rootNode.firstChild.children[1].fieldNameForChild(3);
|
||||
const translationUnitNode = tree.rootNode;
|
||||
const declarationNode = translationUnitNode.firstChild;
|
||||
const binaryExpressionNode = declarationNode
|
||||
.childForFieldName('declarator')
|
||||
.childForFieldName('value');
|
||||
|
||||
assert.equal(noField, null);
|
||||
assert.equal(name, 'name');
|
||||
assert.equal(value, 'value');
|
||||
assert.equal(overflow, null);
|
||||
// -------------------
|
||||
// left: (identifier) 0
|
||||
// operator: "+" _ <--- (not a named child)
|
||||
// (comment) 1 <--- (is an extra)
|
||||
// right: (identifier) 2
|
||||
// -------------------
|
||||
|
||||
assert.equal(binaryExpressionNode.fieldNameForChild(0), 'left');
|
||||
assert.equal(binaryExpressionNode.fieldNameForChild(1), 'operator');
|
||||
// The comment should not have a field name, as it's just an extra
|
||||
assert.equal(binaryExpressionNode.fieldNameForChild(2), null);
|
||||
assert.equal(binaryExpressionNode.fieldNameForChild(3), 'right');
|
||||
// Negative test - Not a valid child index
|
||||
assert.equal(binaryExpressionNode.fieldNameForChild(4), null);
|
||||
});
|
||||
});
|
||||
|
||||
describe('.fieldNameForNamedChild(index)', () => {
|
||||
it('returns the field of a named child or null', () => {
|
||||
parser.setLanguage(C);
|
||||
tree = parser.parse('int w = x + /* y is special! */ y;');
|
||||
|
||||
const translationUnitNode = tree.rootNode;
|
||||
const declarationNode = translationUnitNode.firstNamedChild;
|
||||
const binaryExpressionNode = declarationNode
|
||||
.childForFieldName('declarator')
|
||||
.childForFieldName('value');
|
||||
|
||||
// -------------------
|
||||
// left: (identifier) 0
|
||||
// operator: "+" _ <--- (not a named child)
|
||||
// (comment) 1 <--- (is an extra)
|
||||
// right: (identifier) 2
|
||||
// -------------------
|
||||
|
||||
assert.equal(binaryExpressionNode.fieldNameForNamedChild(0), 'left');
|
||||
// The comment should not have a field name, as it's just an extra
|
||||
assert.equal(binaryExpressionNode.fieldNameForNamedChild(1), null);
|
||||
// The operator is not a named child, so the named child at index 2 is the right child
|
||||
assert.equal(binaryExpressionNode.fieldNameForNamedChild(2), 'right');
|
||||
// Negative test - Not a valid child index
|
||||
assert.equal(binaryExpressionNode.fieldNameForNamedChild(3), null);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,11 +1,11 @@
|
|||
const {assert} = require('chai');
|
||||
let Parser; let JavaScript; let HTML; let languageURL;
|
||||
let Parser; let JavaScript; let HTML; let languageURL; let JSON;
|
||||
|
||||
describe('Parser', () => {
|
||||
let parser;
|
||||
|
||||
before(async () =>
|
||||
({Parser, JavaScript, HTML, languageURL} = await require('./helper')),
|
||||
({Parser, JavaScript, HTML, JSON, languageURL} = await require('./helper')),
|
||||
);
|
||||
|
||||
beforeEach(() => {
|
||||
|
|
@ -388,5 +388,26 @@ describe('Parser', () => {
|
|||
'(program (expression_statement (call_expression function: (identifier) arguments: (arguments))) (expression_statement (identifier)))',
|
||||
);
|
||||
});
|
||||
|
||||
it('parses with a timeout', () => {
|
||||
parser.setLanguage(JSON);
|
||||
|
||||
const startTime = performance.now();
|
||||
assert.throws(() => {
|
||||
parser.parse(
|
||||
(offset, _) => offset === 0 ? '[' : ',0',
|
||||
null,
|
||||
{
|
||||
progressCallback: (_) => {
|
||||
if (performance.now() - startTime > 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},
|
||||
);
|
||||
},
|
||||
);
|
||||
}).timeout(5000);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -455,13 +455,112 @@ describe('Query', () => {
|
|||
describe('Set a timeout', () =>
|
||||
it('returns less than the expected matches', () => {
|
||||
tree = parser.parse('function foo() while (true) { } }\n'.repeat(1000));
|
||||
query = JavaScript.query('(function_declaration name: (identifier) @function)');
|
||||
const matches = query.matches(tree.rootNode, { timeoutMicros: 1000 });
|
||||
query = JavaScript.query(
|
||||
'(function_declaration name: (identifier) @function)',
|
||||
);
|
||||
const matches = query.matches(tree.rootNode, {timeoutMicros: 1000});
|
||||
assert.isBelow(matches.length, 1000);
|
||||
const matches2 = query.matches(tree.rootNode, { timeoutMicros: 0 });
|
||||
const matches2 = query.matches(tree.rootNode, {timeoutMicros: 0});
|
||||
assert.equal(matches2.length, 1000);
|
||||
})
|
||||
);
|
||||
}));
|
||||
|
||||
describe('Start and end indices for patterns', () => {
|
||||
it('Returns the start and end indices for a pattern', () => {
|
||||
const patterns1 = `
|
||||
"+" @operator
|
||||
"-" @operator
|
||||
"*" @operator
|
||||
"=" @operator
|
||||
"=>" @operator
|
||||
`.trim();
|
||||
|
||||
const patterns2 = `
|
||||
(identifier) @a
|
||||
(string) @b
|
||||
`.trim();
|
||||
|
||||
const patterns3 = `
|
||||
((identifier) @b (#match? @b i))
|
||||
(function_declaration name: (identifier) @c)
|
||||
(method_definition name: (property_identifier) @d)
|
||||
`.trim();
|
||||
|
||||
const source = patterns1 + patterns2 + patterns3;
|
||||
|
||||
const query = JavaScript.query(source);
|
||||
|
||||
assert.equal(query.startIndexForPattern(0), 0);
|
||||
assert.equal(query.endIndexForPattern(0), '"+" @operator\n'.length);
|
||||
assert.equal(query.startIndexForPattern(5), patterns1.length);
|
||||
assert.equal(
|
||||
query.endIndexForPattern(5),
|
||||
patterns1.length + '(identifier) @a\n'.length,
|
||||
);
|
||||
assert.equal(
|
||||
query.startIndexForPattern(7),
|
||||
patterns1.length + patterns2.length,
|
||||
);
|
||||
assert.equal(
|
||||
query.endIndexForPattern(7),
|
||||
patterns1.length +
|
||||
patterns2.length +
|
||||
'((identifier) @b (#match? @b i))\n'.length,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Disable pattern', () => {
|
||||
it('Disables patterns in the query', () => {
|
||||
const query = JavaScript.query(`
|
||||
(function_declaration name: (identifier) @name)
|
||||
(function_declaration body: (statement_block) @body)
|
||||
(class_declaration name: (identifier) @name)
|
||||
(class_declaration body: (class_body) @body)
|
||||
`);
|
||||
|
||||
// disable the patterns that match names
|
||||
query.disablePattern(0);
|
||||
query.disablePattern(2);
|
||||
|
||||
const source = 'class A { constructor() {} } function b() { return 1; }';
|
||||
tree = parser.parse(source);
|
||||
const matches = query.matches(tree.rootNode);
|
||||
assert.deepEqual(formatMatches(matches), [
|
||||
{
|
||||
pattern: 3,
|
||||
captures: [{name: 'body', text: '{ constructor() {} }'}],
|
||||
},
|
||||
{pattern: 1, captures: [{name: 'body', text: '{ return 1; }'}]},
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('Executes with a timeout', () => {
|
||||
it('Returns less than the expected matches', () => {
|
||||
tree = parser.parse('function foo() while (true) { } }\n'.repeat(1000));
|
||||
query = JavaScript.query(
|
||||
'(function_declaration) @function',
|
||||
);
|
||||
|
||||
const startTime = performance.now();
|
||||
|
||||
const matches = query.matches(
|
||||
tree.rootNode,
|
||||
{
|
||||
progressCallback: (_) => {
|
||||
if (performance.now() - startTime > 1) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
},
|
||||
);
|
||||
assert.isBelow(matches.length, 1000);
|
||||
|
||||
const matches2 = query.matches(tree.rootNode);
|
||||
assert.equal(matches2.length, 1000);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function formatMatches(matches) {
|
||||
|
|
|
|||
|
|
@ -363,7 +363,7 @@ describe('Tree', () => {
|
|||
);
|
||||
|
||||
const tree2 = tree.copy();
|
||||
([input, edit] = spliceInput(input, 3, 0, '123'));
|
||||
[input, edit] = spliceInput(input, 3, 0, '123');
|
||||
assert.equal(input, 'abc123 + cde');
|
||||
tree.edit(edit);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue