mirror of
https://github.com/duhanbalci/dexpr.git
synced 2026-07-02 08:29:16 +00:00
initial commit
This commit is contained in:
184
editor/node_modules/@lezer/generator/dist/test.js
generated
vendored
Normal file
184
editor/node_modules/@lezer/generator/dist/test.js
generated
vendored
Normal file
@@ -0,0 +1,184 @@
|
||||
import { NodeProp } from '@lezer/common';
|
||||
|
||||
const none = [];
|
||||
class TestSpec {
|
||||
constructor(name, props, children = none, wildcard = false) {
|
||||
this.name = name;
|
||||
this.props = props;
|
||||
this.children = children;
|
||||
this.wildcard = wildcard;
|
||||
}
|
||||
static parse(spec) {
|
||||
let pos = 0, tok = "sof", value = "";
|
||||
function err() {
|
||||
throw new SyntaxError("Invalid test spec: " + spec);
|
||||
}
|
||||
function next() {
|
||||
while (pos < spec.length && /\s/.test(spec.charAt(pos)))
|
||||
pos++;
|
||||
if (pos == spec.length)
|
||||
return tok = "eof";
|
||||
let next = spec.charAt(pos++);
|
||||
if (next == "(" && spec.slice(pos, pos + 4) == "...)") {
|
||||
pos += 4;
|
||||
return tok = "...";
|
||||
}
|
||||
if (/[\[\](),=]/.test(next))
|
||||
return tok = next;
|
||||
if (/[^()\[\],="\s]/.test(next)) {
|
||||
let name = /[^()\[\],="\s]*/.exec(spec.slice(pos - 1));
|
||||
value = name[0];
|
||||
pos += name[0].length - 1;
|
||||
return tok = "name";
|
||||
}
|
||||
if (next == '"') {
|
||||
let content = /^"((?:[^\\"]|\\.)*)"/.exec(spec.slice(pos - 1)) || err();
|
||||
value = JSON.parse(content[0]);
|
||||
pos += content[0].length - 1;
|
||||
return tok = "name";
|
||||
}
|
||||
return err();
|
||||
}
|
||||
next();
|
||||
function parseSeq() {
|
||||
let seq = [];
|
||||
while (tok != "eof" && tok != ")") {
|
||||
seq.push(parse());
|
||||
if (tok == ",")
|
||||
next();
|
||||
}
|
||||
return seq;
|
||||
}
|
||||
function parse() {
|
||||
let name = value, children = none, props = [], wildcard = false;
|
||||
if (tok != "name")
|
||||
err();
|
||||
next();
|
||||
if (tok == "[") {
|
||||
next();
|
||||
while (tok != "]") {
|
||||
if (tok != "name")
|
||||
err();
|
||||
let prop = NodeProp[value], val = "";
|
||||
if (!(prop instanceof NodeProp))
|
||||
err();
|
||||
next();
|
||||
if (tok == "=") {
|
||||
next();
|
||||
if (tok != "name")
|
||||
err();
|
||||
val = value;
|
||||
next();
|
||||
}
|
||||
props.push({ prop, value: prop.deserialize(val) });
|
||||
}
|
||||
next();
|
||||
}
|
||||
if (tok == "(") {
|
||||
next();
|
||||
children = parseSeq();
|
||||
// @ts-ignore TypeScript doesn't understand that `next` may have mutated `tok` (#9998)
|
||||
if (tok != ")")
|
||||
err();
|
||||
next();
|
||||
}
|
||||
else if (tok == "...") {
|
||||
wildcard = true;
|
||||
next();
|
||||
}
|
||||
return new TestSpec(name, props, children, wildcard);
|
||||
}
|
||||
let result = parseSeq();
|
||||
if (tok != "eof")
|
||||
err();
|
||||
return result;
|
||||
}
|
||||
matches(type) {
|
||||
if (type.name != this.name)
|
||||
return false;
|
||||
for (let { prop, value } of this.props)
|
||||
if ((value || type.prop(prop)) && JSON.stringify(type.prop(prop)) != JSON.stringify(value))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
function defaultIgnore(type) { return /\W/.test(type.name); }
|
||||
function testTree(tree, expect, mayIgnore = defaultIgnore) {
|
||||
let specs = TestSpec.parse(expect);
|
||||
let stack = [specs], pos = [0];
|
||||
tree.iterate({
|
||||
enter(n) {
|
||||
if (!n.name)
|
||||
return;
|
||||
let last = stack.length - 1, index = pos[last], seq = stack[last];
|
||||
let next = index < seq.length ? seq[index] : null;
|
||||
if (next && next.matches(n.type)) {
|
||||
if (next.wildcard) {
|
||||
pos[last]++;
|
||||
return false;
|
||||
}
|
||||
pos.push(0);
|
||||
stack.push(next.children);
|
||||
return undefined;
|
||||
}
|
||||
else if (mayIgnore(n.type)) {
|
||||
return false;
|
||||
}
|
||||
else {
|
||||
let parent = last > 0 ? stack[last - 1][pos[last - 1]].name : "tree";
|
||||
let after = next ? next.name + (parent == "tree" ? "" : " in " + parent) : `end of ${parent}`;
|
||||
throw new Error(`Expected ${after}, got ${n.name} at ${n.to} \n${tree}`);
|
||||
}
|
||||
},
|
||||
leave(n) {
|
||||
if (!n.name)
|
||||
return;
|
||||
let last = stack.length - 1, index = pos[last], seq = stack[last];
|
||||
if (index < seq.length)
|
||||
throw new Error(`Unexpected end of ${n.name}. Expected ${seq.slice(index).map(s => s.name).join(", ")} at ${n.from}\n${tree}`);
|
||||
pos.pop();
|
||||
stack.pop();
|
||||
pos[last - 1]++;
|
||||
}
|
||||
});
|
||||
if (pos[0] != specs.length)
|
||||
throw new Error(`Unexpected end of tree. Expected ${stack[0].slice(pos[0]).map(s => s.name).join(", ")} at ${tree.length}\n${tree}`);
|
||||
}
|
||||
function toLineContext(file, index) {
|
||||
const endEol = file.indexOf('\n', index + 80);
|
||||
const endIndex = endEol === -1 ? file.length : endEol;
|
||||
return file.substring(index, endIndex).split(/\n/).map(str => ' | ' + str).join('\n');
|
||||
}
|
||||
function fileTests(file, fileName, mayIgnore = defaultIgnore) {
|
||||
let caseExpr = /\s*#[ \t]*(.*)(?:\r\n|\r|\n)([^]*?)==+>([^]*?)(?:$|(?:\r\n|\r|\n)+(?=#))/gy;
|
||||
let tests = [];
|
||||
let lastIndex = 0;
|
||||
for (;;) {
|
||||
let m = caseExpr.exec(file);
|
||||
if (!m)
|
||||
throw new Error(`Unexpected file format in ${fileName} around\n\n${toLineContext(file, lastIndex)}`);
|
||||
let text = m[2].trim(), expected = m[3].trim();
|
||||
let [, name, configStr] = /(.*?)(\{.*?\})?$/.exec(m[1]);
|
||||
let config = configStr ? JSON.parse(configStr) : null;
|
||||
let strict = !/⚠|\.\.\./.test(expected);
|
||||
tests.push({
|
||||
name,
|
||||
text,
|
||||
expected,
|
||||
configStr,
|
||||
config,
|
||||
strict,
|
||||
run(parser) {
|
||||
if (parser.configure && (strict || config))
|
||||
parser = parser.configure(Object.assign({ strict }, config));
|
||||
testTree(parser.parse(text), expected, mayIgnore);
|
||||
}
|
||||
});
|
||||
lastIndex = m.index + m[0].length;
|
||||
if (lastIndex == file.length)
|
||||
break;
|
||||
}
|
||||
return tests;
|
||||
}
|
||||
|
||||
export { fileTests, testTree };
|
||||
Reference in New Issue
Block a user