initial commit

This commit is contained in:
2026-04-05 16:08:59 +03:00
commit 75ab9bec9f
1117 changed files with 789034 additions and 0 deletions

4313
editor/node_modules/@lezer/generator/dist/index.cjs generated vendored Normal file

File diff suppressed because it is too large Load Diff

95
editor/node_modules/@lezer/generator/dist/index.d.cts generated vendored Normal file
View File

@@ -0,0 +1,95 @@
import { NodePropSource, NodeProp } from '@lezer/common';
import { ExternalTokenizer, Stack, ContextTracker, LRParser } from '@lezer/lr';
type BuildOptions = {
/**
The name of the grammar file
*/
fileName?: string;
/**
A function that should be called with warnings. The default is
to call `console.warn`.
*/
warn?: (message: string) => void;
/**
Whether to include term names in the output file. Defaults to
false.
*/
includeNames?: boolean;
/**
Determines the module system used by the output file. Can be
either `"cjs"` (CommonJS) or `"es"` (ES2015 module), defaults to
`"es"`.
*/
moduleStyle?: string;
/**
Set this to true to output TypeScript code instead of plain
JavaScript.
*/
typeScript?: boolean;
/**
The name of the export that holds the parser in the output file.
Defaults to `"parser"`.
*/
exportName?: string;
/**
When calling `buildParser`, this can be used to provide
placeholders for external tokenizers.
*/
externalTokenizer?: (name: string, terms: {
[name: string]: number;
}) => ExternalTokenizer;
/**
Used by `buildParser` to resolve external prop sources.
*/
externalPropSource?: (name: string) => NodePropSource;
/**
Provide placeholders for external specializers when using
`buildParser`.
*/
externalSpecializer?: (name: string, terms: {
[name: string]: number;
}) => (value: string, stack: Stack) => number;
/**
If given, will be used to initialize external props in the parser
returned by `buildParser`.
*/
externalProp?: (name: string) => NodeProp<any>;
/**
If given, will be used as context tracker in a parser built with
`buildParser`.
*/
contextTracker?: ContextTracker<any> | ((terms: {
[name: string]: number;
}) => ContextTracker<any>);
};
/**
Build an in-memory parser instance for a given grammar. This is
mostly useful for testing. If your grammar uses external
tokenizers, you'll have to provide the `externalTokenizer` option
for the returned parser to be able to parse anything.
*/
declare function buildParser(text: string, options?: BuildOptions): LRParser;
/**
Build the code that represents the parser tables for a given
grammar description. The `parser` property in the return value
holds the main file that exports the `Parser` instance. The
`terms` property holds a declaration file that defines constants
for all of the named terms in grammar, holding their ids as value.
This is useful when external code, such as a tokenizer, needs to
be able to use these ids. It is recommended to run a tree-shaking
bundler when importing this file, since you usually only need a
handful of the many terms in your code.
*/
declare function buildParserFile(text: string, options?: BuildOptions): {
parser: string;
terms: string;
};
/**
The type of error raised when the parser generator finds an issue.
*/
declare class GenError extends Error {
}
export { type BuildOptions, GenError, buildParser, buildParserFile };

95
editor/node_modules/@lezer/generator/dist/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,95 @@
import { NodePropSource, NodeProp } from '@lezer/common';
import { ExternalTokenizer, Stack, ContextTracker, LRParser } from '@lezer/lr';
type BuildOptions = {
/**
The name of the grammar file
*/
fileName?: string;
/**
A function that should be called with warnings. The default is
to call `console.warn`.
*/
warn?: (message: string) => void;
/**
Whether to include term names in the output file. Defaults to
false.
*/
includeNames?: boolean;
/**
Determines the module system used by the output file. Can be
either `"cjs"` (CommonJS) or `"es"` (ES2015 module), defaults to
`"es"`.
*/
moduleStyle?: string;
/**
Set this to true to output TypeScript code instead of plain
JavaScript.
*/
typeScript?: boolean;
/**
The name of the export that holds the parser in the output file.
Defaults to `"parser"`.
*/
exportName?: string;
/**
When calling `buildParser`, this can be used to provide
placeholders for external tokenizers.
*/
externalTokenizer?: (name: string, terms: {
[name: string]: number;
}) => ExternalTokenizer;
/**
Used by `buildParser` to resolve external prop sources.
*/
externalPropSource?: (name: string) => NodePropSource;
/**
Provide placeholders for external specializers when using
`buildParser`.
*/
externalSpecializer?: (name: string, terms: {
[name: string]: number;
}) => (value: string, stack: Stack) => number;
/**
If given, will be used to initialize external props in the parser
returned by `buildParser`.
*/
externalProp?: (name: string) => NodeProp<any>;
/**
If given, will be used as context tracker in a parser built with
`buildParser`.
*/
contextTracker?: ContextTracker<any> | ((terms: {
[name: string]: number;
}) => ContextTracker<any>);
};
/**
Build an in-memory parser instance for a given grammar. This is
mostly useful for testing. If your grammar uses external
tokenizers, you'll have to provide the `externalTokenizer` option
for the returned parser to be able to parse anything.
*/
declare function buildParser(text: string, options?: BuildOptions): LRParser;
/**
Build the code that represents the parser tables for a given
grammar description. The `parser` property in the return value
holds the main file that exports the `Parser` instance. The
`terms` property holds a declaration file that defines constants
for all of the named terms in grammar, holding their ids as value.
This is useful when external code, such as a tokenizer, needs to
be able to use these ids. It is recommended to run a tree-shaking
bundler when importing this file, since you usually only need a
handful of the many terms in your code.
*/
declare function buildParserFile(text: string, options?: BuildOptions): {
parser: string;
terms: string;
};
/**
The type of error raised when the parser generator finds an issue.
*/
declare class GenError extends Error {
}
export { type BuildOptions, GenError, buildParser, buildParserFile };

