+202
@@ -0,0 +1,202 @@
|
||||
|
||||
Apache License
|
||||
Version 2.0, January 2004
|
||||
http://www.apache.org/licenses/
|
||||
|
||||
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
|
||||
|
||||
1. Definitions.
|
||||
|
||||
"License" shall mean the terms and conditions for use, reproduction,
|
||||
and distribution as defined by Sections 1 through 9 of this document.
|
||||
|
||||
"Licensor" shall mean the copyright owner or entity authorized by
|
||||
the copyright owner that is granting the License.
|
||||
|
||||
"Legal Entity" shall mean the union of the acting entity and all
|
||||
other entities that control, are controlled by, or are under common
|
||||
control with that entity. For the purposes of this definition,
|
||||
"control" means (i) the power, direct or indirect, to cause the
|
||||
direction or management of such entity, whether by contract or
|
||||
otherwise, or (ii) ownership of fifty percent (50%) or more of the
|
||||
outstanding shares, or (iii) beneficial ownership of such entity.
|
||||
|
||||
"You" (or "Your") shall mean an individual or Legal Entity
|
||||
exercising permissions granted by this License.
|
||||
|
||||
"Source" form shall mean the preferred form for making modifications,
|
||||
including but not limited to software source code, documentation
|
||||
source, and configuration files.
|
||||
|
||||
"Object" form shall mean any form resulting from mechanical
|
||||
transformation or translation of a Source form, including but
|
||||
not limited to compiled object code, generated documentation,
|
||||
and conversions to other media types.
|
||||
|
||||
"Work" shall mean the work of authorship, whether in Source or
|
||||
Object form, made available under the License, as indicated by a
|
||||
copyright notice that is included in or attached to the work
|
||||
(an example is provided in the Appendix below).
|
||||
|
||||
"Derivative Works" shall mean any work, whether in Source or Object
|
||||
form, that is based on (or derived from) the Work and for which the
|
||||
editorial revisions, annotations, elaborations, or other modifications
|
||||
represent, as a whole, an original work of authorship. For the purposes
|
||||
of this License, Derivative Works shall not include works that remain
|
||||
separable from, or merely link (or bind by name) to the interfaces of,
|
||||
the Work and Derivative Works thereof.
|
||||
|
||||
"Contribution" shall mean any work of authorship, including
|
||||
the original version of the Work and any modifications or additions
|
||||
to that Work or Derivative Works thereof, that is intentionally
|
||||
submitted to Licensor for inclusion in the Work by the copyright owner
|
||||
or by an individual or Legal Entity authorized to submit on behalf of
|
||||
the copyright owner. For the purposes of this definition, "submitted"
|
||||
means any form of electronic, verbal, or written communication sent
|
||||
to the Licensor or its representatives, including but not limited to
|
||||
communication on electronic mailing lists, source code control systems,
|
||||
and issue tracking systems that are managed by, or on behalf of, the
|
||||
Licensor for the purpose of discussing and improving the Work, but
|
||||
excluding communication that is conspicuously marked or otherwise
|
||||
designated in writing by the copyright owner as "Not a Contribution."
|
||||
|
||||
"Contributor" shall mean Licensor and any individual or Legal Entity
|
||||
on behalf of whom a Contribution has been received by Licensor and
|
||||
subsequently incorporated within the Work.
|
||||
|
||||
2. Grant of Copyright License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
copyright license to reproduce, prepare Derivative Works of,
|
||||
publicly display, publicly perform, sublicense, and distribute the
|
||||
Work and such Derivative Works in Source or Object form.
|
||||
|
||||
3. Grant of Patent License. Subject to the terms and conditions of
|
||||
this License, each Contributor hereby grants to You a perpetual,
|
||||
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
|
||||
(except as stated in this section) patent license to make, have made,
|
||||
use, offer to sell, sell, import, and otherwise transfer the Work,
|
||||
where such license applies only to those patent claims licensable
|
||||
by such Contributor that are necessarily infringed by their
|
||||
Contribution(s) alone or by combination of their Contribution(s)
|
||||
with the Work to which such Contribution(s) was submitted. If You
|
||||
institute patent litigation against any entity (including a
|
||||
cross-claim or counterclaim in a lawsuit) alleging that the Work
|
||||
or a Contribution incorporated within the Work constitutes direct
|
||||
or contributory patent infringement, then any patent licenses
|
||||
granted to You under this License for that Work shall terminate
|
||||
as of the date such litigation is filed.
|
||||
|
||||
4. Redistribution. You may reproduce and distribute copies of the
|
||||
Work or Derivative Works thereof in any medium, with or without
|
||||
modifications, and in Source or Object form, provided that You
|
||||
meet the following conditions:
|
||||
|
||||
(a) You must give any other recipients of the Work or
|
||||
Derivative Works a copy of this License; and
|
||||
|
||||
(b) You must cause any modified files to carry prominent notices
|
||||
stating that You changed the files; and
|
||||
|
||||
(c) You must retain, in the Source form of any Derivative Works
|
||||
that You distribute, all copyright, patent, trademark, and
|
||||
attribution notices from the Source form of the Work,
|
||||
excluding those notices that do not pertain to any part of
|
||||
the Derivative Works; and
|
||||
|
||||
(d) If the Work includes a "NOTICE" text file as part of its
|
||||
distribution, then any Derivative Works that You distribute must
|
||||
include a readable copy of the attribution notices contained
|
||||
within such NOTICE file, excluding those notices that do not
|
||||
pertain to any part of the Derivative Works, in at least one
|
||||
of the following places: within a NOTICE text file distributed
|
||||
as part of the Derivative Works; within the Source form or
|
||||
documentation, if provided along with the Derivative Works; or,
|
||||
within a display generated by the Derivative Works, if and
|
||||
wherever such third-party notices normally appear. The contents
|
||||
of the NOTICE file are for informational purposes only and
|
||||
do not modify the License. You may add Your own attribution
|
||||
notices within Derivative Works that You distribute, alongside
|
||||
or as an addendum to the NOTICE text from the Work, provided
|
||||
that such additional attribution notices cannot be construed
|
||||
as modifying the License.
|
||||
|
||||
You may add Your own copyright statement to Your modifications and
|
||||
may provide additional or different license terms and conditions
|
||||
for use, reproduction, or distribution of Your modifications, or
|
||||
for any such Derivative Works as a whole, provided Your use,
|
||||
reproduction, and distribution of the Work otherwise complies with
|
||||
the conditions stated in this License.
|
||||
|
||||
5. Submission of Contributions. Unless You explicitly state otherwise,
|
||||
any Contribution intentionally submitted for inclusion in the Work
|
||||
by You to the Licensor shall be under the terms and conditions of
|
||||
this License, without any additional terms or conditions.
|
||||
Notwithstanding the above, nothing herein shall supersede or modify
|
||||
the terms of any separate license agreement you may have executed
|
||||
with Licensor regarding such Contributions.
|
||||
|
||||
6. Trademarks. This License does not grant permission to use the trade
|
||||
names, trademarks, service marks, or product names of the Licensor,
|
||||
except as required for reasonable and customary use in describing the
|
||||
origin of the Work and reproducing the content of the NOTICE file.
|
||||
|
||||
7. Disclaimer of Warranty. Unless required by applicable law or
|
||||
agreed to in writing, Licensor provides the Work (and each
|
||||
Contributor provides its Contributions) on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
implied, including, without limitation, any warranties or conditions
|
||||
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
|
||||
PARTICULAR PURPOSE. You are solely responsible for determining the
|
||||
appropriateness of using or redistributing the Work and assume any
|
||||
risks associated with Your exercise of permissions under this License.
|
||||
|
||||
8. Limitation of Liability. In no event and under no legal theory,
|
||||
whether in tort (including negligence), contract, or otherwise,
|
||||
unless required by applicable law (such as deliberate and grossly
|
||||
negligent acts) or agreed to in writing, shall any Contributor be
|
||||
liable to You for damages, including any direct, indirect, special,
|
||||
incidental, or consequential damages of any character arising as a
|
||||
result of this License or out of the use or inability to use the
|
||||
Work (including but not limited to damages for loss of goodwill,
|
||||
work stoppage, computer failure or malfunction, or any and all
|
||||
other commercial damages or losses), even if such Contributor
|
||||
has been advised of the possibility of such damages.
|
||||
|
||||
9. Accepting Warranty or Additional Liability. While redistributing
|
||||
the Work or Derivative Works thereof, You may choose to offer,
|
||||
and charge a fee for, acceptance of support, warranty, indemnity,
|
||||
or other liability obligations and/or rights consistent with this
|
||||
License. However, in accepting such obligations, You may act only
|
||||
on Your own behalf and on Your sole responsibility, not on behalf
|
||||
of any other Contributor, and only if You agree to indemnify,
|
||||
defend, and hold each Contributor harmless for any liability
|
||||
incurred by, or claims asserted against, such Contributor by reason
|
||||
of your accepting any such warranty or additional liability.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
APPENDIX: How to apply the Apache License to your work.
|
||||
|
||||
To apply the Apache License to your work, attach the following
|
||||
boilerplate notice, with the fields enclosed by brackets "[]"
|
||||
replaced with your own identifying information. (Don't include
|
||||
the brackets!) The text should be enclosed in the appropriate
|
||||
comment syntax for the file format. We also recommend that a
|
||||
file or class name and description of purpose be included on the
|
||||
same "printed page" as the copyright notice for easier
|
||||
identification within third-party archives.
|
||||
|
||||
Copyright [yyyy] [name of copyright owner]
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
+2
@@ -0,0 +1,2 @@
|
||||
import { GenerateDtsOptions, Rule } from "@chevrotain/types";
|
||||
export declare function generateCstDts(productions: Record<string, Rule>, options?: GenerateDtsOptions): string;
|
||||
+12
@@ -0,0 +1,12 @@
|
||||
import { buildModel } from "./model.js";
|
||||
import { genDts } from "./generate.js";
|
||||
const defaultOptions = {
|
||||
includeVisitorInterface: true,
|
||||
visitorInterfaceName: "ICstNodeVisitor",
|
||||
};
|
||||
export function generateCstDts(productions, options) {
|
||||
const effectiveOptions = Object.assign(Object.assign({}, defaultOptions), options);
|
||||
const model = buildModel(productions);
|
||||
return genDts(model, effectiveOptions);
|
||||
}
|
||||
//# sourceMappingURL=api.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/api.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAEvC,MAAM,cAAc,GAAiC;IACnD,uBAAuB,EAAE,IAAI;IAC7B,oBAAoB,EAAE,iBAAiB;CACxC,CAAC;AAEF,MAAM,UAAU,cAAc,CAC5B,WAAiC,EACjC,OAA4B;IAE5B,MAAM,gBAAgB,mCACjB,cAAc,GACd,OAAO,CACX,CAAC;IAEF,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC;IAEtC,OAAO,MAAM,CAAC,KAAK,EAAE,gBAAgB,CAAC,CAAC;AACzC,CAAC"}
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
import { GenerateDtsOptions } from "@chevrotain/types";
|
||||
import { CstNodeTypeDefinition } from "./model.js";
|
||||
export declare function genDts(model: CstNodeTypeDefinition[], options: Required<GenerateDtsOptions>): string;
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
export function genDts(model, options) {
|
||||
let contentParts = [];
|
||||
contentParts = contentParts.concat(`import type { CstNode, ICstVisitor, IToken } from "chevrotain";`);
|
||||
contentParts = contentParts.concat(model.flatMap((node) => genCstNodeTypes(node)));
|
||||
if (options.includeVisitorInterface) {
|
||||
contentParts = contentParts.concat(genVisitor(options.visitorInterfaceName, model));
|
||||
}
|
||||
return contentParts.join("\n\n") + "\n";
|
||||
}
|
||||
function genCstNodeTypes(node) {
|
||||
const nodeCstInterface = genNodeInterface(node);
|
||||
const nodeChildrenInterface = genNodeChildrenType(node);
|
||||
return [nodeCstInterface, nodeChildrenInterface];
|
||||
}
|
||||
function genNodeInterface(node) {
|
||||
const nodeInterfaceName = getNodeInterfaceName(node.name);
|
||||
const childrenTypeName = getNodeChildrenTypeName(node.name);
|
||||
return `export interface ${nodeInterfaceName} extends CstNode {
|
||||
name: "${node.name}";
|
||||
children: ${childrenTypeName};
|
||||
}`;
|
||||
}
|
||||
function genNodeChildrenType(node) {
|
||||
const typeName = getNodeChildrenTypeName(node.name);
|
||||
return `export type ${typeName} = {
|
||||
${node.properties.map((property) => genChildProperty(property)).join("\n ")}
|
||||
};`;
|
||||
}
|
||||
function genChildProperty(prop) {
|
||||
const typeName = buildTypeString(prop.type);
|
||||
return `${prop.name}${prop.optional ? "?" : ""}: ${typeName}[];`;
|
||||
}
|
||||
function genVisitor(name, nodes) {
|
||||
return `export interface ${name}<IN, OUT> extends ICstVisitor<IN, OUT> {
|
||||
${nodes.map((node) => genVisitorFunction(node)).join("\n ")}
|
||||
}`;
|
||||
}
|
||||
function genVisitorFunction(node) {
|
||||
const childrenTypeName = getNodeChildrenTypeName(node.name);
|
||||
return `${node.name}(children: ${childrenTypeName}, param?: IN): OUT;`;
|
||||
}
|
||||
function buildTypeString(type) {
|
||||
if (Array.isArray(type)) {
|
||||
const typeNames = [...new Set(type.map((t) => getTypeString(t)))];
|
||||
const typeString = typeNames.join(" | ");
|
||||
return "(" + typeString + ")";
|
||||
}
|
||||
else {
|
||||
return getTypeString(type);
|
||||
}
|
||||
}
|
||||
function getTypeString(type) {
|
||||
if (type.kind === "token") {
|
||||
return "IToken";
|
||||
}
|
||||
return getNodeInterfaceName(type.name);
|
||||
}
|
||||
function getNodeInterfaceName(ruleName) {
|
||||
return ruleName.charAt(0).toUpperCase() + ruleName.slice(1) + "CstNode";
|
||||
}
|
||||
function getNodeChildrenTypeName(ruleName) {
|
||||
return ruleName.charAt(0).toUpperCase() + ruleName.slice(1) + "CstChildren";
|
||||
}
|
||||
//# sourceMappingURL=generate.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"generate.js","sourceRoot":"","sources":["../../src/generate.ts"],"names":[],"mappings":"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"}
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
import type { Rule } from "@chevrotain/types";
|
||||
export declare function buildModel(productions: Record<string, Rule>): CstNodeTypeDefinition[];
|
||||
export type CstNodeTypeDefinition = {
|
||||
name: string;
|
||||
properties: PropertyTypeDefinition[];
|
||||
};
|
||||
export type PropertyTypeDefinition = {
|
||||
name: string;
|
||||
type: PropertyArrayType;
|
||||
optional: boolean;
|
||||
};
|
||||
export type PropertyArrayType = TokenArrayType | RuleArrayType | (TokenArrayType | RuleArrayType)[];
|
||||
export type TokenArrayType = {
|
||||
kind: "token";
|
||||
};
|
||||
export type RuleArrayType = {
|
||||
kind: "rule";
|
||||
name: string;
|
||||
};
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
import { GAstVisitor, NonTerminal } from "@chevrotain/gast";
|
||||
export function buildModel(productions) {
|
||||
const generator = new CstNodeDefinitionGenerator();
|
||||
const allRules = Object.values(productions);
|
||||
return allRules.map((rule) => generator.visitRule(rule));
|
||||
}
|
||||
class CstNodeDefinitionGenerator extends GAstVisitor {
|
||||
visitRule(node) {
|
||||
const rawElements = this.visitEach(node.definition);
|
||||
const grouped = Object.groupBy(rawElements, (el) => el.propertyName);
|
||||
const properties = Object.entries(grouped).map(([propertyName, group]) => {
|
||||
const allNullable = !group.some((el) => !el.canBeNull);
|
||||
// In an alternation with a label a property name can have
|
||||
// multiple types.
|
||||
let propertyType = group[0].type;
|
||||
if (group.length > 1) {
|
||||
propertyType = group.map((g) => g.type);
|
||||
}
|
||||
return {
|
||||
name: propertyName,
|
||||
type: propertyType,
|
||||
optional: allNullable,
|
||||
};
|
||||
});
|
||||
return {
|
||||
name: node.name,
|
||||
properties: properties,
|
||||
};
|
||||
}
|
||||
visitAlternative(node) {
|
||||
return this.visitEachAndOverrideWith(node.definition, { canBeNull: true });
|
||||
}
|
||||
visitOption(node) {
|
||||
return this.visitEachAndOverrideWith(node.definition, { canBeNull: true });
|
||||
}
|
||||
visitRepetition(node) {
|
||||
return this.visitEachAndOverrideWith(node.definition, { canBeNull: true });
|
||||
}
|
||||
visitRepetitionMandatory(node) {
|
||||
return this.visitEach(node.definition);
|
||||
}
|
||||
visitRepetitionMandatoryWithSeparator(node) {
|
||||
return this.visitEach(node.definition).concat({
|
||||
propertyName: node.separator.name,
|
||||
canBeNull: true,
|
||||
type: getType(node.separator),
|
||||
});
|
||||
}
|
||||
visitRepetitionWithSeparator(node) {
|
||||
return this.visitEachAndOverrideWith(node.definition, {
|
||||
canBeNull: true,
|
||||
}).concat({
|
||||
propertyName: node.separator.name,
|
||||
canBeNull: true,
|
||||
type: getType(node.separator),
|
||||
});
|
||||
}
|
||||
visitAlternation(node) {
|
||||
return this.visitEachAndOverrideWith(node.definition, { canBeNull: true });
|
||||
}
|
||||
visitTerminal(node) {
|
||||
return [
|
||||
{
|
||||
propertyName: node.label || node.terminalType.name,
|
||||
canBeNull: false,
|
||||
type: getType(node),
|
||||
},
|
||||
];
|
||||
}
|
||||
visitNonTerminal(node) {
|
||||
return [
|
||||
{
|
||||
propertyName: node.label || node.nonTerminalName,
|
||||
canBeNull: false,
|
||||
type: getType(node),
|
||||
},
|
||||
];
|
||||
}
|
||||
visitEachAndOverrideWith(definition, override) {
|
||||
return this.visitEach(definition).map((definition) => (Object.assign(Object.assign({}, definition), override)));
|
||||
}
|
||||
visitEach(definition) {
|
||||
return definition.flatMap((definition) => this.visit(definition));
|
||||
}
|
||||
}
|
||||
function getType(production) {
|
||||
if (production instanceof NonTerminal) {
|
||||
return {
|
||||
kind: "rule",
|
||||
name: production.referencedRule.name,
|
||||
};
|
||||
}
|
||||
return { kind: "token" };
|
||||
}
|
||||
//# sourceMappingURL=model.js.map
|
||||
+1
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"model.js","sourceRoot":"","sources":["../../src/model.ts"],"names":[],"mappings":"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"}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
{
|
||||
"name": "@chevrotain/cst-dts-gen",
|
||||
"version": "12.0.0",
|
||||
"description": "Generates type definitions for Chevrotain CST nodes",
|
||||
"keywords": [],
|
||||
"bugs": {
|
||||
"url": "https://github.com/Chevrotain/chevrotain/issues"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"type": "module",
|
||||
"types": "./lib/src/api.d.ts",
|
||||
"exports": {
|
||||
".": {
|
||||
"import": "./lib/src/api.js",
|
||||
"types": "./lib/src/api.d.ts"
|
||||
}
|
||||
},
|
||||
"files": [
|
||||
"lib/src/**/*.js",
|
||||
"lib/src/**/*.map",
|
||||
"lib/src/**/*.d.ts",
|
||||
"src/**/*.ts"
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/Chevrotain/chevrotain.git"
|
||||
},
|
||||
"scripts": {
|
||||
"---------- CI FLOWS --------": "",
|
||||
"ci": "pnpm run build test",
|
||||
"build": "npm-run-all clean compile",
|
||||
"test": "echo \"tests are in a different package\"",
|
||||
"---------- BUILD STEPS --------": "",
|
||||
"clean": "shx rm -rf lib",
|
||||
"compile:watch": "tsc -w",
|
||||
"compile": "tsc"
|
||||
},
|
||||
"dependencies": {
|
||||
"@chevrotain/gast": "12.0.0",
|
||||
"@chevrotain/types": "12.0.0"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"gitHead": "d3b4d05d5dd53d53d27175119bc7c9ed8056e3d5"
|
||||
}
|
||||
+22
@@ -0,0 +1,22 @@
|
||||
import { GenerateDtsOptions, Rule } from "@chevrotain/types";
|
||||
import { buildModel } from "./model.js";
|
||||
import { genDts } from "./generate.js";
|
||||
|
||||
const defaultOptions: Required<GenerateDtsOptions> = {
|
||||
includeVisitorInterface: true,
|
||||
visitorInterfaceName: "ICstNodeVisitor",
|
||||
};
|
||||
|
||||
export function generateCstDts(
|
||||
productions: Record<string, Rule>,
|
||||
options?: GenerateDtsOptions,
|
||||
): string {
|
||||
const effectiveOptions = {
|
||||
...defaultOptions,
|
||||
...options,
|
||||
};
|
||||
|
||||
const model = buildModel(productions);
|
||||
|
||||
return genDts(model, effectiveOptions);
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
import { GenerateDtsOptions } from "@chevrotain/types";
|
||||
import {
|
||||
CstNodeTypeDefinition,
|
||||
PropertyArrayType,
|
||||
PropertyTypeDefinition,
|
||||
RuleArrayType,
|
||||
TokenArrayType,
|
||||
} from "./model.js";
|
||||
|
||||
export function genDts(
|
||||
model: CstNodeTypeDefinition[],
|
||||
options: Required<GenerateDtsOptions>,
|
||||
): string {
|
||||
let contentParts: string[] = [];
|
||||
|
||||
contentParts = contentParts.concat(
|
||||
`import type { CstNode, ICstVisitor, IToken } from "chevrotain";`,
|
||||
);
|
||||
|
||||
contentParts = contentParts.concat(
|
||||
model.flatMap((node) => genCstNodeTypes(node)),
|
||||
);
|
||||
|
||||
if (options.includeVisitorInterface) {
|
||||
contentParts = contentParts.concat(
|
||||
genVisitor(options.visitorInterfaceName, model),
|
||||
);
|
||||
}
|
||||
|
||||
return contentParts.join("\n\n") + "\n";
|
||||
}
|
||||
|
||||
function genCstNodeTypes(node: CstNodeTypeDefinition) {
|
||||
const nodeCstInterface = genNodeInterface(node);
|
||||
const nodeChildrenInterface = genNodeChildrenType(node);
|
||||
|
||||
return [nodeCstInterface, nodeChildrenInterface];
|
||||
}
|
||||
|
||||
function genNodeInterface(node: CstNodeTypeDefinition) {
|
||||
const nodeInterfaceName = getNodeInterfaceName(node.name);
|
||||
const childrenTypeName = getNodeChildrenTypeName(node.name);
|
||||
|
||||
return `export interface ${nodeInterfaceName} extends CstNode {
|
||||
name: "${node.name}";
|
||||
children: ${childrenTypeName};
|
||||
}`;
|
||||
}
|
||||
|
||||
function genNodeChildrenType(node: CstNodeTypeDefinition) {
|
||||
const typeName = getNodeChildrenTypeName(node.name);
|
||||
|
||||
return `export type ${typeName} = {
|
||||
${node.properties.map((property) => genChildProperty(property)).join("\n ")}
|
||||
};`;
|
||||
}
|
||||
|
||||
function genChildProperty(prop: PropertyTypeDefinition) {
|
||||
const typeName = buildTypeString(prop.type);
|
||||
return `${prop.name}${prop.optional ? "?" : ""}: ${typeName}[];`;
|
||||
}
|
||||
|
||||
function genVisitor(name: string, nodes: CstNodeTypeDefinition[]) {
|
||||
return `export interface ${name}<IN, OUT> extends ICstVisitor<IN, OUT> {
|
||||
${nodes.map((node) => genVisitorFunction(node)).join("\n ")}
|
||||
}`;
|
||||
}
|
||||
|
||||
function genVisitorFunction(node: CstNodeTypeDefinition) {
|
||||
const childrenTypeName = getNodeChildrenTypeName(node.name);
|
||||
return `${node.name}(children: ${childrenTypeName}, param?: IN): OUT;`;
|
||||
}
|
||||
|
||||
function buildTypeString(type: PropertyArrayType) {
|
||||
if (Array.isArray(type)) {
|
||||
const typeNames = [...new Set(type.map((t) => getTypeString(t)))];
|
||||
const typeString = typeNames.join(" | ");
|
||||
return "(" + typeString + ")";
|
||||
} else {
|
||||
return getTypeString(type);
|
||||
}
|
||||
}
|
||||
|
||||
function getTypeString(type: TokenArrayType | RuleArrayType) {
|
||||
if (type.kind === "token") {
|
||||
return "IToken";
|
||||
}
|
||||
return getNodeInterfaceName(type.name);
|
||||
}
|
||||
|
||||
function getNodeInterfaceName(ruleName: string) {
|
||||
return ruleName.charAt(0).toUpperCase() + ruleName.slice(1) + "CstNode";
|
||||
}
|
||||
|
||||
function getNodeChildrenTypeName(ruleName: string) {
|
||||
return ruleName.charAt(0).toUpperCase() + ruleName.slice(1) + "CstChildren";
|
||||
}
|
||||
+167
@@ -0,0 +1,167 @@
|
||||
import type {
|
||||
Alternation,
|
||||
Alternative,
|
||||
IProduction,
|
||||
Option,
|
||||
Repetition,
|
||||
RepetitionMandatory,
|
||||
RepetitionMandatoryWithSeparator,
|
||||
RepetitionWithSeparator,
|
||||
Rule,
|
||||
Terminal,
|
||||
TokenType,
|
||||
} from "@chevrotain/types";
|
||||
import { GAstVisitor, NonTerminal } from "@chevrotain/gast";
|
||||
|
||||
export function buildModel(
|
||||
productions: Record<string, Rule>,
|
||||
): CstNodeTypeDefinition[] {
|
||||
const generator = new CstNodeDefinitionGenerator();
|
||||
const allRules = Object.values(productions);
|
||||
return allRules.map((rule) => generator.visitRule(rule));
|
||||
}
|
||||
|
||||
export type CstNodeTypeDefinition = {
|
||||
name: string;
|
||||
properties: PropertyTypeDefinition[];
|
||||
};
|
||||
|
||||
export type PropertyTypeDefinition = {
|
||||
name: string;
|
||||
type: PropertyArrayType;
|
||||
optional: boolean;
|
||||
};
|
||||
|
||||
export type PropertyArrayType =
|
||||
| TokenArrayType
|
||||
| RuleArrayType
|
||||
| (TokenArrayType | RuleArrayType)[];
|
||||
|
||||
export type TokenArrayType = { kind: "token" };
|
||||
export type RuleArrayType = {
|
||||
kind: "rule";
|
||||
name: string;
|
||||
};
|
||||
|
||||
class CstNodeDefinitionGenerator extends GAstVisitor {
|
||||
visitRule(node: Rule): CstNodeTypeDefinition {
|
||||
const rawElements = this.visitEach(node.definition);
|
||||
|
||||
const grouped = Object.groupBy(rawElements, (el) => el.propertyName);
|
||||
const properties = Object.entries(grouped).map(([propertyName, group]) => {
|
||||
const allNullable = !group!.some((el) => !el.canBeNull);
|
||||
|
||||
// In an alternation with a label a property name can have
|
||||
// multiple types.
|
||||
let propertyType: PropertyArrayType = group![0].type;
|
||||
if (group!.length > 1) {
|
||||
propertyType = group!.map((g) => g.type);
|
||||
}
|
||||
|
||||
return {
|
||||
name: propertyName,
|
||||
type: propertyType,
|
||||
optional: allNullable,
|
||||
} as PropertyTypeDefinition;
|
||||
});
|
||||
|
||||
return {
|
||||
name: node.name,
|
||||
properties: properties,
|
||||
};
|
||||
}
|
||||
|
||||
visitAlternative(node: Alternative) {
|
||||
return this.visitEachAndOverrideWith(node.definition, { canBeNull: true });
|
||||
}
|
||||
|
||||
visitOption(node: Option) {
|
||||
return this.visitEachAndOverrideWith(node.definition, { canBeNull: true });
|
||||
}
|
||||
|
||||
visitRepetition(node: Repetition) {
|
||||
return this.visitEachAndOverrideWith(node.definition, { canBeNull: true });
|
||||
}
|
||||
|
||||
visitRepetitionMandatory(node: RepetitionMandatory) {
|
||||
return this.visitEach(node.definition);
|
||||
}
|
||||
|
||||
visitRepetitionMandatoryWithSeparator(
|
||||
node: RepetitionMandatoryWithSeparator,
|
||||
) {
|
||||
return this.visitEach(node.definition).concat({
|
||||
propertyName: node.separator.name,
|
||||
canBeNull: true,
|
||||
type: getType(node.separator),
|
||||
});
|
||||
}
|
||||
|
||||
visitRepetitionWithSeparator(node: RepetitionWithSeparator) {
|
||||
return this.visitEachAndOverrideWith(node.definition, {
|
||||
canBeNull: true,
|
||||
}).concat({
|
||||
propertyName: node.separator.name,
|
||||
canBeNull: true,
|
||||
type: getType(node.separator),
|
||||
});
|
||||
}
|
||||
|
||||
visitAlternation(node: Alternation) {
|
||||
return this.visitEachAndOverrideWith(node.definition, { canBeNull: true });
|
||||
}
|
||||
|
||||
visitTerminal(node: Terminal): PropertyTupleElement[] {
|
||||
return [
|
||||
{
|
||||
propertyName: node.label || node.terminalType.name,
|
||||
canBeNull: false,
|
||||
type: getType(node),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
visitNonTerminal(node: NonTerminal): PropertyTupleElement[] {
|
||||
return [
|
||||
{
|
||||
propertyName: node.label || node.nonTerminalName,
|
||||
canBeNull: false,
|
||||
type: getType(node),
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
private visitEachAndOverrideWith(
|
||||
definition: IProduction[],
|
||||
override: Partial<PropertyTupleElement>,
|
||||
) {
|
||||
return this.visitEach(definition).map(
|
||||
(definition) => ({ ...definition, ...override }) as PropertyTupleElement,
|
||||
);
|
||||
}
|
||||
|
||||
private visitEach(definition: IProduction[]) {
|
||||
return definition.flatMap(
|
||||
(definition) => this.visit(definition) as PropertyTupleElement[],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
type PropertyTupleElement = {
|
||||
propertyName: string;
|
||||
canBeNull: boolean;
|
||||
type: TokenArrayType | RuleArrayType;
|
||||
};
|
||||
|
||||
function getType(
|
||||
production: Terminal | NonTerminal | TokenType,
|
||||
): TokenArrayType | RuleArrayType {
|
||||
if (production instanceof NonTerminal) {
|
||||
return {
|
||||
kind: "rule",
|
||||
name: production.referencedRule.name,
|
||||
};
|
||||
}
|
||||
|
||||
return { kind: "token" };
|
||||
}
|
||||
Reference in New Issue
Block a user