4309
editor/node_modules/@lezer/generator/dist/index.js generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,45 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var path = require('path');
var fs = require('fs');
var index_js = require('./index.cjs');
function lezer(config = {}) {
let built = Object.create(null);
return {
name: "rollup-plugin-lezer",
resolveId(source, importer) {
let m = /^([^\0].*\.grammar)(\.terms)?$/.exec(source);
if (!m) return null
let id = path.resolve(importer ? path.dirname(importer) : process.cwd(), m[1]);
return m[2] ? `\0${id}.terms` : id
},
load(id) {
let m = /^\0?(.*\.grammar)(\.terms)?$/.exec(id);
if (!m) return null
if (!m[2]) this.addWatchFile(id);
let base = m[1];
let build = built[base] || (built[base] = fs.promises.readFile(base, "utf8").then(code => index_js.buildParserFile(code, {
fileName: base,
moduleStyle: "es",
exportName: config.exportName,
warn: message => this.warn(message)
})));
return build.then(result => m[2] ? result.terms : result.parser)
},
watchChange(id) {
if (built[id]) built[id] = null;
}
}
}
const rollup = lezer;
exports.lezer = lezer;
exports.rollup = rollup;

View File

@@ -0,0 +1,3 @@
import {Plugin} from "rollup"
export function lezer(config?: {exportName?: string}): Plugin

View File

@@ -0,0 +1,3 @@
import {Plugin} from "rollup"
export function lezer(config?: {exportName?: string}): Plugin

View File

@@ -0,0 +1,38 @@
import {resolve, dirname} from "path"
import {promises as fs} from "fs"
import {buildParserFile} from "./index.js"
export function lezer(config = {}) {
let built = Object.create(null)
return {
name: "rollup-plugin-lezer",
resolveId(source, importer) {
let m = /^([^\0].*\.grammar)(\.terms)?$/.exec(source)
if (!m) return null
let id = resolve(importer ? dirname(importer) : process.cwd(), m[1])
return m[2] ? `\0${id}.terms` : id
},
load(id) {
let m = /^\0?(.*\.grammar)(\.terms)?$/.exec(id)
if (!m) return null
if (!m[2]) this.addWatchFile(id)
let base = m[1]
let build = built[base] || (built[base] = fs.readFile(base, "utf8").then(code => buildParserFile(code, {
fileName: base,
moduleStyle: "es",
exportName: config.exportName,
warn: message => this.warn(message)
})))
return build.then(result => m[2] ? result.terms : result.parser)
},
watchChange(id) {
if (built[id]) built[id] = null
}
}
}
export const rollup = lezer

187
editor/node_modules/@lezer/generator/dist/test.cjs generated vendored Normal file
View File

@@ -0,0 +1,187 @@
'use strict';
var common = require('@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 = common.NodeProp[value], val = "";
if (!(prop instanceof common.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;
}
exports.fileTests = fileTests;
exports.testTree = testTree;

15
editor/node_modules/@lezer/generator/dist/test.d.cts generated vendored Normal file
View File

@@ -0,0 +1,15 @@
import { Tree, Parser, NodeType } from '@lezer/common';
declare function defaultIgnore(type: NodeType): boolean;
declare function testTree(tree: Tree, expect: string, mayIgnore?: typeof defaultIgnore): void;
declare function fileTests(file: string, fileName: string, mayIgnore?: typeof defaultIgnore): {
name: string;
text: string;
expected: string;
configStr: string;
config: object;
strict: boolean;
run(parser: Parser): void;
}[];
export { fileTests, testTree };

15
editor/node_modules/@lezer/generator/dist/test.d.ts generated vendored Normal file
View File

@@ -0,0 +1,15 @@
import { Tree, Parser, NodeType } from '@lezer/common';
declare function defaultIgnore(type: NodeType): boolean;
declare function testTree(tree: Tree, expect: string, mayIgnore?: typeof defaultIgnore): void;
declare function fileTests(file: string, fileName: string, mayIgnore?: typeof defaultIgnore): {
name: string;
text: string;
expected: string;
configStr: string;
config: object;
strict: boolean;
run(parser: Parser): void;
}[];
export { fileTests, testTree };

184
editor/node_modules/@lezer/generator/dist/test.js generated vendored Normal file
View 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 };