First commit.

Signed-off-by: Chen Xiao <abigwc@gmail.com>
This commit is contained in:
Chen Xiao
2026-05-08 14:43:16 +08:00
commit 0b64e2de94
10989 changed files with 2253791 additions and 0 deletions
@@ -0,0 +1,12 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { AstReflection } from '../syntax-tree.js';
import type { LangiumCoreServices } from '../index.js';
import type { Grammar } from '../languages/generated/ast.js';
import type { AstTypes } from './type-system/type-collector/types.js';
export declare function interpretAstReflection(astTypes: AstTypes): AstReflection;
export declare function interpretAstReflection(grammar: Grammar, services?: LangiumCoreServices): AstReflection;
//# sourceMappingURL=ast-reflection-interpreter.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"ast-reflection-interpreter.d.ts","sourceRoot":"","sources":["../../src/grammar/ast-reflection-interpreter.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,aAAa,EAAkC,MAAM,mBAAmB,CAAC;AACvF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,+BAA+B,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAY,MAAM,uCAAuC,CAAC;AAOhF,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,QAAQ,GAAG,aAAa,CAAC;AAC1E,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,mBAAmB,GAAG,aAAa,CAAC"}
+127
View File
@@ -0,0 +1,127 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { AbstractAstReflection } from '../syntax-tree.js';
import { MultiMap } from '../utils/collections.js';
import { isGrammar } from '../languages/generated/ast.js';
import { collectAst } from './type-system/ast-collector.js';
import { collectTypeHierarchy, findReferenceTypes, isAstType, mergeTypesAndInterfaces } from './type-system/types-util.js';
export function interpretAstReflection(grammarOrTypes, services) {
let collectedTypes;
if (isGrammar(grammarOrTypes)) {
collectedTypes = collectAst(grammarOrTypes, { services });
}
else {
collectedTypes = grammarOrTypes;
}
const allTypes = collectedTypes.interfaces.map(e => e.name).concat(collectedTypes.unions.filter(e => isAstType(e.type)).map(e => e.name));
const references = buildReferenceTypes(collectedTypes);
const metaData = buildTypeMetaData(collectedTypes);
const superTypes = collectTypeHierarchy(mergeTypesAndInterfaces(collectedTypes)).superTypes;
return new InterpretedAstReflection({
allTypes,
references,
metaData,
superTypes
});
}
class InterpretedAstReflection extends AbstractAstReflection {
constructor(options) {
// Build the types object required by AbstractAstReflection
const types = {};
for (const typeName of options.allTypes) {
const typeMetaData = options.metaData.get(typeName);
if (typeMetaData) {
const properties = {};
// Convert properties array to object and add reference types
if (Array.isArray(typeMetaData.properties)) {
for (const prop of typeMetaData.properties) {
const referenceKey = `${typeName}:${prop.name}`;
const referenceType = options.references.get(referenceKey);
properties[prop.name] = {
name: prop.name,
defaultValue: prop.defaultValue,
...(referenceType && { referenceType })
};
}
}
else {
// If properties is already an object, copy it and add reference types
for (const [propName, prop] of Object.entries(typeMetaData.properties)) {
const referenceKey = `${typeName}:${propName}`;
const referenceType = options.references.get(referenceKey);
properties[propName] = {
...prop,
...(referenceType && { referenceType })
};
}
}
types[typeName] = {
name: typeName,
properties,
superTypes: Array.from(options.superTypes.get(typeName))
};
}
}
super();
// Initialize the readonly types field
Object.defineProperty(this, 'types', { value: types });
}
computeIsSubtype(subtype, originalSuperType) {
const typeMetaData = this.types[subtype];
if (!typeMetaData) {
return false;
}
for (const superType of typeMetaData.superTypes) {
if (this.isSubtype(superType, originalSuperType)) {
return true;
}
}
return false;
}
}
function buildReferenceTypes(astTypes) {
const references = new MultiMap();
for (const interfaceType of astTypes.interfaces) {
for (const property of interfaceType.properties) {
for (const referenceType of findReferenceTypes(property.type)) {
references.add(interfaceType.name, [property.name, referenceType]);
}
}
for (const superType of interfaceType.interfaceSuperTypes) {
const superTypeReferences = references.get(superType.name);
references.addAll(interfaceType.name, superTypeReferences);
}
}
const map = new Map();
for (const [type, [property, target]] of references) {
map.set(`${type}:${property}`, target);
}
return map;
}
function buildTypeMetaData(astTypes) {
const map = new Map();
for (const interfaceType of astTypes.interfaces) {
const props = interfaceType.superProperties;
map.set(interfaceType.name, {
name: interfaceType.name,
properties: buildPropertyMetaData(props),
superTypes: [] // Will be populated later from superTypes data
});
}
return map;
}
function buildPropertyMetaData(props) {
const properties = {};
const all = props.sort((a, b) => a.name.localeCompare(b.name));
for (const property of all) {
properties[property.name] = {
name: property.name,
defaultValue: property.defaultValue
};
}
return properties;
}
//# sourceMappingURL=ast-reflection-interpreter.js.map
@@ -0,0 +1 @@
{"version":3,"file":"ast-reflection-interpreter.js","sourceRoot":"","sources":["../../src/grammar/ast-reflection-interpreter.ts"],"names":[],"mappings":"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"}
+7
View File
@@ -0,0 +1,7 @@
/******************************************************************************
* This file was generated by langium-cli 4.2.1.
* DO NOT EDIT MANUALLY!
******************************************************************************/
import type { Grammar } from '../../languages/generated/ast.js';
export declare const LangiumGrammarGrammar: () => Grammar;
//# sourceMappingURL=grammar.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"grammar.d.ts","sourceRoot":"","sources":["../../../src/grammar/generated/grammar.ts"],"names":[],"mappings":"AAAA;;;gFAGgF;AAEhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAIhE,eAAO,MAAM,qBAAqB,QAAO,OAAgz5D,CAAC"}
File diff suppressed because one or more lines are too long
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"grammar.js","sourceRoot":"","sources":["../../../src/grammar/generated/grammar.ts"],"names":[],"mappings":"AAAA;;;gFAGgF;AAGhF,OAAO,EAAE,mBAAmB,EAAE,MAAM,+BAA+B,CAAC;AAEpE,IAAI,2BAAgD,CAAC;AACrD,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAY,EAAE,CAAC,2BAA2B,IAAI,CAAC,2BAA2B,GAAG,mBAAmB,CAAC,it5DAAit5D,CAAC,CAAC,CAAC"}
+17
View File
@@ -0,0 +1,17 @@
/******************************************************************************
* This file was generated by langium-cli 4.2.1.
* DO NOT EDIT MANUALLY!
******************************************************************************/
import type { Module } from '../../dependency-injection.js';
import type { LangiumSharedCoreServices, LangiumCoreServices, LangiumGeneratedCoreServices, LangiumGeneratedSharedCoreServices } from '../../services.js';
import type { IParserConfig } from '../../parser/parser-config.js';
export declare const LangiumGrammarLanguageMetaData: {
readonly languageId: "langium";
readonly fileExtensions: readonly [".langium"];
readonly caseInsensitive: false;
readonly mode: "production";
};
export declare const LangiumGrammarParserConfig: IParserConfig;
export declare const LangiumGrammarGeneratedSharedModule: Module<LangiumSharedCoreServices, LangiumGeneratedSharedCoreServices>;
export declare const LangiumGrammarGeneratedModule: Module<LangiumCoreServices, LangiumGeneratedCoreServices>;
//# sourceMappingURL=module.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../../src/grammar/generated/module.ts"],"names":[],"mappings":"AAAA;;;gFAGgF;AAIhF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,+BAA+B,CAAC;AAC5D,OAAO,KAAK,EAAE,yBAAyB,EAAE,mBAAmB,EAAE,4BAA4B,EAAE,kCAAkC,EAAE,MAAM,mBAAmB,CAAC;AAC1J,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAGnE,eAAO,MAAM,8BAA8B;;;;;CAKN,CAAC;AAEtC,eAAO,MAAM,0BAA0B,EAAE,aAExC,CAAC;AAEF,eAAO,MAAM,mCAAmC,EAAE,MAAM,CAAC,yBAAyB,EAAE,kCAAkC,CAErH,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,MAAM,CAAC,mBAAmB,EAAE,4BAA4B,CAMnG,CAAC"}
+26
View File
@@ -0,0 +1,26 @@
/******************************************************************************
* This file was generated by langium-cli 4.2.1.
* DO NOT EDIT MANUALLY!
******************************************************************************/
import { LangiumGrammarAstReflection } from '../../languages/generated/ast.js';
import { LangiumGrammarGrammar } from './grammar.js';
export const LangiumGrammarLanguageMetaData = {
languageId: 'langium',
fileExtensions: ['.langium'],
caseInsensitive: false,
mode: 'production'
};
export const LangiumGrammarParserConfig = {
maxLookahead: 3,
};
export const LangiumGrammarGeneratedSharedModule = {
AstReflection: () => new LangiumGrammarAstReflection()
};
export const LangiumGrammarGeneratedModule = {
Grammar: () => LangiumGrammarGrammar(),
LanguageMetaData: () => LangiumGrammarLanguageMetaData,
parser: {
ParserConfig: () => LangiumGrammarParserConfig
}
};
//# sourceMappingURL=module.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"module.js","sourceRoot":"","sources":["../../../src/grammar/generated/module.ts"],"names":[],"mappings":"AAAA;;;gFAGgF;AAGhF,OAAO,EAAE,2BAA2B,EAAE,MAAM,kCAAkC,CAAC;AAI/E,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AAErD,MAAM,CAAC,MAAM,8BAA8B,GAAG;IAC1C,UAAU,EAAE,SAAS;IACrB,cAAc,EAAE,CAAC,UAAU,CAAC;IAC5B,eAAe,EAAE,KAAK;IACtB,IAAI,EAAE,YAAY;CACe,CAAC;AAEtC,MAAM,CAAC,MAAM,0BAA0B,GAAkB;IACrD,YAAY,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,CAAC,MAAM,mCAAmC,GAA0E;IACtH,aAAa,EAAE,GAAG,EAAE,CAAC,IAAI,2BAA2B,EAAE;CACzD,CAAC;AAEF,MAAM,CAAC,MAAM,6BAA6B,GAA8D;IACpG,OAAO,EAAE,GAAG,EAAE,CAAC,qBAAqB,EAAE;IACtC,gBAAgB,EAAE,GAAG,EAAE,CAAC,8BAA8B;IACtD,MAAM,EAAE;QACJ,YAAY,EAAE,GAAG,EAAE,CAAC,0BAA0B;KACjD;CACJ,CAAC"}
+27
View File
@@ -0,0 +1,27 @@
/******************************************************************************
* Copyright 2023 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
*
* @module langium/grammar
*/
export * from './generated/grammar.js';
export * from './generated/module.js';
export * from './lsp/grammar-call-hierarchy.js';
export * from './lsp/grammar-code-actions.js';
export * from './lsp/grammar-completion-provider.js';
export * from './lsp/grammar-definition.js';
export * from './lsp/grammar-folding-ranges.js';
export * from './lsp/grammar-formatter.js';
export * from './lsp/grammar-semantic-tokens.js';
export * from './references/grammar-naming.js';
export * from './references/grammar-references.js';
export * from './references/grammar-scope.js';
export * from './validation/types-validator.js';
export * from './validation/validation-resources-collector.js';
export * from './validation/validator.js';
export * from './type-system/index.js';
export * from './langium-grammar-module.js';
export * from './internal-grammar-util.js';
export * from './ast-reflection-interpreter.js';
//# sourceMappingURL=index.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/grammar/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAMH,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sCAAsC,CAAC;AACrD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,oCAAoC,CAAC;AACnD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iCAAiC,CAAC"}
+30
View File
@@ -0,0 +1,30 @@
/******************************************************************************
* Copyright 2023 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
*
* @module langium/grammar
*/
// This file contains Langium grammar language internals.
// It is not supposed to be exported with the general `langium` export.
// Instead, it is available from `langium/grammar`.
export * from './generated/grammar.js';
export * from './generated/module.js';
export * from './lsp/grammar-call-hierarchy.js';
export * from './lsp/grammar-code-actions.js';
export * from './lsp/grammar-completion-provider.js';
export * from './lsp/grammar-definition.js';
export * from './lsp/grammar-folding-ranges.js';
export * from './lsp/grammar-formatter.js';
export * from './lsp/grammar-semantic-tokens.js';
export * from './references/grammar-naming.js';
export * from './references/grammar-references.js';
export * from './references/grammar-scope.js';
export * from './validation/types-validator.js';
export * from './validation/validation-resources-collector.js';
export * from './validation/validator.js';
export * from './type-system/index.js';
export * from './langium-grammar-module.js';
export * from './internal-grammar-util.js';
export * from './ast-reflection-interpreter.js';
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/grammar/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,yDAAyD;AACzD,uEAAuE;AACvE,mDAAmD;AAEnD,cAAc,wBAAwB,CAAC;AACvC,cAAc,uBAAuB,CAAC;AACtC,cAAc,iCAAiC,CAAC;AAChD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,sCAAsC,CAAC;AACrD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,iCAAiC,CAAC;AAChD,cAAc,4BAA4B,CAAC;AAC3C,cAAc,kCAAkC,CAAC;AACjD,cAAc,gCAAgC,CAAC;AAC/C,cAAc,oCAAoC,CAAC;AACnD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,iCAAiC,CAAC;AAChD,cAAc,gDAAgD,CAAC;AAC/D,cAAc,2BAA2B,CAAC;AAC1C,cAAc,wBAAwB,CAAC;AACvC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,4BAA4B,CAAC;AAC3C,cAAc,iCAAiC,CAAC"}
+35
View File
@@ -0,0 +1,35 @@
/******************************************************************************
* Copyright 2021-2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { URI } from '../utils/uri-utils.js';
import type { LangiumDocuments } from '../workspace/documents.js';
import * as ast from '../languages/generated/ast.js';
import type { LangiumGrammarServices } from './langium-grammar-module.js';
import type { IParserConfig } from '../parser/parser-config.js';
import type { LanguageMetaData } from '../languages/language-meta-data.js';
import type { Module } from '../dependency-injection.js';
import type { LangiumServices, LangiumSharedServices } from '../lsp/lsp-services.js';
export declare function hasDataTypeReturn(rule: ast.ParserRule): boolean;
export declare function isStringGrammarType(type: ast.AbstractType | ast.TypeDefinition): boolean;
export declare function getTypeNameWithoutError(type?: ast.AbstractType | ast.Action): string | undefined;
export declare function resolveImportUri(imp: ast.GrammarImport): URI | undefined;
export declare function resolveImport(documents: LangiumDocuments, imp: ast.GrammarImport): ast.Grammar | undefined;
export declare function resolveTransitiveImports(documents: LangiumDocuments, grammar: ast.Grammar): ast.Grammar[];
export declare function resolveTransitiveImports(documents: LangiumDocuments, importNode: ast.GrammarImport): ast.Grammar[];
export declare function extractAssignments(element: ast.AbstractElement): ast.Assignment[];
export declare function isPrimitiveGrammarType(type: string): boolean;
/**
* Create an instance of the language services for the given grammar. This function is very
* useful when the grammar is defined on-the-fly, for example in tests of the Langium framework.
*/
export declare function createServicesForGrammar<L extends LangiumServices = LangiumServices, S extends LangiumSharedServices = LangiumSharedServices>(config: {
grammar: string | ast.Grammar;
grammarServices?: LangiumGrammarServices;
parserConfig?: IParserConfig;
languageMetaData?: LanguageMetaData;
module?: Module<L, unknown>;
sharedModule?: Module<S, unknown>;
}): Promise<L>;
//# sourceMappingURL=internal-grammar-util.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"internal-grammar-util.d.ts","sourceRoot":"","sources":["../../src/grammar/internal-grammar-util.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,EAAE,GAAG,EAAE,MAAM,uBAAuB,CAAC;AAC5C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAElE,OAAO,KAAK,GAAG,MAAM,+BAA+B,CAAC;AAGrD,OAAO,KAAK,EAAE,sBAAsB,EAAC,MAAM,6BAA6B,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,4BAA4B,CAAC;AAChE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oCAAoC,CAAC;AAC3E,OAAO,KAAK,EAAE,MAAM,EAAC,MAAM,4BAA4B,CAAC;AAGxD,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAC;AAMrF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,GAAG,CAAC,UAAU,GAAG,OAAO,CAG/D;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,GAAG,CAAC,YAAY,GAAG,GAAG,CAAC,cAAc,GAAG,OAAO,CAExF;AAmCD,wBAAgB,uBAAuB,CAAC,IAAI,CAAC,EAAE,GAAG,CAAC,YAAY,GAAG,GAAG,CAAC,MAAM,GAAG,MAAM,GAAG,SAAS,CAShG;AAED,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,GAAG,CAAC,aAAa,GAAG,GAAG,GAAG,SAAS,CAUxE;AAED,wBAAgB,aAAa,CAAC,SAAS,EAAE,gBAAgB,EAAE,GAAG,EAAE,GAAG,CAAC,aAAa,GAAG,GAAG,CAAC,OAAO,GAAG,SAAS,CAc1G;AAED,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,gBAAgB,EAAE,OAAO,EAAE,GAAG,CAAC,OAAO,GAAG,GAAG,CAAC,OAAO,EAAE,CAAA;AAC1G,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,gBAAgB,EAAE,UAAU,EAAE,GAAG,CAAC,aAAa,GAAG,GAAG,CAAC,OAAO,EAAE,CAAA;AA2CnH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,GAAG,CAAC,eAAe,GAAG,GAAG,CAAC,UAAU,EAAE,CAYjF;AAID,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;GAGG;AACH,wBAAsB,wBAAwB,CAAC,CAAC,SAAS,eAAe,GAAG,eAAe,EAAE,CAAC,SAAS,qBAAqB,GAAG,qBAAqB,EAAE,MAAM,EAAE;IACzJ,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC;IAC9B,eAAe,CAAC,EAAE,sBAAsB,CAAC;IACzC,YAAY,CAAC,EAAE,aAAa,CAAC;IAC7B,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IACpC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,CAAA;CACpC,GAAG,OAAO,CAAC,CAAC,CAAC,CAkCb"}
+198
View File
@@ -0,0 +1,198 @@
/******************************************************************************
* Copyright 2021-2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { URI } from '../utils/uri-utils.js';
import * as ast from '../languages/generated/ast.js';
import { getDocument } from '../utils/ast-utils.js';
import { UriUtils } from '../utils/uri-utils.js';
import { createLangiumGrammarServices } from './langium-grammar-module.js';
import { inject } from '../dependency-injection.js';
import { createDefaultModule, createDefaultSharedModule } from '../lsp/default-lsp-module.js';
import { EmptyFileSystem } from '../workspace/file-system-provider.js';
import { interpretAstReflection } from './ast-reflection-interpreter.js';
import { getTypeName, isDataType } from '../utils/grammar-utils.js';
export function hasDataTypeReturn(rule) {
const returnType = rule.returnType?.ref;
return rule.dataType !== undefined || (ast.isType(returnType) && isDataType(returnType));
}
export function isStringGrammarType(type) {
return isStringTypeInternal(type, new Set());
}
function isStringTypeInternal(type, visited) {
if (visited.has(type)) {
return true;
}
else {
visited.add(type);
}
if (ast.isParserRule(type)) {
if (type.dataType) {
return type.dataType === 'string';
}
if (type.returnType?.ref) {
return isStringTypeInternal(type.returnType.ref, visited);
}
}
else if (ast.isType(type)) {
return isStringTypeInternal(type.type, visited);
}
else if (ast.isArrayType(type)) {
return false;
}
else if (ast.isReferenceType(type)) {
return false;
}
else if (ast.isUnionType(type)) {
return type.types.every(e => isStringTypeInternal(e, visited));
}
else if (ast.isSimpleType(type)) {
if (type.primitiveType === 'string') {
return true;
}
else if (type.stringType) {
return true;
}
else if (type.typeRef?.ref) {
return isStringTypeInternal(type.typeRef.ref, visited);
}
}
return false;
}
export function getTypeNameWithoutError(type) {
if (!type) {
return undefined;
}
try {
return getTypeName(type);
}
catch {
return undefined;
}
}
export function resolveImportUri(imp) {
if (imp.path === undefined || imp.path.length === 0) {
return undefined;
}
const dirUri = UriUtils.dirname(getDocument(imp).uri);
let grammarPath = imp.path;
if (!grammarPath.endsWith('.langium')) {
grammarPath += '.langium';
}
return UriUtils.resolvePath(dirUri, grammarPath);
}
export function resolveImport(documents, imp) {
const resolvedUri = resolveImportUri(imp);
if (!resolvedUri) {
return undefined;
}
const resolvedDocument = documents.getDocument(resolvedUri);
if (!resolvedDocument) {
return undefined;
}
const node = resolvedDocument.parseResult.value;
if (ast.isGrammar(node)) {
return node;
}
return undefined;
}
export function resolveTransitiveImports(documents, grammarOrImport) {
if (ast.isGrammarImport(grammarOrImport)) {
const resolvedGrammar = resolveImport(documents, grammarOrImport);
if (resolvedGrammar) {
const transitiveGrammars = resolveTransitiveImportsInternal(documents, resolvedGrammar);
transitiveGrammars.push(resolvedGrammar);
return transitiveGrammars;
}
return [];
}
else {
return resolveTransitiveImportsInternal(documents, grammarOrImport);
}
}
/**
* Resolves all transitively imported grammars of the given grammar.
* In case of grammars importing each other in circular way, each grammar is remembered only once.
* The initial grammar will never be part of the result.
* @param documents the service to get all available Langium documents
* @param grammar the grammar to transitively resolve its imported grammars
* @param initialGrammar Even if the initial grammar transitively imports itself in circular way again, the initial grammar will not be part of the result!
* @param visited since grammars might import each other in circular way, this set remembers the already visited gramar URIs to prevent loops
* @param grammars the result set of already imported and resolved grammars
* @returns the collected `grammars` in a new array
*/
function resolveTransitiveImportsInternal(documents, grammar, initialGrammar = grammar, visited = new Set(), grammars = new Set()) {
const doc = getDocument(grammar);
if (initialGrammar !== grammar) {
grammars.add(grammar);
}
if (!visited.has(doc.uri)) {
visited.add(doc.uri);
for (const imp of grammar.imports) {
const importedGrammar = resolveImport(documents, imp);
if (importedGrammar) {
resolveTransitiveImportsInternal(documents, importedGrammar, initialGrammar, visited, grammars);
}
}
}
return Array.from(grammars);
}
export function extractAssignments(element) {
if (ast.isAssignment(element)) {
return [element];
}
else if (ast.isAlternatives(element) || ast.isGroup(element) || ast.isUnorderedGroup(element)) {
return element.elements.flatMap(e => extractAssignments(e));
}
else if (ast.isRuleCall(element) && element.rule.ref) {
if (ast.isInfixRule(element.rule.ref)) {
return [];
}
return extractAssignments(element.rule.ref.definition);
}
return [];
}
const primitiveTypes = ['string', 'number', 'boolean', 'Date', 'bigint'];
export function isPrimitiveGrammarType(type) {
return primitiveTypes.includes(type);
}
/**
* Create an instance of the language services for the given grammar. This function is very
* useful when the grammar is defined on-the-fly, for example in tests of the Langium framework.
*/
export async function createServicesForGrammar(config) {
const grammarServices = config.grammarServices ?? createLangiumGrammarServices(EmptyFileSystem).grammar;
const uri = URI.parse('memory:/grammar.langium');
const factory = grammarServices.shared.workspace.LangiumDocumentFactory;
const grammarDocument = typeof config.grammar === 'string'
? factory.fromString(config.grammar, uri)
: getDocument(config.grammar);
const grammarNode = grammarDocument.parseResult.value;
const documentBuilder = grammarServices.shared.workspace.DocumentBuilder;
await documentBuilder.build([grammarDocument], { validation: false });
const parserConfig = config.parserConfig ?? {
skipValidations: false
};
const languageMetaData = config.languageMetaData ?? {
caseInsensitive: false,
fileExtensions: ['.txt'],
languageId: grammarNode.name ?? 'UNKNOWN',
mode: 'development'
};
const generatedSharedModule = {
AstReflection: () => interpretAstReflection(grammarNode),
};
const generatedModule = {
Grammar: () => grammarNode,
LanguageMetaData: () => languageMetaData,
parser: {
ParserConfig: () => parserConfig
}
};
const shared = inject(createDefaultSharedModule(EmptyFileSystem), generatedSharedModule, config.sharedModule);
const services = inject(createDefaultModule({ shared }), generatedModule, config.module);
shared.ServiceRegistry.register(services);
return services;
}
//# sourceMappingURL=internal-grammar-util.js.map
File diff suppressed because one or more lines are too long
+34
View File
@@ -0,0 +1,34 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { Module } from '../dependency-injection.js';
import type { DeepPartial } from '../services.js';
import type { LangiumServices, LangiumSharedServices, PartialLangiumServices, PartialLangiumSharedServices } from '../lsp/lsp-services.js';
import { type DefaultSharedModuleContext } from '../lsp/default-lsp-module.js';
import { LangiumGrammarValidator } from './validation/validator.js';
import { LangiumGrammarValidationResourcesCollector } from './validation/validation-resources-collector.js';
import { LangiumGrammarTypesValidator } from './validation/types-validator.js';
export type LangiumGrammarAddedServices = {
validation: {
LangiumGrammarValidator: LangiumGrammarValidator;
ValidationResourcesCollector: LangiumGrammarValidationResourcesCollector;
LangiumGrammarTypesValidator: LangiumGrammarTypesValidator;
};
};
export type LangiumGrammarServices = LangiumServices & LangiumGrammarAddedServices;
export declare const LangiumGrammarModule: Module<LangiumGrammarServices, PartialLangiumServices & LangiumGrammarAddedServices>;
/**
* Creates Langium grammar services, enriched with LSP functionality
*
* @param context Shared module context, used to create additional shared modules
* @param sharedModule Existing shared module to inject together with new shared services
* @param module Additional/modified service implementations for the language services
* @returns Shared services enriched with LSP services + Grammar services, per usual
*/
export declare function createLangiumGrammarServices(context: DefaultSharedModuleContext, sharedModule?: Module<LangiumSharedServices, PartialLangiumSharedServices>, module?: Module<LangiumGrammarServices, DeepPartial<LangiumServices & LangiumGrammarAddedServices>>): {
shared: LangiumSharedServices;
grammar: LangiumGrammarServices;
};
//# sourceMappingURL=langium-grammar-module.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"langium-grammar-module.d.ts","sourceRoot":"","sources":["../../src/grammar/langium-grammar-module.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACzD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,eAAe,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,4BAA4B,EAAE,MAAM,wBAAwB,CAAC;AAI3I,OAAO,EAAE,KAAK,0BAA0B,EAAkD,MAAM,8BAA8B,CAAC;AAI/H,OAAO,EAAE,uBAAuB,EAA4B,MAAM,2BAA2B,CAAC;AAU9F,OAAO,EAAE,0CAA0C,EAAE,MAAM,gDAAgD,CAAC;AAC5G,OAAO,EAAE,4BAA4B,EAAgC,MAAM,iCAAiC,CAAC;AAG7G,MAAM,MAAM,2BAA2B,GAAG;IACtC,UAAU,EAAE;QACR,uBAAuB,EAAE,uBAAuB,CAAC;QACjD,4BAA4B,EAAE,0CAA0C,CAAC;QACzE,4BAA4B,EAAE,4BAA4B,CAAC;KAC9D,CAAA;CACJ,CAAA;AAED,MAAM,MAAM,sBAAsB,GAAG,eAAe,GAAG,2BAA2B,CAAC;AAEnF,eAAO,MAAM,oBAAoB,EAAE,MAAM,CAAC,sBAAsB,EAAE,sBAAsB,GAAG,2BAA2B,CAsBrH,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,0BAA0B,EAC5E,YAAY,CAAC,EAAE,MAAM,CAAC,qBAAqB,EAAE,4BAA4B,CAAC,EAC1E,MAAM,CAAC,EAAE,MAAM,CAAC,sBAAsB,EAAE,WAAW,CAAC,eAAe,GAAG,2BAA2B,CAAC,CAAC,GAAG;IACtG,MAAM,EAAE,qBAAqB,CAAC;IAC9B,OAAO,EAAE,sBAAsB,CAAA;CAClC,CAyBA"}
+77
View File
@@ -0,0 +1,77 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { LangiumGrammarTypeHierarchyProvider } from './lsp/grammar-type-hierarchy.js';
import { createDefaultModule, createDefaultSharedModule } from '../lsp/default-lsp-module.js';
import { inject } from '../dependency-injection.js';
import { LangiumGrammarGeneratedModule, LangiumGrammarGeneratedSharedModule } from './generated/module.js';
import { LangiumGrammarScopeComputation, LangiumGrammarScopeProvider } from './references/grammar-scope.js';
import { LangiumGrammarValidator, registerValidationChecks } from './validation/validator.js';
import { LangiumGrammarCodeActionProvider } from './lsp/grammar-code-actions.js';
import { LangiumGrammarCompletionProvider } from './lsp/grammar-completion-provider.js';
import { LangiumGrammarFoldingRangeProvider } from './lsp/grammar-folding-ranges.js';
import { LangiumGrammarFormatter } from './lsp/grammar-formatter.js';
import { LangiumGrammarSemanticTokenProvider } from './lsp/grammar-semantic-tokens.js';
import { LangiumGrammarNameProvider } from './references/grammar-naming.js';
import { LangiumGrammarReferences } from './references/grammar-references.js';
import { LangiumGrammarDefinitionProvider } from './lsp/grammar-definition.js';
import { LangiumGrammarCallHierarchyProvider } from './lsp/grammar-call-hierarchy.js';
import { LangiumGrammarValidationResourcesCollector } from './validation/validation-resources-collector.js';
import { LangiumGrammarTypesValidator, registerTypeValidationChecks } from './validation/types-validator.js';
import { DocumentState } from '../workspace/documents.js';
export const LangiumGrammarModule = {
validation: {
LangiumGrammarValidator: (services) => new LangiumGrammarValidator(services),
ValidationResourcesCollector: (services) => new LangiumGrammarValidationResourcesCollector(services),
LangiumGrammarTypesValidator: () => new LangiumGrammarTypesValidator(),
},
lsp: {
FoldingRangeProvider: (services) => new LangiumGrammarFoldingRangeProvider(services),
CodeActionProvider: (services) => new LangiumGrammarCodeActionProvider(services),
SemanticTokenProvider: (services) => new LangiumGrammarSemanticTokenProvider(services),
Formatter: () => new LangiumGrammarFormatter(),
DefinitionProvider: (services) => new LangiumGrammarDefinitionProvider(services),
CallHierarchyProvider: (services) => new LangiumGrammarCallHierarchyProvider(services),
TypeHierarchyProvider: (services) => new LangiumGrammarTypeHierarchyProvider(services),
CompletionProvider: (services) => new LangiumGrammarCompletionProvider(services)
},
references: {
ScopeComputation: (services) => new LangiumGrammarScopeComputation(services),
ScopeProvider: (services) => new LangiumGrammarScopeProvider(services),
References: (services) => new LangiumGrammarReferences(services),
NameProvider: () => new LangiumGrammarNameProvider()
}
};
/**
* Creates Langium grammar services, enriched with LSP functionality
*
* @param context Shared module context, used to create additional shared modules
* @param sharedModule Existing shared module to inject together with new shared services
* @param module Additional/modified service implementations for the language services
* @returns Shared services enriched with LSP services + Grammar services, per usual
*/
export function createLangiumGrammarServices(context, sharedModule, module) {
const shared = inject(createDefaultSharedModule(context), LangiumGrammarGeneratedSharedModule, sharedModule);
const grammar = inject(createDefaultModule({ shared }), LangiumGrammarGeneratedModule, LangiumGrammarModule, module);
addTypeCollectionPhase(shared, grammar);
shared.ServiceRegistry.register(grammar);
registerValidationChecks(grammar);
registerTypeValidationChecks(grammar);
if (!context.connection) {
// We don't run inside a language server
// Therefore, initialize the configuration provider instantly
shared.workspace.ConfigurationProvider.initialized({});
}
return { shared, grammar };
}
function addTypeCollectionPhase(sharedServices, grammarServices) {
const documentBuilder = sharedServices.workspace.DocumentBuilder;
documentBuilder.onDocumentPhase(DocumentState.IndexedReferences, async (document) => {
const typeCollector = grammarServices.validation.ValidationResourcesCollector;
const grammar = document.parseResult.value;
document.validationResources = typeCollector.collectValidationResources(grammar);
});
}
//# sourceMappingURL=langium-grammar-module.js.map
@@ -0,0 +1 @@
{"version":3,"file":"langium-grammar-module.js","sourceRoot":"","sources":["../../src/grammar/langium-grammar-module.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,15 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { CallHierarchyIncomingCall, CallHierarchyOutgoingCall } from 'vscode-languageserver';
import type { AstNode } from '../../syntax-tree.js';
import type { Stream } from '../../utils/stream.js';
import type { ReferenceDescription } from '../../workspace/ast-descriptions.js';
import { AbstractCallHierarchyProvider } from '../../lsp/call-hierarchy-provider.js';
export declare class LangiumGrammarCallHierarchyProvider extends AbstractCallHierarchyProvider {
protected getIncomingCalls(node: AstNode, references: Stream<ReferenceDescription>): CallHierarchyIncomingCall[] | undefined;
protected getOutgoingCalls(node: AstNode): CallHierarchyOutgoingCall[] | undefined;
}
//# sourceMappingURL=grammar-call-hierarchy.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-call-hierarchy.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-call-hierarchy.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,yBAAyB,EAAE,yBAAyB,EAAS,MAAM,uBAAuB,CAAC;AACzG,OAAO,KAAK,EAAE,OAAO,EAAW,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAEhF,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AAKrF,qBAAa,mCAAoC,SAAQ,6BAA6B;IAElF,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,oBAAoB,CAAC,GAAG,yBAAyB,EAAE,GAAG,SAAS;IAiD5H,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,yBAAyB,EAAE,GAAG,SAAS;CAmErF"}
+128
View File
@@ -0,0 +1,128 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { SymbolKind } from 'vscode-languageserver';
import { AbstractCallHierarchyProvider } from '../../lsp/call-hierarchy-provider.js';
import { getContainerOfType, getDocument, streamAllContents } from '../../utils/ast-utils.js';
import { findLeafNodeAtOffset } from '../../utils/cst-utils.js';
import { isAbstractParserRule, isInfixRule, isParserRule, isRuleCall } from '../../languages/generated/ast.js';
export class LangiumGrammarCallHierarchyProvider extends AbstractCallHierarchyProvider {
getIncomingCalls(node, references) {
if (!isAbstractParserRule(node)) {
return undefined;
}
// This map is used to group incoming calls to avoid duplicates.
const uniqueRules = new Map();
references.forEach(ref => {
const doc = this.documents.getDocument(ref.sourceUri);
if (!doc) {
return;
}
const rootNode = doc.parseResult.value;
if (!rootNode.$cstNode) {
return;
}
const targetNode = findLeafNodeAtOffset(rootNode.$cstNode, ref.segment.offset);
if (!targetNode) {
return;
}
const parserRule = getContainerOfType(targetNode.astNode, isAbstractParserRule);
if (!parserRule || !parserRule.$cstNode) {
return;
}
const nameNode = this.nameProvider.getNameNode(parserRule);
if (!nameNode) {
return;
}
const refDocUri = ref.sourceUri.toString();
const ruleId = refDocUri + '@' + nameNode.text;
uniqueRules.has(ruleId) ?
uniqueRules.set(ruleId, { parserRule: parserRule.$cstNode, nameNode, targetNodes: [...uniqueRules.get(ruleId).targetNodes, targetNode], docUri: refDocUri })
: uniqueRules.set(ruleId, { parserRule: parserRule.$cstNode, nameNode, targetNodes: [targetNode], docUri: refDocUri });
});
if (uniqueRules.size === 0) {
return undefined;
}
return Array.from(uniqueRules.values()).map(rule => ({
from: {
kind: SymbolKind.Method,
name: rule.nameNode.text,
range: rule.parserRule.range,
selectionRange: rule.nameNode.range,
uri: rule.docUri
},
fromRanges: rule.targetNodes.map(node => node.range)
}));
}
getOutgoingCalls(node) {
if (isParserRule(node)) {
const ruleCalls = streamAllContents(node).filter(isRuleCall).toArray();
// This map is used to group outgoing calls to avoid duplicates.
const uniqueRules = new Map();
ruleCalls.forEach(ruleCall => {
const cstNode = ruleCall.$cstNode;
if (!cstNode) {
return;
}
const refCstNode = ruleCall.rule.ref?.$cstNode;
if (!refCstNode) {
return;
}
const refNameNode = this.nameProvider.getNameNode(refCstNode.astNode);
if (!refNameNode) {
return;
}
const refDocUri = getDocument(refCstNode.astNode).uri.toString();
const ruleId = refDocUri + '@' + refNameNode.text;
uniqueRules.has(ruleId) ?
uniqueRules.set(ruleId, { refCstNode: refCstNode, to: refNameNode, from: [...uniqueRules.get(ruleId).from, cstNode.range], docUri: refDocUri })
: uniqueRules.set(ruleId, { refCstNode: refCstNode, to: refNameNode, from: [cstNode.range], docUri: refDocUri });
});
if (uniqueRules.size === 0) {
return undefined;
}
return Array.from(uniqueRules.values()).map(rule => ({
to: {
kind: SymbolKind.Method,
name: rule.to.text,
range: rule.refCstNode.range,
selectionRange: rule.to.range,
uri: rule.docUri
},
fromRanges: rule.from
}));
}
else if (isInfixRule(node)) {
const ruleCall = node.call;
const cstNode = ruleCall.$cstNode;
if (!cstNode) {
return undefined;
}
const refCstNode = ruleCall.rule.ref?.$cstNode;
if (!refCstNode) {
return undefined;
}
const refNameNode = this.nameProvider.getNameNode(refCstNode.astNode);
if (!refNameNode) {
return undefined;
}
const refDocUri = getDocument(refCstNode.astNode).uri.toString();
return [{
to: {
kind: SymbolKind.Method,
name: refNameNode.text,
range: refCstNode.range,
selectionRange: refNameNode.range,
uri: refDocUri
},
fromRanges: [cstNode.range]
}];
}
else {
return undefined;
}
}
}
//# sourceMappingURL=grammar-call-hierarchy.js.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-call-hierarchy.js","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-call-hierarchy.ts"],"names":[],"mappings":"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"}
+42
View File
@@ -0,0 +1,42 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { CodeActionParams } from 'vscode-languageserver-protocol';
import type { CodeAction, Command } from 'vscode-languageserver-types';
import * as ast from '../../languages/generated/ast.js';
import type { CodeActionProvider } from '../../lsp/code-action.js';
import type { LangiumServices } from '../../lsp/lsp-services.js';
import type { AstReflection } from '../../syntax-tree.js';
import type { MaybePromise } from '../../utils/promise-utils.js';
import type { LangiumDocument } from '../../workspace/documents.js';
import type { IndexManager } from '../../workspace/index-manager.js';
export declare class LangiumGrammarCodeActionProvider implements CodeActionProvider {
protected readonly reflection: AstReflection;
protected readonly indexManager: IndexManager;
constructor(services: LangiumServices);
getCodeActions(document: LangiumDocument<ast.Grammar>, params: CodeActionParams): MaybePromise<Array<Command | CodeAction>>;
private createCodeActions;
/**
* Adds missing returns for parser rule
*/
private fixMissingReturns;
private fixInvalidReturnsInfers;
private fixMissingInfer;
private fixMissingCrossRefTerminal;
private fixSuperfluousInfer;
private isRuleReplaceable;
private replaceRule;
private isDefinitionReplaceable;
private replaceDefinition;
private replaceParserRuleByTypeDeclaration;
private fixUnnecessaryFileExtension;
private makeUpperCase;
private addEntryKeyword;
private fixRegexTokens;
private fixCrossRefSyntax;
private addNewRule;
private lookInGlobalScope;
}
//# sourceMappingURL=grammar-code-actions.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-code-actions.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-code-actions.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAIhF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAY,MAAM,6BAA6B,CAAC;AACjF,OAAO,KAAK,GAAG,MAAM,kCAAkC,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAA4B,MAAM,sBAAsB,CAAC;AAGpF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAOjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAGrE,qBAAa,gCAAiC,YAAW,kBAAkB;IAEvE,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC;IAC7C,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;gBAElC,QAAQ,EAAE,eAAe;IAKrC,cAAc,CAAC,QAAQ,EAAE,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,gBAAgB,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC,CAAC;IAS3H,OAAO,CAAC,iBAAiB;IAmDzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAoBzB,OAAO,CAAC,uBAAuB;IAqB/B,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,0BAA0B;IAwBlC,OAAO,CAAC,mBAAmB;IAoB3B,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,uBAAuB;IAS/B,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,kCAAkC;IA8B1C,OAAO,CAAC,2BAA2B;IAwBnC,OAAO,CAAC,aAAa;IAwBrB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,cAAc;IA4BtB,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,UAAU;IA6BlB,OAAO,CAAC,iBAAiB;CA0E5B"}
+458
View File
@@ -0,0 +1,458 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { CodeActionKind } from 'vscode-languageserver';
import * as ast from '../../languages/generated/ast.js';
import { getContainerOfType } from '../../utils/ast-utils.js';
import { findLeafNodeAtOffset } from '../../utils/cst-utils.js';
import { escapeRegExp } from '../../utils/regexp-utils.js';
import { UriUtils } from '../../utils/uri-utils.js';
import { DocumentValidator } from '../../validation/document-validator.js';
import { IssueCodes } from '../validation/validator.js';
export class LangiumGrammarCodeActionProvider {
constructor(services) {
this.reflection = services.shared.AstReflection;
this.indexManager = services.shared.workspace.IndexManager;
}
getCodeActions(document, params) {
const result = [];
const acceptor = (ca) => ca && result.push(ca);
for (const diagnostic of params.context.diagnostics) {
this.createCodeActions(diagnostic, document, acceptor);
}
return result;
}
createCodeActions(diagnostic, document, accept) {
switch (diagnostic.data?.code) {
case IssueCodes.GrammarNameUppercase:
case IssueCodes.RuleNameUppercase:
accept(this.makeUpperCase(diagnostic, document));
break;
case IssueCodes.UseRegexTokens:
accept(this.fixRegexTokens(diagnostic, document));
break;
case IssueCodes.EntryRuleTokenSyntax:
accept(this.addEntryKeyword(diagnostic, document));
break;
case IssueCodes.CrossRefTokenSyntax:
accept(this.fixCrossRefSyntax(diagnostic, document));
break;
case IssueCodes.ParserRuleToTypeDecl:
accept(this.replaceParserRuleByTypeDeclaration(diagnostic, document));
break;
case IssueCodes.UnnecessaryFileExtension:
accept(this.fixUnnecessaryFileExtension(diagnostic, document));
break;
case IssueCodes.MissingReturns:
accept(this.fixMissingReturns(diagnostic, document));
break;
case IssueCodes.InvalidInfers:
case IssueCodes.InvalidReturns:
accept(this.fixInvalidReturnsInfers(diagnostic, document));
break;
case IssueCodes.MissingInfer:
accept(this.fixMissingInfer(diagnostic, document));
break;
case IssueCodes.MissingCrossRefTerminal:
accept(this.fixMissingCrossRefTerminal(diagnostic, document));
break;
case IssueCodes.SuperfluousInfer:
accept(this.fixSuperfluousInfer(diagnostic, document));
break;
case DocumentValidator.LinkingError: {
const data = diagnostic.data;
if (data && data.containerType === 'RuleCall' && data.property === 'rule') {
accept(this.addNewRule(diagnostic, data, document));
}
if (data) {
this.lookInGlobalScope(diagnostic, data, document).forEach(accept);
}
break;
}
}
return undefined;
}
/**
* Adds missing returns for parser rule
*/
fixMissingReturns(diagnostic, document) {
const text = document.textDocument.getText(diagnostic.range);
if (text) {
return {
title: `Add explicit return type for parser rule ${text}`,
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
edit: {
changes: {
[document.textDocument.uri]: [{
range: diagnostic.range,
newText: `${text} returns ${text}` // suggestion adds missing 'return'
}]
}
}
};
}
return undefined;
}
fixInvalidReturnsInfers(diagnostic, document) {
const data = diagnostic.data;
if (data && data.actionSegment) {
const text = document.textDocument.getText(data.actionSegment.range);
return {
title: `Correct ${text} usage`,
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
edit: {
changes: {
[document.textDocument.uri]: [{
range: data.actionSegment.range,
newText: text === 'infers' ? 'returns' : 'infers'
}]
}
}
};
}
return undefined;
}
fixMissingInfer(diagnostic, document) {
const data = diagnostic.data;
if (data && data.actionSegment) {
return {
title: "Correct 'infer' usage",
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
edit: {
changes: {
[document.textDocument.uri]: [{
range: {
start: data.actionSegment.range.end,
end: data.actionSegment.range.end
},
newText: 'infer '
}]
}
}
};
}
return undefined;
}
fixMissingCrossRefTerminal(diagnostic, document) {
const grammar = document.parseResult.value;
const idTerminal = grammar.rules.find(rule => ast.isTerminalRule(rule) && rule.name === 'ID');
if (idTerminal) {
return {
title: 'Use ID token to resolve cross-reference',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
edit: {
changes: {
[document.textDocument.uri]: [{
range: {
start: diagnostic.range.end,
end: diagnostic.range.end
},
newText: ':ID'
}]
}
}
};
}
return undefined;
}
fixSuperfluousInfer(diagnostic, document) {
const data = diagnostic.data;
if (data && data.actionRange) {
return {
title: "Remove the 'infer' keyword",
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
edit: {
changes: {
[document.textDocument.uri]: [{
range: data.actionRange,
newText: ''
}]
}
}
};
}
return undefined;
}
isRuleReplaceable(rule) {
/** at the moment, only "pure" parser rules are supported:
* - supported are only Alternatives (recursively) and "infers"
* - "returns" is not relevant, since cross-references would not refer to the parser rule, but to its "return type" instead
*/
return !rule.fragment && !rule.entry && rule.parameters.length === 0 && !rule.returnType && !rule.dataType;
}
replaceRule(rule) {
const type = rule.inferredType ?? rule;
return type.name;
}
isDefinitionReplaceable(node) {
if (ast.isRuleCall(node)) {
return node.arguments.length === 0 && ast.isParserRule(node.rule.ref) && this.isRuleReplaceable(node.rule.ref);
}
if (ast.isAlternatives(node)) {
return node.elements.every(child => this.isDefinitionReplaceable(child));
}
return false;
}
replaceDefinition(node) {
if (ast.isRuleCall(node) && node.rule.ref) {
return node.rule.ref.name;
}
if (ast.isAlternatives(node)) {
return node.elements.map(child => this.replaceDefinition(child)).join(' | ');
}
throw new Error('missing code for ' + node);
}
replaceParserRuleByTypeDeclaration(diagnostic, document) {
const rootCst = document.parseResult.value.$cstNode;
if (rootCst) {
const offset = document.textDocument.offsetAt(diagnostic.range.start);
const cstNode = findLeafNodeAtOffset(rootCst, offset);
const rule = getContainerOfType(cstNode?.astNode, ast.isParserRule);
if (rule && rule.$cstNode) {
const isReplaceable = this.isRuleReplaceable(rule) && this.isDefinitionReplaceable(rule.definition);
if (isReplaceable) {
const newText = `type ${this.replaceRule(rule)} = ${this.replaceDefinition(rule.definition)};`;
return {
title: 'Replace with type declaration',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range: diagnostic.range,
newText
}]
}
}
};
}
}
}
return undefined;
}
fixUnnecessaryFileExtension(diagnostic, document) {
const end = { ...diagnostic.range.end };
end.character -= 1;
const start = { ...end };
start.character -= '.langium'.length;
return {
title: 'Remove file extension',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range: {
start,
end
},
newText: ''
}]
}
}
};
}
makeUpperCase(diagnostic, document) {
const range = {
start: diagnostic.range.start,
end: {
line: diagnostic.range.start.line,
character: diagnostic.range.start.character + 1
}
};
return {
title: 'First letter to upper case',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range,
newText: document.textDocument.getText(range).toUpperCase()
}]
}
}
};
}
addEntryKeyword(diagnostic, document) {
return {
title: 'Add entry keyword',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range: { start: diagnostic.range.start, end: diagnostic.range.start },
newText: 'entry '
}]
}
}
};
}
fixRegexTokens(diagnostic, document) {
const offset = document.textDocument.offsetAt(diagnostic.range.start);
const rootCst = document.parseResult.value.$cstNode;
if (rootCst) {
const cstNode = findLeafNodeAtOffset(rootCst, offset);
const container = getContainerOfType(cstNode?.astNode, ast.isCharacterRange);
if (container && container.right && container.$cstNode) {
const left = container.left.value;
const right = container.right.value;
return {
title: 'Refactor into regular expression',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range: container.$cstNode.range,
newText: `/[${escapeRegExp(left)}-${escapeRegExp(right)}]/`
}]
}
}
};
}
}
return undefined;
}
fixCrossRefSyntax(diagnostic, document) {
return {
title: "Replace '|' with ':'",
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range: diagnostic.range,
newText: ':'
}]
}
}
};
}
addNewRule(diagnostic, data, document) {
const offset = document.textDocument.offsetAt(diagnostic.range.start);
const rootCst = document.parseResult.value.$cstNode;
if (rootCst) {
const cstNode = findLeafNodeAtOffset(rootCst, offset);
const container = getContainerOfType(cstNode?.astNode, ast.isParserRule);
if (container && container.$cstNode) {
return {
title: `Add new rule '${data.refText}'`,
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: false,
edit: {
changes: {
[document.textDocument.uri]: [{
range: {
start: container.$cstNode.range.end,
end: container.$cstNode.range.end
},
newText: '\n\n' + data.refText + ':\n /* TODO implement rule */ {infer ' + data.refText + '};'
}]
}
}
};
}
}
return undefined;
}
lookInGlobalScope(diagnostic, data, document) {
const refInfo = {
container: {
$type: data.containerType
},
property: data.property,
reference: {
$refText: data.refText
}
};
const referenceType = this.reflection.getReferenceType(refInfo);
const candidates = this.indexManager.allElements(referenceType).filter(e => e.name === data.refText);
const result = [];
let shortestPathIndex = -1;
let shortestPathLength = -1;
for (const candidate of candidates) {
if (UriUtils.equals(candidate.documentUri, document.uri)) {
continue;
}
// Find an import path and a position to insert the import
const importPath = getRelativeImport(document.uri, candidate.documentUri);
let position;
let suffix = '';
const grammar = document.parseResult.value;
const nextImport = grammar.imports.find(imp => imp.path && importPath < imp.path);
if (nextImport) {
// Insert the new import alphabetically
position = nextImport.$cstNode?.range.start;
}
else if (grammar.imports.length > 0) {
// Put the new import after the last import
const rangeEnd = grammar.imports[grammar.imports.length - 1].$cstNode.range.end;
if (rangeEnd) {
position = { line: rangeEnd.line + 1, character: 0 };
}
}
else if (grammar.rules.length > 0) {
// Put the new import before the first rule
position = grammar.rules[0].$cstNode?.range.start;
suffix = '\n';
}
if (position) {
if (shortestPathIndex < 0 || importPath.length < shortestPathLength) {
shortestPathIndex = result.length;
shortestPathLength = importPath.length;
}
// Add an import declaration for the candidate in the global scope
result.push({
title: `Add import to '${importPath}'`,
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: false,
edit: {
changes: {
[document.textDocument.uri]: [{
range: {
start: position,
end: position
},
newText: `import '${importPath}'\n${suffix}`
}]
}
}
});
}
}
// Mark the code action with the shortest import path as preferred
if (shortestPathIndex >= 0) {
result[shortestPathIndex].isPreferred = true;
}
return result;
}
}
function getRelativeImport(source, target) {
const sourceDir = UriUtils.dirname(source);
let relativePath = UriUtils.relative(sourceDir, target);
if (!relativePath.startsWith('./') && !relativePath.startsWith('../')) {
relativePath = './' + relativePath;
}
if (relativePath.endsWith('.langium')) {
relativePath = relativePath.substring(0, relativePath.length - '.langium'.length);
}
return relativePath;
}
//# sourceMappingURL=grammar-code-actions.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,18 @@
/******************************************************************************
* Copyright 2023 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { NextFeature } from '../../lsp/completion/follow-element-computation.js';
import { DefaultCompletionProvider, type CompletionAcceptor, type CompletionContext } from '../../lsp/completion/completion-provider.js';
import type { MaybePromise } from '../../utils/promise-utils.js';
import type { AbstractElement } from '../../languages/generated/ast.js';
import type { LangiumServices } from '../../lsp/lsp-services.js';
export declare class LangiumGrammarCompletionProvider extends DefaultCompletionProvider {
private readonly documents;
constructor(services: LangiumServices);
protected completionFor(context: CompletionContext, next: NextFeature<AbstractElement>, acceptor: CompletionAcceptor): MaybePromise<void>;
private completeImportPath;
private getAllFiles;
}
//# sourceMappingURL=grammar-completion-provider.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-completion-provider.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-completion-provider.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAIhF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oDAAoD,CAAC;AACtF,OAAO,EAAE,yBAAyB,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AACzI,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAGjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAGxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,qBAAa,gCAAiC,SAAQ,yBAAyB;IAE3E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;gBAEvC,QAAQ,EAAE,eAAe;cAKlB,aAAa,CAAC,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,WAAW,CAAC,eAAe,CAAC,EAAE,QAAQ,EAAE,kBAAkB,GAAG,YAAY,CAAC,IAAI,CAAC;IASlJ,OAAO,CAAC,kBAAkB;IAmC1B,OAAO,CAAC,WAAW;CAmBtB"}
@@ -0,0 +1,78 @@
/******************************************************************************
* Copyright 2023 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { CompletionItemKind } from 'vscode-languageserver-types';
import { DefaultCompletionProvider } from '../../lsp/completion/completion-provider.js';
import { getContainerOfType } from '../../utils/ast-utils.js';
import { isAssignment } from '../../languages/generated/ast.js';
import { UriUtils } from '../../utils/uri-utils.js';
export class LangiumGrammarCompletionProvider extends DefaultCompletionProvider {
constructor(services) {
super(services);
this.documents = () => services.shared.workspace.LangiumDocuments;
}
completionFor(context, next, acceptor) {
const assignment = getContainerOfType(next.feature, isAssignment);
if (assignment?.feature === 'path') {
this.completeImportPath(context, acceptor);
}
else {
return super.completionFor(context, next, acceptor);
}
}
completeImportPath(context, acceptor) {
const text = context.textDocument.getText();
const existingText = text.substring(context.tokenOffset, context.offset);
let allPaths = this.getAllFiles(context.document);
let range = {
start: context.position,
end: context.position
};
if (existingText.length > 0) {
const existingPath = existingText.substring(1);
allPaths = allPaths.filter(path => path.startsWith(existingPath));
// Completely replace the current token
const start = context.textDocument.positionAt(context.tokenOffset + 1);
const end = context.textDocument.positionAt(context.tokenEndOffset - 1);
range = {
start,
end
};
}
for (const path of allPaths) {
// Only insert quotes if there is no `path` token yet.
const delimiter = existingText.length > 0 ? '' : '"';
const completionValue = `${delimiter}${path}${delimiter}`;
acceptor(context, {
label: path,
textEdit: {
newText: completionValue,
range
},
kind: CompletionItemKind.File,
sortText: '0'
});
}
}
getAllFiles(document) {
const documents = this.documents().all;
const uri = document.uri.toString();
const dirname = UriUtils.dirname(document.uri).toString();
const paths = [];
for (const doc of documents) {
if (!UriUtils.equals(doc.uri, uri)) {
const docUri = doc.uri.toString();
const uriWithoutExt = docUri.substring(0, docUri.length - UriUtils.extname(doc.uri).length);
let relativePath = UriUtils.relative(dirname, uriWithoutExt);
if (!relativePath.startsWith('.')) {
relativePath = `./${relativePath}`;
}
paths.push(relativePath);
}
}
return paths;
}
}
//# sourceMappingURL=grammar-completion-provider.js.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-completion-provider.js","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-completion-provider.ts"],"names":[],"mappings":"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"}
+20
View File
@@ -0,0 +1,20 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { DefinitionParams } from 'vscode-languageserver';
import type { LangiumServices } from '../../lsp/lsp-services.js';
import type { AstNode, LeafCstNode } from '../../syntax-tree.js';
import type { MaybePromise } from '../../utils/promise-utils.js';
import type { LangiumDocuments } from '../../workspace/documents.js';
import type { Grammar } from '../../languages/generated/ast.js';
import { LocationLink } from 'vscode-languageserver';
import { DefaultDefinitionProvider } from '../../lsp/index.js';
export declare class LangiumGrammarDefinitionProvider extends DefaultDefinitionProvider {
protected documents: LangiumDocuments;
constructor(services: LangiumServices);
protected collectLocationLinks(sourceCstNode: LeafCstNode, _params: DefinitionParams): MaybePromise<LocationLink[] | undefined>;
protected findTargetObject(importedGrammar: Grammar): AstNode | undefined;
}
//# sourceMappingURL=grammar-definition.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-definition.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-definition.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAc,MAAM,sBAAsB,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAS,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAM/D,qBAAa,gCAAiC,SAAQ,yBAAyB;IAE3E,SAAS,CAAC,SAAS,EAAE,gBAAgB,CAAC;gBAE1B,QAAQ,EAAE,eAAe;cAKlB,oBAAoB,CAAC,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,GAAG,YAAY,CAAC,YAAY,EAAE,GAAG,SAAS,CAAC;IAsBxI,SAAS,CAAC,gBAAgB,CAAC,eAAe,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS;CAO5E"}
+41
View File
@@ -0,0 +1,41 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { LocationLink, Range } from 'vscode-languageserver';
import { DefaultDefinitionProvider } from '../../lsp/index.js';
import { streamContents } from '../../utils/ast-utils.js';
import { findAssignment } from '../../utils/grammar-utils.js';
import { isGrammarImport } from '../../languages/generated/ast.js';
import { resolveImport } from '../internal-grammar-util.js';
export class LangiumGrammarDefinitionProvider extends DefaultDefinitionProvider {
constructor(services) {
super(services);
this.documents = services.shared.workspace.LangiumDocuments;
}
collectLocationLinks(sourceCstNode, _params) {
const pathFeature = 'path';
if (isGrammarImport(sourceCstNode.astNode) && findAssignment(sourceCstNode)?.feature === pathFeature) {
const importedGrammar = resolveImport(this.documents, sourceCstNode.astNode);
if (importedGrammar?.$document) {
const targetObject = this.findTargetObject(importedGrammar) ?? importedGrammar;
const selectionRange = this.nameProvider.getNameNode(targetObject)?.range ?? Range.create(0, 0, 0, 0);
const previewRange = targetObject.$cstNode?.range ?? Range.create(0, 0, 0, 0);
return [
LocationLink.create(importedGrammar.$document.uri.toString(), previewRange, selectionRange, sourceCstNode.range)
];
}
return undefined;
}
return super.collectLocationLinks(sourceCstNode, _params);
}
findTargetObject(importedGrammar) {
// Jump to grammar name or the first element
if (importedGrammar.isDeclared) {
return importedGrammar;
}
return streamContents(importedGrammar).head();
}
}
//# sourceMappingURL=grammar-definition.js.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-definition.js","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-definition.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAQhF,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,MAAM,OAAO,gCAAiC,SAAQ,yBAAyB;IAI3E,YAAY,QAAyB;QACjC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC;IAChE,CAAC;IAEkB,oBAAoB,CAAC,aAA0B,EAAE,OAAyB;QACzF,MAAM,WAAW,GAA8B,MAAM,CAAC;QACtD,IAAI,eAAe,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,cAAc,CAAC,aAAa,CAAC,EAAE,OAAO,KAAK,WAAW,EAAE,CAAC;YACnG,MAAM,eAAe,GAAG,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;YAC7E,IAAI,eAAe,EAAE,SAAS,EAAE,CAAC;gBAC7B,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,IAAI,eAAe,CAAC;gBAC/E,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBACtG,MAAM,YAAY,GAAG,YAAY,CAAC,QAAQ,EAAE,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC9E,OAAO;oBACH,YAAY,CAAC,MAAM,CACf,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,EACxC,YAAY,EACZ,cAAc,EACd,aAAa,CAAC,KAAK,CACtB;iBACJ,CAAC;YACN,CAAC;YACD,OAAO,SAAS,CAAC;QACrB,CAAC;QACD,OAAO,KAAK,CAAC,oBAAoB,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;IAES,gBAAgB,CAAC,eAAwB;QAC/C,4CAA4C;QAC5C,IAAI,eAAe,CAAC,UAAU,EAAE,CAAC;YAC7B,OAAO,eAAe,CAAC;QAC3B,CAAC;QACD,OAAO,cAAc,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,CAAC;CACJ"}
@@ -0,0 +1,14 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { AstNode } from '../../syntax-tree.js';
import { DefaultFoldingRangeProvider } from '../../lsp/folding-range-provider.js';
/**
* A specialized folding range provider for the grammar language
*/
export declare class LangiumGrammarFoldingRangeProvider extends DefaultFoldingRangeProvider {
shouldProcessContent(node: AstNode): boolean;
}
//# sourceMappingURL=grammar-folding-ranges.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-folding-ranges.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-folding-ranges.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAGlF;;GAEG;AACH,qBAAa,kCAAmC,SAAQ,2BAA2B;IAEtE,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;CAIxD"}
+17
View File
@@ -0,0 +1,17 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { DefaultFoldingRangeProvider } from '../../lsp/folding-range-provider.js';
import { isParserRule } from '../../languages/generated/ast.js';
/**
* A specialized folding range provider for the grammar language
*/
export class LangiumGrammarFoldingRangeProvider extends DefaultFoldingRangeProvider {
shouldProcessContent(node) {
// Exclude parser rules from folding
return !isParserRule(node);
}
}
//# sourceMappingURL=grammar-folding-ranges.js.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-folding-ranges.js","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-folding-ranges.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAGhF,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAEhE;;GAEG;AACH,MAAM,OAAO,kCAAmC,SAAQ,2BAA2B;IAEtE,oBAAoB,CAAC,IAAa;QACvC,oCAAoC;QACpC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;CACJ"}
+11
View File
@@ -0,0 +1,11 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { AstNode } from '../../syntax-tree.js';
import { AbstractFormatter } from '../../lsp/formatter.js';
export declare class LangiumGrammarFormatter extends AbstractFormatter {
protected format(node: AstNode): void;
}
//# sourceMappingURL=grammar-formatter.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-formatter.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-formatter.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAc,MAAM,wBAAwB,CAAC;AAKvE,qBAAa,uBAAwB,SAAQ,iBAAiB;IAE1D,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;CA0FxC"}
+112
View File
@@ -0,0 +1,112 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { AbstractFormatter, Formatting } from '../../lsp/formatter.js';
import * as ast from '../../languages/generated/ast.js';
const indentOrSpace = Formatting.fit(Formatting.oneSpace(), Formatting.indent());
export class LangiumGrammarFormatter extends AbstractFormatter {
format(node) {
if (ast.isCrossReference(node)) {
const formatter = this.getNodeFormatter(node);
formatter.properties('type', 'terminal').surround(Formatting.noSpace());
}
else if (ast.isParserRule(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keywords('entry', 'fragment', 'returns').append(Formatting.oneSpace());
if ((node.inferredType || node.returnType || node.dataType) && node.parameters.length === 0) {
formatter.property('name').append(Formatting.oneSpace());
}
else {
formatter.property('name').append(Formatting.noSpace());
}
formatter.properties('parameters').append(Formatting.noSpace());
formatter.keywords(',').append(Formatting.oneSpace());
formatter.keywords('<').append(Formatting.noSpace());
const semicolon = formatter.keyword(';');
const colon = formatter.keyword(':');
colon.prepend(Formatting.noSpace());
formatter.interior(colon, semicolon).prepend(Formatting.indent());
semicolon.prepend(Formatting.fit(Formatting.noSpace(), Formatting.newLine()));
formatter.node(node).prepend(Formatting.noIndent());
}
else if (ast.isTerminalRule(node)) {
const formatter = this.getNodeFormatter(node);
if (node.type) {
formatter.property('name').append(Formatting.oneSpace());
formatter.keyword('returns').append(Formatting.oneSpace());
}
formatter.keywords('hidden', 'terminal', 'fragment').append(Formatting.oneSpace());
formatter.keyword(':').prepend(Formatting.noSpace());
formatter.keyword(';').prepend(Formatting.fit(Formatting.noSpace(), Formatting.newLine()));
formatter.node(node).prepend(Formatting.noIndent());
}
else if (ast.isAction(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keyword('{').append(Formatting.noSpace());
formatter.keywords('.', '+=', '=').surround(Formatting.noSpace());
formatter.keyword('}').prepend(Formatting.noSpace());
}
else if (ast.isInferredType(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keywords('infer', 'infers').append(Formatting.oneSpace());
}
else if (ast.isAssignment(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keywords('=', '+=', '?=').surround(Formatting.noSpace());
}
else if (ast.isRuleCall(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keyword('<').surround(Formatting.noSpace());
formatter.keyword(',').append(Formatting.oneSpace());
formatter.properties('arguments').append(Formatting.noSpace());
}
else if (ast.isInterface(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keyword('interface').append(Formatting.oneSpace());
formatter.keyword('extends').prepend(Formatting.oneSpace()).append(indentOrSpace);
formatter.keywords(',').prepend(Formatting.noSpace()).append(indentOrSpace);
const bracesOpen = formatter.keyword('{');
bracesOpen.prepend(Formatting.fit(Formatting.oneSpace(), Formatting.newLine()));
const bracesClose = formatter.keyword('}');
bracesClose.prepend(Formatting.newLine());
formatter.interior(bracesOpen, bracesClose).prepend(Formatting.indent());
}
else if (ast.isType(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keyword('type').append(Formatting.oneSpace());
formatter.keyword('=').prepend(Formatting.oneSpace()).append(indentOrSpace);
formatter.keyword(';').prepend(Formatting.noSpace()).append(Formatting.newLine());
}
else if (ast.isGrammar(node)) {
const formatter = this.getNodeFormatter(node);
const nodes = formatter.nodes(...node.rules, ...node.interfaces, ...node.types, ...node.imports);
nodes.prepend(Formatting.noIndent());
formatter.keyword('grammar').prepend(Formatting.noSpace()).append(Formatting.oneSpace());
}
else if (ast.isInfixRuleOperatorList(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keywords('left', 'right').append(Formatting.oneSpace());
formatter.keywords('|').surround(Formatting.oneSpace());
}
else if (ast.isInfixRuleOperators(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keywords('>').prepend(Formatting.newLine());
}
else if (ast.isInfixRule(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keyword('infix').append(Formatting.oneSpace());
formatter.keyword('on').append(Formatting.oneSpace());
const semicolon = formatter.keyword(';');
const colon = formatter.keyword(':');
colon.prepend(Formatting.noSpace());
formatter.interior(colon, semicolon).prepend(Formatting.indent());
}
if (ast.isAbstractElement(node)) {
const formatter = this.getNodeFormatter(node);
formatter.property('cardinality').prepend(Formatting.noSpace());
}
}
}
//# sourceMappingURL=grammar-formatter.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,12 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { AstNode } from '../../syntax-tree.js';
import type { SemanticTokenAcceptor } from '../../lsp/semantic-token-provider.js';
import { AbstractSemanticTokenProvider } from '../../lsp/semantic-token-provider.js';
export declare class LangiumGrammarSemanticTokenProvider extends AbstractSemanticTokenProvider {
protected highlightElement(node: AstNode, acceptor: SemanticTokenAcceptor): void;
}
//# sourceMappingURL=grammar-semantic-tokens.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-semantic-tokens.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-semantic-tokens.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAElF,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AAGrF,qBAAa,mCAAoC,SAAQ,6BAA6B;IAElF,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,qBAAqB,GAAG,IAAI;CA0DnF"}
+75
View File
@@ -0,0 +1,75 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { SemanticTokenTypes } from 'vscode-languageserver';
import { AbstractSemanticTokenProvider } from '../../lsp/semantic-token-provider.js';
import { isAction, isAssignment, isInfixRule, isParameter, isParameterReference, isReturnType, isRuleCall, isSimpleType, isTypeAttribute } from '../../languages/generated/ast.js';
export class LangiumGrammarSemanticTokenProvider extends AbstractSemanticTokenProvider {
highlightElement(node, acceptor) {
if (isAssignment(node)) {
acceptor({
node,
property: 'feature',
type: SemanticTokenTypes.property
});
}
else if (isAction(node)) {
if (node.feature) {
acceptor({
node,
property: 'feature',
type: SemanticTokenTypes.property
});
}
}
else if (isReturnType(node)) {
acceptor({
node,
property: 'name',
type: SemanticTokenTypes.type
});
}
else if (isSimpleType(node)) {
if (node.primitiveType || node.typeRef) {
acceptor({
node,
property: node.primitiveType ? 'primitiveType' : 'typeRef',
type: SemanticTokenTypes.type
});
}
}
else if (isParameter(node)) {
acceptor({
node,
property: 'name',
type: SemanticTokenTypes.parameter
});
}
else if (isParameterReference(node)) {
acceptor({
node,
property: 'parameter',
type: SemanticTokenTypes.parameter
});
}
else if (isRuleCall(node)) {
if (!isInfixRule(node.rule.ref) && node.rule.ref?.fragment) {
acceptor({
node,
property: 'rule',
type: SemanticTokenTypes.type
});
}
}
else if (isTypeAttribute(node)) {
acceptor({
node,
property: 'name',
type: SemanticTokenTypes.property
});
}
}
}
//# sourceMappingURL=grammar-semantic-tokens.js.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-semantic-tokens.js","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-semantic-tokens.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAIhF,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,oBAAoB,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAEnL,MAAM,OAAO,mCAAoC,SAAQ,6BAA6B;IAExE,gBAAgB,CAAC,IAAa,EAAE,QAA+B;QACrE,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,QAAQ,CAAC;gBACL,IAAI;gBACJ,QAAQ,EAAE,SAAS;gBACnB,IAAI,EAAE,kBAAkB,CAAC,QAAQ;aACpC,CAAC,CAAC;QACP,CAAC;aAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,QAAQ,CAAC;oBACL,IAAI;oBACJ,QAAQ,EAAE,SAAS;oBACnB,IAAI,EAAE,kBAAkB,CAAC,QAAQ;iBACpC,CAAC,CAAC;YACP,CAAC;QACL,CAAC;aAAM,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,QAAQ,CAAC;gBACL,IAAI;gBACJ,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,kBAAkB,CAAC,IAAI;aAChC,CAAC,CAAC;QACP,CAAC;aAAM,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACrC,QAAQ,CAAC;oBACL,IAAI;oBACJ,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS;oBAC1D,IAAI,EAAE,kBAAkB,CAAC,IAAI;iBAChC,CAAC,CAAC;YACP,CAAC;QACL,CAAC;aAAM,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,QAAQ,CAAC;gBACL,IAAI;gBACJ,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,kBAAkB,CAAC,SAAS;aACrC,CAAC,CAAC;QACP,CAAC;aAAM,IAAI,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,QAAQ,CAAC;gBACL,IAAI;gBACJ,QAAQ,EAAE,WAAW;gBACrB,IAAI,EAAE,kBAAkB,CAAC,SAAS;aACrC,CAAC,CAAC;QACP,CAAC;aAAM,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC;gBACzD,QAAQ,CAAC;oBACL,IAAI;oBACJ,QAAQ,EAAE,MAAM;oBAChB,IAAI,EAAE,kBAAkB,CAAC,IAAI;iBAChC,CAAC,CAAC;YACP,CAAC;QACL,CAAC;aAAM,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,QAAQ,CAAC;gBACL,IAAI;gBACJ,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,kBAAkB,CAAC,QAAQ;aACpC,CAAC,CAAC;QACP,CAAC;IACL,CAAC;CAEJ"}
@@ -0,0 +1,13 @@
/******************************************************************************
* Copyright 2023 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { AstNode } from '../../syntax-tree.js';
import type { TypeHierarchyItem } from 'vscode-languageserver';
import { AbstractTypeHierarchyProvider } from '../../lsp/type-hierarchy-provider.js';
export declare class LangiumGrammarTypeHierarchyProvider extends AbstractTypeHierarchyProvider {
protected getSupertypes(node: AstNode): TypeHierarchyItem[] | undefined;
protected getSubtypes(node: AstNode): TypeHierarchyItem[] | undefined;
}
//# sourceMappingURL=grammar-type-hierarchy.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-type-hierarchy.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-type-hierarchy.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AAKrF,qBAAa,mCAAoC,SAAQ,6BAA6B;IAClF,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,iBAAiB,EAAE,GAAG,SAAS;IAiBvE,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,iBAAiB,EAAE,GAAG,SAAS;CAmCxE"}
+54
View File
@@ -0,0 +1,54 @@
/******************************************************************************
* Copyright 2023 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { AbstractTypeHierarchyProvider } from '../../lsp/type-hierarchy-provider.js';
import { getDocument } from '../../utils/ast-utils.js';
import { findLeafNodeAtOffset } from '../../utils/cst-utils.js';
import { isInterface } from '../../languages/generated/ast.js';
export class LangiumGrammarTypeHierarchyProvider extends AbstractTypeHierarchyProvider {
getSupertypes(node) {
if (!isInterface(node)) {
return undefined;
}
const items = node.superTypes.flatMap(superType => {
const ref = superType.ref;
if (!ref) {
return [];
}
return this.getTypeHierarchyItems(ref, getDocument(ref)) ?? [];
});
return items.length === 0 ? undefined : items;
}
getSubtypes(node) {
if (!isInterface(node)) {
return undefined;
}
const items = this.references
.findReferences(node, { includeDeclaration: false })
.flatMap(ref => {
const document = this.documents.getDocument(ref.sourceUri);
if (!document) {
return [];
}
const rootNode = document.parseResult.value;
if (!rootNode.$cstNode) {
return [];
}
const refCstNode = findLeafNodeAtOffset(rootNode.$cstNode, ref.segment.offset);
if (!refCstNode) {
return [];
}
// Only consider references that occur as a superType of an interface
const refNode = refCstNode.astNode;
if (!isInterface(refNode) || refNode.superTypes.every(superType => superType.$refNode !== refCstNode)) {
return [];
}
return this.getTypeHierarchyItems(refNode, document) ?? [];
})
.toArray();
return items.length === 0 ? undefined : items;
}
}
//# sourceMappingURL=grammar-type-hierarchy.js.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-type-hierarchy.js","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-type-hierarchy.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAIhF,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAE/D,MAAM,OAAO,mCAAoC,SAAQ,6BAA6B;IACxE,aAAa,CAAC,IAAa;QACjC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;YAC9C,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC;YAC1B,IAAI,CAAC,GAAG,EAAE,CAAC;gBACP,OAAO,EAAE,CAAC;YACd,CAAC;YAED,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;IAClD,CAAC;IAES,WAAW,CAAC,IAAa;QAC/B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU;aACxB,cAAc,CAAC,IAAI,EAAE,EAAC,kBAAkB,EAAE,KAAK,EAAC,CAAC;aACjD,OAAO,CAAC,GAAG,CAAC,EAAE;YACX,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC3D,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACZ,OAAO,EAAE,CAAC;YACd,CAAC;YAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC;YAC5C,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACrB,OAAO,EAAE,CAAC;YACd,CAAC;YAED,MAAM,UAAU,GAAG,oBAAoB,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC/E,IAAI,CAAC,UAAU,EAAE,CAAC;gBACd,OAAO,EAAE,CAAC;YACd,CAAC;YAED,qEAAqE;YACrE,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;YACnC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,KAAK,UAAU,CAAC,EAAE,CAAC;gBACpG,OAAO,EAAE,CAAC;YACd,CAAC;YAED,OAAO,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/D,CAAC,CAAC;aACD,OAAO,EAAE,CAAC;QAEf,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;IAClD,CAAC;CACJ"}
+12
View File
@@ -0,0 +1,12 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { AstNode, CstNode } from '../../syntax-tree.js';
import { DefaultNameProvider } from '../../references/name-provider.js';
export declare class LangiumGrammarNameProvider extends DefaultNameProvider {
getName(node: AstNode): string | undefined;
getNameNode(node: AstNode): CstNode | undefined;
}
//# sourceMappingURL=grammar-naming.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-naming.d.ts","sourceRoot":"","sources":["../../../src/grammar/references/grammar-naming.ts"],"names":[],"mappings":"AAAA;;;;+EAI+E;AAE/E,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AAIxE,qBAAa,0BAA2B,SAAQ,mBAAmB;IAEtD,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS;IAQ1C,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS;CAQ3D"}
+27
View File
@@ -0,0 +1,27 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { DefaultNameProvider } from '../../references/name-provider.js';
import { findNodeForProperty } from '../../utils/grammar-utils.js';
import { isAssignment } from '../../languages/generated/ast.js';
export class LangiumGrammarNameProvider extends DefaultNameProvider {
getName(node) {
if (isAssignment(node)) {
return node.feature;
}
else {
return super.getName(node);
}
}
getNameNode(node) {
if (isAssignment(node)) {
return findNodeForProperty(node.$cstNode, 'feature');
}
else {
return super.getNameNode(node);
}
}
}
//# sourceMappingURL=grammar-naming.js.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-naming.js","sourceRoot":"","sources":["../../../src/grammar/references/grammar-naming.ts"],"names":[],"mappings":"AAAA;;;;+EAI+E;AAG/E,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAC;AACxE,OAAO,EAAE,mBAAmB,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAEhE,MAAM,OAAO,0BAA2B,SAAQ,mBAAmB;IAEtD,OAAO,CAAC,IAAa;QAC1B,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,OAAO,IAAI,CAAC,OAAO,CAAC;QACxB,CAAC;aAAM,CAAC;YACJ,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC/B,CAAC;IACL,CAAC;IAEQ,WAAW,CAAC,IAAa;QAC9B,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,OAAO,mBAAmB,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC;QACzD,CAAC;aAAM,CAAC;YACJ,OAAO,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;QACnC,CAAC;IACL,CAAC;CAEJ"}
@@ -0,0 +1,21 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { AstNode, CstNode } from '../../syntax-tree.js';
import type { Stream } from '../../utils/stream.js';
import type { ReferenceDescription } from '../../workspace/ast-descriptions.js';
import type { AbstractParserRule, Action, Assignment, Interface, Type, TypeAttribute } from '../../languages/generated/ast.js';
import type { FindReferencesOptions } from '../../references/references.js';
import { DefaultReferences } from '../../references/references.js';
export declare class LangiumGrammarReferences extends DefaultReferences {
findDeclarations(sourceCstNode: CstNode): AstNode[];
findReferences(targetNode: AstNode, options: FindReferencesOptions): Stream<ReferenceDescription>;
protected findReferencesToTypeAttribute(targetNode: TypeAttribute, includeDeclaration: boolean): Stream<ReferenceDescription>;
protected createReferencesToAttribute(ruleOrAction: AbstractParserRule | Action, attribute: TypeAttribute): ReferenceDescription[];
protected findAssignmentDeclaration(assignment: Assignment): AstNode | undefined;
protected findActionDeclaration(action: Action, featureName?: string): TypeAttribute | undefined;
protected findRulesWithReturnType(interf: Interface | Type): Array<AbstractParserRule | Action>;
}
//# sourceMappingURL=grammar-references.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-references.d.ts","sourceRoot":"","sources":["../../../src/grammar/references/grammar-references.ts"],"names":[],"mappings":"AAAA;;;;+EAI+E;AAE/E,OAAO,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAChF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAC/H,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,gCAAgC,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAWnE,qBAAa,wBAAyB,SAAQ,iBAAiB;IAElD,gBAAgB,CAAC,aAAa,EAAE,OAAO,GAAG,OAAO,EAAE;IAgBnD,cAAc,CAAC,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,qBAAqB,GAAG,MAAM,CAAC,oBAAoB,CAAC;IAQ1G,SAAS,CAAC,6BAA6B,CAAC,UAAU,EAAE,aAAa,EAAE,kBAAkB,EAAE,OAAO,GAAG,MAAM,CAAC,oBAAoB,CAAC;IAqB7H,SAAS,CAAC,2BAA2B,CAAC,YAAY,EAAE,kBAAkB,GAAG,MAAM,EAAE,SAAS,EAAE,aAAa,GAAG,oBAAoB,EAAE;IAmElI,SAAS,CAAC,yBAAyB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,GAAG,SAAS;IAuBhF,SAAS,CAAC,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,aAAa,GAAG,SAAS;IAchG,SAAS,CAAC,uBAAuB,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,GAAG,KAAK,CAAC,kBAAkB,GAAG,MAAM,CAAC;CAclG"}
@@ -0,0 +1,180 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { DefaultReferences } from '../../references/references.js';
import { getContainerOfType, getDocument } from '../../utils/ast-utils.js';
import { toDocumentSegment } from '../../utils/cst-utils.js';
import { findAssignment, findNodeForKeyword, findNodeForProperty, getActionAtElement } from '../../utils/grammar-utils.js';
import { stream } from '../../utils/stream.js';
import { UriUtils } from '../../utils/uri-utils.js';
import { isAbstractParserRule, isAction, isAssignment, isInfixRule, isInterface, isParserRule, isType, isTypeAttribute } from '../../languages/generated/ast.js';
import { extractAssignments } from '../internal-grammar-util.js';
import { collectChildrenTypes, collectSuperTypes } from '../type-system/types-util.js';
import { assertUnreachable } from '../../utils/errors.js';
export class LangiumGrammarReferences extends DefaultReferences {
findDeclarations(sourceCstNode) {
const nodeElem = sourceCstNode.astNode;
const assignment = findAssignment(sourceCstNode);
if (assignment && assignment.feature === 'feature') {
// Only search for a special declaration if the cst node is the feature property of the action/assignment
if (isAssignment(nodeElem)) {
const decl = this.findAssignmentDeclaration(nodeElem);
return decl ? [decl] : [];
}
else if (isAction(nodeElem)) {
const decl = this.findActionDeclaration(nodeElem);
return decl ? [decl] : [];
}
}
return super.findDeclarations(sourceCstNode);
}
findReferences(targetNode, options) {
if (isTypeAttribute(targetNode)) {
return this.findReferencesToTypeAttribute(targetNode, options.includeDeclaration ?? false);
}
else {
return super.findReferences(targetNode, options);
}
}
findReferencesToTypeAttribute(targetNode, includeDeclaration) {
const refs = [];
const interfaceNode = getContainerOfType(targetNode, isInterface);
if (interfaceNode) {
if (includeDeclaration) {
refs.push(...this.getSelfReferences(targetNode));
}
const interfaces = collectChildrenTypes(interfaceNode, this, this.documents, this.nodeLocator);
const targetRules = [];
interfaces.forEach(interf => {
const rules = this.findRulesWithReturnType(interf);
targetRules.push(...rules);
});
targetRules.forEach(rule => {
const references = this.createReferencesToAttribute(rule, targetNode);
refs.push(...references);
});
}
return stream(refs);
}
createReferencesToAttribute(ruleOrAction, attribute) {
const refs = [];
if (isParserRule(ruleOrAction)) {
const assignment = extractAssignments(ruleOrAction.definition).find(a => a.feature === attribute.name);
if (assignment?.$cstNode) {
const leaf = this.nameProvider.getNameNode(assignment);
if (leaf) {
const assignmentUri = getDocument(assignment).uri;
const attributeUri = getDocument(attribute).uri;
refs.push({
sourceUri: assignmentUri,
sourcePath: this.nodeLocator.getAstNodePath(assignment),
targetUri: attributeUri,
targetPath: this.nodeLocator.getAstNodePath(attribute),
segment: toDocumentSegment(leaf),
local: UriUtils.equals(assignmentUri, attributeUri)
});
}
}
}
else if (isInfixRule(ruleOrAction)) {
let leaf;
if (attribute.name === 'left' || attribute.name === 'right') {
// Use the 'on' keyword as segment
leaf = findNodeForKeyword(ruleOrAction.$cstNode, 'on');
}
else if (attribute.name === 'operator') {
// Use the rule definition in 'operators' as segment
leaf = findNodeForProperty(ruleOrAction.$cstNode, 'operators');
}
if (leaf) {
const ruleUri = getDocument(ruleOrAction).uri;
const attributeUri = getDocument(attribute).uri;
refs.push({
sourceUri: ruleUri,
sourcePath: this.nodeLocator.getAstNodePath(ruleOrAction),
targetUri: attributeUri,
targetPath: this.nodeLocator.getAstNodePath(attribute),
segment: toDocumentSegment(leaf),
local: UriUtils.equals(ruleUri, attributeUri)
});
}
}
else if (isAction(ruleOrAction)) {
// If the action references the attribute directly
if (ruleOrAction.feature === attribute.name) {
const leaf = findNodeForProperty(ruleOrAction.$cstNode, 'feature');
if (leaf) {
const actionUri = getDocument(ruleOrAction).uri;
const attributeUri = getDocument(attribute).uri;
refs.push({
sourceUri: actionUri,
sourcePath: this.nodeLocator.getAstNodePath(ruleOrAction),
targetUri: attributeUri,
targetPath: this.nodeLocator.getAstNodePath(attribute),
segment: toDocumentSegment(leaf),
local: UriUtils.equals(actionUri, attributeUri)
});
}
}
// Find all references within the parser rule that contains this action
const parserRule = getContainerOfType(ruleOrAction, isParserRule);
refs.push(...this.createReferencesToAttribute(parserRule, attribute));
}
else {
assertUnreachable(ruleOrAction);
}
return refs;
}
findAssignmentDeclaration(assignment) {
const parserRule = getContainerOfType(assignment, isParserRule);
const action = getActionAtElement(assignment);
if (action) {
const actionDeclaration = this.findActionDeclaration(action, assignment.feature);
if (actionDeclaration) {
return actionDeclaration;
}
}
if (parserRule?.returnType?.ref) {
if (isInterface(parserRule.returnType.ref) || isType(parserRule.returnType.ref)) {
const interfaces = collectSuperTypes(parserRule.returnType.ref);
for (const interf of interfaces) {
const typeAttribute = interf.attributes.find(att => att.name === assignment.feature);
if (typeAttribute) {
return typeAttribute;
}
}
}
}
return assignment;
}
findActionDeclaration(action, featureName) {
if (action.type?.ref) {
const feature = featureName ?? action.feature;
const interfaces = collectSuperTypes(action.type.ref);
for (const interf of interfaces) {
const typeAttribute = interf.attributes.find(att => att.name === feature);
if (typeAttribute) {
return typeAttribute;
}
}
}
return undefined;
}
findRulesWithReturnType(interf) {
const rules = [];
const refs = this.index.findAllReferences(interf, this.nodeLocator.getAstNodePath(interf));
for (const ref of refs) {
const doc = this.documents.getDocument(ref.sourceUri);
if (doc) {
const astNode = this.nodeLocator.getAstNode(doc.parseResult.value, ref.sourcePath);
if (isAbstractParserRule(astNode) || isAction(astNode)) {
rules.push(astNode);
}
}
}
return rules;
}
}
//# sourceMappingURL=grammar-references.js.map
File diff suppressed because one or more lines are too long
+41
View File
@@ -0,0 +1,41 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { Scope } from '../../references/scope.js';
import type { LangiumCoreServices } from '../../services.js';
import type { AstNode, AstNodeDescription, ReferenceInfo } from '../../syntax-tree.js';
import type { MultiMap } from '../../utils/collections.js';
import type { AstNodeLocator } from '../../workspace/ast-node-locator.js';
import type { LangiumDocument, LangiumDocuments } from '../../workspace/documents.js';
import { DefaultScopeComputation } from '../../references/scope-computation.js';
import { DefaultScopeProvider } from '../../references/scope-provider.js';
export declare class LangiumGrammarScopeProvider extends DefaultScopeProvider {
protected readonly langiumDocuments: LangiumDocuments;
constructor(services: LangiumCoreServices);
getScope(context: ReferenceInfo): Scope;
private getNamedArgumentScope;
private getTypeScope;
protected getGlobalScope(referenceType: string, context: ReferenceInfo): Scope;
private gatherImports;
}
export declare class LangiumGrammarScopeComputation extends DefaultScopeComputation {
protected readonly astNodeLocator: AstNodeLocator;
constructor(services: LangiumCoreServices);
protected addExportedSymbol(node: AstNode, exports: AstNodeDescription[], document: LangiumDocument): void;
protected addLocalSymbol(node: AstNode, document: LangiumDocument, symbols: MultiMap<AstNode, AstNodeDescription>): void;
/**
* Add synthetic type into the scope in case of explicitly or implicitly inferred type:<br>
* cases: `ParserRule: ...;` or `ParserRule infers Type: ...;`
*/
protected processTypeNode(node: AstNode, document: LangiumDocument, symbols: MultiMap<AstNode, AstNodeDescription>): void;
/**
* Add synthetic type into the scope in case of explicitly inferred type:
*
* case: `{infer Action}`
*/
protected processActionNode(node: AstNode, document: LangiumDocument, symbols: MultiMap<AstNode, AstNodeDescription>): void;
protected createInferredTypeDescription(node: AstNode, name: string, document?: LangiumDocument): AstNodeDescription;
}
//# sourceMappingURL=grammar-scope.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-scope.d.ts","sourceRoot":"","sources":["../../../src/grammar/references/grammar-scope.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,2BAA2B,CAAC;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACvF,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,KAAK,EAAmB,eAAe,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AAGvG,OAAO,EAAE,uBAAuB,EAAE,MAAM,uCAAuC,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAM1E,qBAAa,2BAA4B,SAAQ,oBAAoB;IAEjE,SAAS,CAAC,QAAQ,CAAC,gBAAgB,EAAE,gBAAgB,CAAC;gBAE1C,QAAQ,EAAE,mBAAmB;IAKhC,QAAQ,CAAC,OAAO,EAAE,aAAa,GAAG,KAAK;IAYhD,OAAO,CAAC,qBAAqB;IAY7B,OAAO,CAAC,YAAY;cAiBD,cAAc,CAAC,aAAa,EAAE,MAAM,EAAE,OAAO,EAAE,aAAa,GAAG,KAAK;IAcvF,OAAO,CAAC,aAAa;CAgBxB;AAED,qBAAa,8BAA+B,SAAQ,uBAAuB;IACvE,SAAS,CAAC,QAAQ,CAAC,cAAc,EAAE,cAAc,CAAC;gBAEtC,QAAQ,EAAE,mBAAmB;cAKtB,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,EAAE,QAAQ,EAAE,eAAe,GAAG,IAAI;cAkChG,cAAc,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC,GAAG,IAAI;IAUjI;;;OAGG;IACH,SAAS,CAAC,eAAe,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC,GAAG,IAAI;IAQzH;;;;OAIG;IACH,SAAS,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAC,GAAG,IAAI;IAO3H,SAAS,CAAC,6BAA6B,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,GAAE,eAAmC,GAAG,kBAAkB;CAe1I"}
+164
View File
@@ -0,0 +1,164 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { EMPTY_SCOPE, MultiMapScope } from '../../references/scope.js';
import { DefaultScopeComputation } from '../../references/scope-computation.js';
import { DefaultScopeProvider } from '../../references/scope-provider.js';
import { findRootNode, getContainerOfType, getDocument, streamAllContents } from '../../utils/ast-utils.js';
import { toDocumentSegment } from '../../utils/cst-utils.js';
import { AbstractType, InferredType, Interface, NamedArgument, Type, isAbstractParserRule, isAction, isGrammar, isReturnType, isRuleCall } from '../../languages/generated/ast.js';
import { resolveImportUri } from '../internal-grammar-util.js';
export class LangiumGrammarScopeProvider extends DefaultScopeProvider {
constructor(services) {
super(services);
this.langiumDocuments = services.shared.workspace.LangiumDocuments;
}
getScope(context) {
if (context.container.$type === NamedArgument.$type && context.property === 'parameter') {
return this.getNamedArgumentScope(context);
}
const referenceType = this.reflection.getReferenceType(context);
if (referenceType === AbstractType.$type) {
return this.getTypeScope(referenceType, context);
}
else {
return super.getScope(context);
}
}
getNamedArgumentScope(context) {
const ruleCall = context.container.$container;
if (!isRuleCall(ruleCall)) {
return EMPTY_SCOPE;
}
const rule = ruleCall.rule.ref;
if (!isAbstractParserRule(rule)) {
return EMPTY_SCOPE;
}
return this.createScopeForNodes(rule.parameters);
}
getTypeScope(referenceType, context) {
const localSymbols = getDocument(context.container).localSymbols;
const rootNode = findRootNode(context.container);
if (localSymbols && rootNode && localSymbols.has(rootNode)) {
const globalScope = this.getGlobalScope(referenceType, context);
const localScope = localSymbols.getStream(rootNode).filter(des => des.type === Interface.$type || des.type === Type.$type || des.type === InferredType.$type);
return this.createScope(localScope, globalScope);
}
else {
return this.getGlobalScope(referenceType, context);
}
}
getGlobalScope(referenceType, context) {
const grammar = getContainerOfType(context.container, isGrammar);
if (!grammar) {
return EMPTY_SCOPE;
}
const importedUris = new Set();
this.gatherImports(grammar, importedUris);
let importedElements = this.indexManager.allElements(referenceType, importedUris);
if (referenceType === AbstractType.$type) {
importedElements = importedElements.filter(des => des.type === Interface.$type || des.type === Type.$type || des.type === InferredType.$type);
}
return new MultiMapScope(importedElements);
}
gatherImports(grammar, importedUris) {
for (const imp0rt of grammar.imports) {
const uri = resolveImportUri(imp0rt);
if (uri && !importedUris.has(uri.toString())) {
importedUris.add(uri.toString());
const importedDocument = this.langiumDocuments.getDocument(uri);
if (importedDocument) {
const rootNode = importedDocument.parseResult.value;
if (isGrammar(rootNode)) {
this.gatherImports(rootNode, importedUris);
}
}
}
}
}
}
export class LangiumGrammarScopeComputation extends DefaultScopeComputation {
constructor(services) {
super(services);
this.astNodeLocator = services.workspace.AstNodeLocator;
}
addExportedSymbol(node, exports, document) {
// this function is called in order to export nodes to the GLOBAL scope
/* Among others, TYPES need to be exported.
* There are three ways to define types:
* - explicit "type" declarations
* - explicit "interface" declarations
* - "inferred types", which can be distinguished into ...
* - inferred types with explicitly declared names, i.e. parser rules with "infers", actions with "infer"
* Note, that multiple explicitly inferred types might have the same name! Cross-references to such types are resolved to the first declaration.
* - implicitly inferred types, i.e. parser rules without "infers" and without "returns",
* which implicitly declare a type with the same name as the parser rule
* Note, that implicitly inferred types are unique, since names of parser rules must be unique.
*/
// export the top-level elements: parser rules, terminal rules, types, interfaces
super.addExportedSymbol(node, exports, document);
// additionally, export inferred types:
if (isAbstractParserRule(node)) {
if (!node.returnType && !node.dataType) {
// Export implicitly and explicitly inferred type from parser rule
const typeNode = node.inferredType ?? node;
exports.push(this.createInferredTypeDescription(typeNode, typeNode.name, document));
}
streamAllContents(node).forEach(childNode => {
if (isAction(childNode) && childNode.inferredType) {
// Export explicitly inferred type from action
exports.push(this.createInferredTypeDescription(childNode.inferredType, childNode.inferredType.name, document));
}
});
}
}
addLocalSymbol(node, document, symbols) {
// for the precompution of the local scope
if (isReturnType(node)) {
return;
}
this.processTypeNode(node, document, symbols);
this.processActionNode(node, document, symbols);
super.addLocalSymbol(node, document, symbols);
}
/**
* Add synthetic type into the scope in case of explicitly or implicitly inferred type:<br>
* cases: `ParserRule: ...;` or `ParserRule infers Type: ...;`
*/
processTypeNode(node, document, symbols) {
const container = node.$container;
if (container && isAbstractParserRule(node) && !node.returnType && !node.dataType) {
const typeNode = node.inferredType ?? node;
symbols.add(container, this.createInferredTypeDescription(typeNode, typeNode.name, document));
}
}
/**
* Add synthetic type into the scope in case of explicitly inferred type:
*
* case: `{infer Action}`
*/
processActionNode(node, document, symbols) {
const container = findRootNode(node);
if (container && isAction(node) && node.inferredType) {
symbols.add(container, this.createInferredTypeDescription(node.inferredType, node.inferredType.name, document));
}
}
createInferredTypeDescription(node, name, document = getDocument(node)) {
let nameNodeSegment;
const nameSegmentGetter = () => nameNodeSegment ?? (nameNodeSegment = toDocumentSegment(this.nameProvider.getNameNode(node) ?? node.$cstNode));
return {
node,
name,
get nameSegment() {
return nameSegmentGetter();
},
selectionSegment: toDocumentSegment(node.$cstNode),
type: InferredType.$type,
documentUri: document.uri,
path: this.astNodeLocator.getAstNodePath(node)
};
}
}
//# sourceMappingURL=grammar-scope.js.map
File diff suppressed because one or more lines are too long
+32
View File
@@ -0,0 +1,32 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { type Grammar } from '../../languages/generated/ast.js';
import { type LangiumCoreServices } from '../../services.js';
import type { ValidationAstTypes } from './type-collector/all-types.js';
import type { PlainAstTypes } from './type-collector/plain-types.js';
import type { AstTypes } from './type-collector/types.js';
/**
* Collects all types for the generated AST. The types collector entry point.
*
* @param grammars All grammars involved in the type generation process
* @param config some optional configurations
*/
export declare function collectAst(grammars: Grammar | Grammar[], config?: {
/** Langium core services to resolve imports as needed, and to pass along JSDoc comments to the generated AST */
services?: LangiumCoreServices;
filterNonAstTypeUnions?: boolean;
}): AstTypes;
/**
* Collects all types used during the validation process.
* The validation process requires us to compare our inferred types with our declared types.
*
* @param grammars All grammars involved in the validation process
* @param services Langium core services to resolve imports as needed, and to pass along JSDoc comments to the generated AST
*/
export declare function collectValidationAst(grammars: Grammar | Grammar[], services?: LangiumCoreServices): ValidationAstTypes;
export declare function createAstTypes(first: PlainAstTypes, second?: PlainAstTypes): AstTypes;
export declare function specifyAstNodeProperties(astTypes: AstTypes): void;
//# sourceMappingURL=ast-collector.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"ast-collector.d.ts","sourceRoot":"","sources":["../../../src/grammar/type-system/ast-collector.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,EAAE,KAAK,OAAO,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,KAAK,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,+BAA+B,CAAC;AAExE,OAAO,KAAK,EAAE,aAAa,EAA8B,MAAM,iCAAiC,CAAC;AAEjG,OAAO,KAAK,EAAE,QAAQ,EAAsD,MAAM,2BAA2B,CAAC;AAI9G;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,EAAE,EAAE,MAAM,CAAC,EAAE;IAC/D,gHAAgH;IAChH,QAAQ,CAAC,EAAE,mBAAmB,CAAC;IAC/B,sBAAsB,CAAC,EAAE,OAAO,CAAC;CACpC,GAAG,QAAQ,CAOX;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,EAAE,EAAE,QAAQ,CAAC,EAAE,mBAAmB,GAAG,kBAAkB,CAQtH;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,QAAQ,CASrF;AAaD,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,QAAQ,QAM1D"}
+169
View File
@@ -0,0 +1,169 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import {} from '../../languages/generated/ast.js';
import {} from '../../services.js';
import { collectTypeResources } from './type-collector/all-types.js';
import { plainToTypes } from './type-collector/plain-types.js';
import { isInterfaceType, isPrimitiveType, isPropertyUnion, isStringType, isUnionType, isValueType } from './type-collector/types.js';
import { findAstTypes, isAstType } from './types-util.js';
/**
* Collects all types for the generated AST. The types collector entry point.
*
* @param grammars All grammars involved in the type generation process
* @param config some optional configurations
*/
export function collectAst(grammars, config) {
const { inferred, declared } = collectTypeResources(grammars, config?.services);
const result = createAstTypes(inferred, declared);
if (config?.filterNonAstTypeUnions) {
result.unions = result.unions.filter(e => isAstType(e.type));
}
return result;
}
/**
* Collects all types used during the validation process.
* The validation process requires us to compare our inferred types with our declared types.
*
* @param grammars All grammars involved in the validation process
* @param services Langium core services to resolve imports as needed, and to pass along JSDoc comments to the generated AST
*/
export function collectValidationAst(grammars, services) {
const { inferred, declared, astResources } = collectTypeResources(grammars, services);
return {
astResources,
inferred: createAstTypes(declared, inferred),
declared: createAstTypes(inferred, declared)
};
}
export function createAstTypes(first, second) {
const astTypes = {
interfaces: mergeAndRemoveDuplicates(...first.interfaces, ...second?.interfaces ?? []),
unions: mergeAndRemoveDuplicates(...first.unions, ...second?.unions ?? []),
};
const finalTypes = plainToTypes(astTypes);
specifyAstNodeProperties(finalTypes);
return finalTypes;
}
/**
* Merges the lists of given elements into a single list and removes duplicates. Elements later in the lists get precedence over earlier elements.
*
* The distinction is performed over the `name` property of the element. The result is a name-sorted list of elements.
*/
function mergeAndRemoveDuplicates(...elements) {
return Array.from(elements
.reduce((acc, type) => { acc.set(type.name, type); return acc; }, new Map())
.values()).sort((a, b) => a.name.localeCompare(b.name));
}
export function specifyAstNodeProperties(astTypes) {
const nameToType = filterInterfaceLikeTypes(astTypes);
const array = Array.from(nameToType.values());
addSubTypes(array);
buildContainerTypes(astTypes.interfaces);
buildTypeNames(array);
}
function buildTypeNames(types) {
// Recursively collect all subtype names
const visited = new Set();
const collect = (type) => {
if (visited.has(type))
return;
visited.add(type);
type.typeNames.add(type.name);
for (const subtype of type.subTypes) {
collect(subtype);
subtype.typeNames.forEach(n => type.typeNames.add(n));
}
};
types.forEach(collect);
}
/**
* Removes union types that reference only to primitive types or
* types that reference only to primitive types.
*/
function filterInterfaceLikeTypes({ interfaces, unions }) {
const nameToType = interfaces.concat(unions)
.reduce((acc, e) => { acc.set(e.name, e); return acc; }, new Map());
const cache = new Map();
for (const union of unions) {
cache.set(union, isDataType(union.type, new Set()));
}
for (const [union, isDataType] of cache) {
if (isDataType) {
nameToType.delete(union.name);
}
}
return nameToType;
}
function isDataType(property, visited) {
if (visited.has(property)) {
return true;
}
visited.add(property);
if (isPropertyUnion(property)) {
return property.types.every(e => isDataType(e, visited));
}
else if (isValueType(property)) {
const value = property.value;
if (isUnionType(value)) {
return isDataType(value.type, visited);
}
else {
return false;
}
}
else {
return isPrimitiveType(property) || isStringType(property);
}
}
function addSubTypes(types) {
for (const interfaceType of types) {
for (const superTypeName of interfaceType.superTypes) {
superTypeName.subTypes.add(interfaceType);
}
}
}
/**
* Builds types of `$container` property.
* @param interfaces Interfaces for which container types are calculated.
*/
function buildContainerTypes(interfaces) {
const nameToInterface = interfaces
.reduce((acc, type) => { acc.set(type.name, type); return acc; }, new Map());
// 1st stage: collect container types
for (const containerType of interfaces) {
const types = containerType.properties.flatMap(property => findAstTypes(property.type));
for (const type of types) {
nameToInterface.get(type)?.containerTypes.add(containerType);
}
}
// 2nd stage: lift the container types of containers to parents
// if one of the children has no container types, the parent also loses container types
// contains type names that have children and at least one of them has no container types
const emptyContainerTypes = new Set();
const queue = interfaces.filter(interf => interf.subTypes.size === 0);
const visited = new Set(queue);
while (queue.length > 0) {
const interf = queue.shift();
if (interf) {
for (const superType of interf.superTypes) {
if (isInterfaceType(superType)) {
if (interf.containerTypes.size === 0) {
emptyContainerTypes.add(superType.name);
superType.containerTypes.clear();
}
else if (!emptyContainerTypes.has(superType.name)) {
interf.containerTypes.forEach(e => superType.containerTypes.add(e));
}
if (!visited.has(superType)) {
visited.add(superType);
queue.push(superType);
}
}
}
}
}
}
//# sourceMappingURL=ast-collector.js.map
File diff suppressed because one or more lines are too long
+13
View File
@@ -0,0 +1,13 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
export * from './ast-collector.js';
export * from './type-collector/types.js';
export * from './type-collector/all-types.js';
export * from './type-collector/declared-types.js';
export * from './type-collector/inferred-types.js';
export * from './type-collector/plain-types.js';
export * from './types-util.js';
//# sourceMappingURL=index.d.ts.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/grammar/type-system/index.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,oCAAoC,CAAC;AACnD,cAAc,oCAAoC,CAAC;AACnD,cAAc,iCAAiC,CAAC;AAChD,cAAc,iBAAiB,CAAC"}
+13
View File
@@ -0,0 +1,13 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
export * from './ast-collector.js';
export * from './type-collector/types.js';
export * from './type-collector/all-types.js';
export * from './type-collector/declared-types.js';
export * from './type-collector/inferred-types.js';
export * from './type-collector/plain-types.js';
export * from './types-util.js';
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/grammar/type-system/index.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,cAAc,oBAAoB,CAAC;AACnC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,oCAAoC,CAAC;AACnD,cAAc,oCAAoC,CAAC;AACnD,cAAc,iCAAiC,CAAC;AAChD,cAAc,iBAAiB,CAAC"}
@@ -0,0 +1,30 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { ParserRule, Interface, Type, Grammar, InfixRule } from '../../../languages/generated/ast.js';
import type { URI } from '../../../utils/uri-utils.js';
import type { LangiumCoreServices } from '../../../index.js';
import type { PlainAstTypes } from './plain-types.js';
import type { AstTypes } from './types.js';
export interface AstResources {
parserRules: ParserRule[];
infixRules: InfixRule[];
datatypeRules: ParserRule[];
interfaces: Interface[];
types: Type[];
}
export interface TypeResources {
inferred: PlainAstTypes;
declared: PlainAstTypes;
astResources: AstResources;
}
export interface ValidationAstTypes {
inferred: AstTypes;
declared: AstTypes;
astResources: AstResources;
}
export declare function collectTypeResources(grammars: Grammar | Grammar[], services?: LangiumCoreServices): TypeResources;
export declare function collectAllAstResources(grammars: Grammar | Grammar[], visited?: Set<URI>, astResources?: AstResources, services?: LangiumCoreServices): AstResources;
//# sourceMappingURL=all-types.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"all-types.d.ts","sourceRoot":"","sources":["../../../../src/grammar/type-system/type-collector/all-types.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,qCAAqC,CAAC;AAC3G,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAC7D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACtD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAQ3C,MAAM,WAAW,YAAY;IACzB,WAAW,EAAE,UAAU,EAAE,CAAA;IACzB,UAAU,EAAE,SAAS,EAAE,CAAA;IACvB,aAAa,EAAE,UAAU,EAAE,CAAA;IAC3B,UAAU,EAAE,SAAS,EAAE,CAAA;IACvB,KAAK,EAAE,IAAI,EAAE,CAAA;CAChB;AAED,MAAM,WAAW,aAAa;IAC1B,QAAQ,EAAE,aAAa,CAAA;IACvB,QAAQ,EAAE,aAAa,CAAA;IACvB,YAAY,EAAE,YAAY,CAAA;CAC7B;AAED,MAAM,WAAW,kBAAkB;IAC/B,QAAQ,EAAE,QAAQ,CAAA;IAClB,QAAQ,EAAE,QAAQ,CAAA;IAClB,YAAY,EAAE,YAAY,CAAA;CAC7B;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,EAAE,EAAE,QAAQ,CAAC,EAAE,mBAAmB,GAAG,aAAa,CAUjH;AAID,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,OAAO,GAAG,OAAO,EAAE,EAAE,OAAO,GAAE,GAAG,CAAC,GAAG,CAAa,EAC/F,YAAY,GAAE,YAAgG,EAAE,QAAQ,CAAC,EAAE,mBAAmB,GAAG,YAAY,CA8BhK"}
@@ -0,0 +1,55 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { collectInferredTypes } from './inferred-types.js';
import { collectDeclaredTypes } from './declared-types.js';
import { getDocument } from '../../../utils/ast-utils.js';
import { isInfixRule, isParserRule } from '../../../languages/generated/ast.js';
import { resolveImport } from '../../internal-grammar-util.js';
import { isDataTypeRule } from '../../../utils/grammar-utils.js';
export function collectTypeResources(grammars, services) {
const astResources = collectAllAstResources(grammars, undefined, undefined, services);
const declared = collectDeclaredTypes(astResources.interfaces, astResources.types, services);
const inferred = collectInferredTypes(astResources.parserRules, astResources.datatypeRules, astResources.infixRules, declared, services);
return {
astResources,
inferred,
declared
};
}
///////////////////////////////////////////////////////////////////////////////
export function collectAllAstResources(grammars, visited = new Set(), astResources = { parserRules: [], infixRules: [], datatypeRules: [], interfaces: [], types: [] }, services) {
if (!Array.isArray(grammars))
grammars = [grammars];
for (const grammar of grammars) {
const doc = getDocument(grammar);
if (visited.has(doc.uri)) {
continue;
}
visited.add(doc.uri);
for (const rule of grammar.rules) {
if (isParserRule(rule) && !rule.fragment) {
if (isDataTypeRule(rule)) {
astResources.datatypeRules.push(rule);
}
else {
astResources.parserRules.push(rule);
}
}
else if (isInfixRule(rule)) {
astResources.infixRules.push(rule);
}
}
grammar.interfaces.forEach(e => astResources.interfaces.push(e));
grammar.types.forEach(e => astResources.types.push(e));
const documents = services?.shared.workspace.LangiumDocuments;
if (documents) {
const importedGrammars = grammar.imports.map(e => resolveImport(documents, e)).filter(e => e !== undefined);
collectAllAstResources(importedGrammars, visited, astResources, services);
}
}
return astResources;
}
//# sourceMappingURL=all-types.js.map
@@ -0,0 +1 @@
{"version":3,"file":"all-types.js","sourceRoot":"","sources":["../../../../src/grammar/type-system/type-collector/all-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { Interface, Type, TypeDefinition } from '../../../languages/generated/ast.js';
import type { LangiumCoreServices } from '../../../index.js';
import type { PlainAstTypes, PlainPropertyType } from './plain-types.js';
export declare function collectDeclaredTypes(interfaces: Interface[], unions: Type[], services?: LangiumCoreServices): PlainAstTypes;
export declare function typeDefinitionToPropertyType(type: TypeDefinition): PlainPropertyType;
//# sourceMappingURL=declared-types.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"declared-types.d.ts","sourceRoot":"","sources":["../../../../src/grammar/type-system/type-collector/declared-types.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,cAAc,EAAgB,MAAM,qCAAqC,CAAC;AACzG,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE7D,OAAO,KAAK,EAAE,aAAa,EAA4D,iBAAiB,EAAc,MAAM,kBAAkB,CAAC;AAK/I,wBAAgB,oBAAoB,CAAC,UAAU,EAAE,SAAS,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,QAAQ,CAAC,EAAE,mBAAmB,GAAG,aAAa,CAoD3H;AAYD,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,cAAc,GAAG,iBAAiB,CA8CpF"}
@@ -0,0 +1,124 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { isArrayLiteral, isBooleanLiteral } from '../../../languages/generated/ast.js';
import { isArrayType, isReferenceType, isUnionType, isSimpleType } from '../../../languages/generated/ast.js';
import { getTypeNameWithoutError, isPrimitiveGrammarType } from '../../internal-grammar-util.js';
import { getTypeName } from '../../../utils/grammar-utils.js';
export function collectDeclaredTypes(interfaces, unions, services) {
const commentProvider = services?.documentation.CommentProvider;
const declaredTypes = { unions: [], interfaces: [] };
// add interfaces
for (const type of interfaces) {
const properties = [];
for (const attribute of type.attributes) {
const property = {
name: attribute.name,
optional: attribute.isOptional,
astNodes: new Set([attribute]),
type: typeDefinitionToPropertyType(attribute.type),
comment: commentProvider?.getComment(attribute)
};
if (attribute.defaultValue) {
property.defaultValue = toPropertyDefaultValue(attribute.defaultValue);
}
properties.push(property);
}
const superTypes = new Set();
for (const superType of type.superTypes) {
if (superType.ref) {
superTypes.add(getTypeName(superType.ref));
}
}
const interfaceType = {
name: type.name,
declared: true,
abstract: false,
properties: properties,
superTypes: superTypes,
subTypes: new Set(),
comment: commentProvider?.getComment(type),
};
declaredTypes.interfaces.push(interfaceType);
}
// add types
for (const union of unions) {
const unionType = {
name: union.name,
declared: true,
type: typeDefinitionToPropertyType(union.type),
superTypes: new Set(),
subTypes: new Set(),
comment: commentProvider?.getComment(union),
};
declaredTypes.unions.push(unionType);
}
return declaredTypes;
}
function toPropertyDefaultValue(literal) {
if (isBooleanLiteral(literal)) {
return literal.true;
}
else if (isArrayLiteral(literal)) {
return literal.elements.map(toPropertyDefaultValue);
}
else {
return literal.value;
}
}
export function typeDefinitionToPropertyType(type) {
if (isArrayType(type)) {
return {
elementType: typeDefinitionToPropertyType(type.elementType)
};
}
else if (isReferenceType(type)) {
return {
referenceType: typeDefinitionToPropertyType(type.referenceType),
isMulti: type.isMulti,
isSingle: !type.isMulti
};
}
else if (isUnionType(type)) {
return {
types: type.types.map(typeDefinitionToPropertyType)
};
}
else if (isSimpleType(type)) {
let value;
if (type.primitiveType) {
value = type.primitiveType;
return {
primitive: value
};
}
else if (type.stringType) {
value = type.stringType;
return {
string: value
};
}
else if (type.typeRef) {
const ref = type.typeRef.ref;
const value = getTypeNameWithoutError(ref);
if (value) {
if (isPrimitiveGrammarType(value)) {
return {
primitive: value
};
}
else {
return {
value
};
}
}
}
}
return {
primitive: 'unknown'
};
}
//# sourceMappingURL=declared-types.js.map
@@ -0,0 +1 @@
{"version":3,"file":"declared-types.js","sourceRoot":"","sources":["../../../../src/grammar/type-system/type-collector/declared-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { ParserRule, InfixRule } from '../../../languages/generated/ast.js';
import type { PlainAstTypes } from './plain-types.js';
import type { LangiumCoreServices } from '../../../index.js';
export declare function collectInferredTypes(parserRules: ParserRule[], datatypeRules: ParserRule[], infixRules: InfixRule[], declared: PlainAstTypes, services?: LangiumCoreServices): PlainAstTypes;
//# sourceMappingURL=inferred-types.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"inferred-types.d.ts","sourceRoot":"","sources":["../../../../src/grammar/type-system/type-collector/inferred-types.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,UAAU,EAAiD,SAAS,EAAqC,MAAM,qCAAqC,CAAC;AACnK,OAAO,KAAK,EAAE,aAAa,EAAgE,MAAM,kBAAkB,CAAC;AACpH,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAgQ7D,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,aAAa,EAAE,UAAU,EAAE,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,CAAC,EAAE,mBAAmB,GAAG,aAAa,CA+B5L"}
@@ -0,0 +1,742 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { isNamed } from '../../../references/name-provider.js';
import { MultiMap } from '../../../utils/collections.js';
import { isAlternatives, isKeyword, isParserRule, isAction, isGroup, isUnorderedGroup, isAssignment, isRuleCall, isCrossReference, isTerminalRule, isAbstractParserRule } from '../../../languages/generated/ast.js';
import { getTypeNameWithoutError, isPrimitiveGrammarType } from '../../internal-grammar-util.js';
import { mergePropertyTypes } from './plain-types.js';
import { isOptionalCardinality, terminalRegex, getRuleTypeName, getTypeName } from '../../../utils/grammar-utils.js';
class TypeGraph {
constructor(context, root) {
this.context = context;
this.root = root;
}
getTypes() {
return this.iterate(this.root, [{
alt: {
name: this.root.name,
properties: this.root.properties,
ruleCalls: this.root.ruleCalls,
super: []
},
current: this.root,
next: this.root.children
}]);
}
iterate(root, paths) {
const finished = paths.filter(e => e.next.length === 0);
do {
const next = this.recurse(root, paths);
const unfinished = [];
for (const path of next) {
if (path.next.length > 0) {
unfinished.push(path);
}
else {
finished.push(path);
}
}
paths = unfinished;
} while (paths.length > 0);
return finished;
}
recurse(root, paths, end) {
const all = [];
for (const path of paths) {
const node = path.current;
if (node !== end && node.children.length > 0) {
const nextPaths = this.applyNext(root, path);
const subPaths = this.recurse(root, nextPaths, node.end ?? end);
all.push(...subPaths);
}
else {
all.push(path);
}
}
const map = new MultiMap();
for (const path of all) {
map.add(path.current, path);
}
const unique = [];
for (const [node, groupedPaths] of map.entriesGroupedByKey()) {
unique.push(...flattenTypes(groupedPaths, node));
}
return unique;
}
applyNext(root, nextPath) {
const splits = this.splitType(nextPath.alt, nextPath.next.length);
const paths = [];
for (let i = 0; i < nextPath.next.length; i++) {
const split = splits[i];
const part = nextPath.next[i];
if (part.actionWithAssignment) {
// If the path enters an action with an assignment which changes the current name
// We already add a new path, since the next part of the part refers to a new inferred type
paths.push({
alt: copyTypeAlternative(split),
current: part,
next: [],
comment: split.comment,
});
}
if (part.name !== undefined && part.name !== split.name) {
if (part.actionWithAssignment) {
// We reset all properties, super types and ruleCalls since we are now in a new inferred type
split.properties = [];
split.ruleCalls = [];
split.super = [root.name];
split.name = part.name;
}
else {
split.super = [split.name, ...split.ruleCalls];
split.properties = [];
split.ruleCalls = [];
split.name = part.name;
}
}
split.properties.push(...part.properties);
split.ruleCalls.push(...part.ruleCalls);
const path = {
alt: split,
current: part,
next: part.children,
comment: split.comment
};
path.alt.super = path.alt.super.filter(e => e !== path.alt.name);
paths.push(path);
}
return paths;
}
splitType(type, count) {
const alternatives = [];
for (let i = 0; i < count; i++) {
alternatives.push(copyTypeAlternative(type));
}
return alternatives;
}
getSuperTypes(node) {
const set = new Set();
this.collectSuperTypes(node, node, set);
return Array.from(set);
}
collectSuperTypes(original, part, set) {
if (part.ruleCalls.length > 0) {
// Each unassigned rule call corresponds to a super type
for (const ruleCall of part.ruleCalls) {
set.add(ruleCall);
}
return;
}
for (const parent of part.parents) {
if (original.name === undefined) {
this.collectSuperTypes(parent, parent, set);
}
else if (parent.name !== undefined && parent.name !== original.name) {
set.add(parent.name);
}
else {
this.collectSuperTypes(original, parent, set);
}
}
if (part.parents.length === 0 && part.name) {
set.add(part.name);
}
}
connect(parent, children) {
children.parents.push(parent);
parent.children.push(children);
return children;
}
merge(...parts) {
if (parts.length === 1) {
return parts[0];
}
else if (parts.length === 0) {
throw new Error('No parts to merge');
}
const node = newTypePart();
node.parents = parts;
for (const parent of parts) {
parent.children.push(node);
}
return node;
}
hasLeafNode(part) {
return this.partHasLeafNode(part);
}
partHasLeafNode(part, ignore) {
if (part.children.some(e => e !== ignore)) {
return true;
}
else if (part.name) {
return false;
}
else {
return part.parents.some(e => this.partHasLeafNode(e, part));
}
}
}
function copyTypePart(value) {
return {
name: value.name,
children: [],
parents: [],
actionWithAssignment: value.actionWithAssignment,
ruleCalls: value.ruleCalls.slice(),
properties: value.properties.map(copyProperty),
};
}
function copyTypeAlternative(value) {
return {
name: value.name,
super: value.super,
ruleCalls: value.ruleCalls.slice(),
properties: value.properties.map(e => copyProperty(e)),
comment: value.comment,
};
}
function copyProperty(value) {
return {
name: value.name,
optional: value.optional,
type: value.type,
astNodes: value.astNodes,
comment: value.comment,
};
}
export function collectInferredTypes(parserRules, datatypeRules, infixRules, declared, services) {
const commentProvider = services?.documentation.CommentProvider;
// extract interfaces and types from parser rules
const allTypes = [];
const context = {
fragments: new Map()
};
for (const rule of parserRules) {
const comment = commentProvider?.getComment(rule);
allTypes.push(...getRuleTypes(context, rule, services).map(typePath => ({ ...typePath, comment })));
}
const infixInterfaces = calculateInfixInterfaces(infixRules);
const interfaces = calculateInterfaces(allTypes, infixInterfaces);
const unions = buildSuperUnions(interfaces);
const astTypes = extractUnions(interfaces, unions, declared);
// extract types from datatype rules
for (const rule of datatypeRules) {
const type = getDataRuleType(rule);
astTypes.unions.push({
name: rule.name,
declared: false,
type,
subTypes: new Set(),
superTypes: new Set(),
dataType: rule.dataType,
comment: commentProvider?.getComment(rule),
});
}
return astTypes;
}
function calculateInfixInterfaces(rules) {
const interfaces = [];
for (const infixRule of rules) {
const on = infixRule.call.rule.ref;
const onName = isAbstractParserRule(on) ? getTypeName(on) : on?.name;
if (onName && infixRule.name) {
const operators = infixRule.operators.precedences
.flatMap(e => e.operators).map(e => e.value).sort();
const expressionProperty = {
astNodes: new Set(),
optional: false,
type: {
value: onName
}
};
const interfaceType = {
name: getTypeName(infixRule),
declared: false,
abstract: false,
properties: [
{
...expressionProperty,
name: 'left'
},
{
...expressionProperty,
name: 'right'
},
{
name: 'operator',
astNodes: new Set(),
optional: false,
type: {
types: operators.map(operator => ({
string: operator
}))
}
}
],
subTypes: new Set(),
superTypes: new Set()
};
interfaces.push(interfaceType);
}
}
return interfaces;
}
function getDataRuleType(rule) {
if (rule.dataType && rule.dataType !== 'string') {
return {
primitive: rule.dataType
};
}
let cancelled = false;
const cancel = () => {
cancelled = true;
return {
primitive: 'unknown'
};
};
const type = buildDataRuleType(rule.definition, cancel);
if (cancelled) {
return {
primitive: 'string'
};
}
else {
return type;
}
}
function buildDataRuleType(element, cancel) {
if (element.cardinality) {
// Multiplicity/optionality is not supported for types
return cancel();
}
if (isAlternatives(element)) {
return {
types: element.elements.map(e => buildDataRuleType(e, cancel))
};
}
else if (isGroup(element) || isUnorderedGroup(element)) {
if (element.elements.length !== 1) {
return cancel();
}
else {
return buildDataRuleType(element.elements[0], cancel);
}
}
else if (isRuleCall(element)) {
const ref = element.rule?.ref;
if (ref) {
if (isTerminalRule(ref)) {
let regex;
try {
regex = terminalRegex(ref).toString();
}
catch {
// If the regex cannot be built, we assume it's just a string
regex = undefined;
}
return {
primitive: ref.type?.name ?? 'string',
regex
};
}
else {
return {
value: ref.name
};
}
}
else {
return cancel();
}
}
else if (isKeyword(element)) {
return {
string: element.value
};
}
return cancel();
}
function getRuleTypes(context, rule, services) {
const type = newTypePart(rule);
const graph = new TypeGraph(context, type);
if (rule.definition) {
type.end = collectElement(graph, graph.root, rule.definition, services);
}
return flattenTypes(graph.getTypes(), type.end ?? newTypePart());
}
function newTypePart(element) {
return {
name: isAbstractParserRule(element) || isAction(element) ? getTypeNameWithoutError(element) : element,
properties: [],
ruleCalls: [],
children: [],
parents: [],
actionWithAssignment: false
};
}
/**
* Collects all possible type branches of a given parser rule element.
*
* @param state State to walk over element's graph.
* @param type Element that collects a current type branch for the given element.
* @param element The given AST element, from which it's necessary to extract the type.
*/
function collectElement(graph, current, element, services) {
const optional = isOptionalCardinality(element.cardinality, element);
if (isAlternatives(element)) {
const children = [];
if (optional) {
// Create a new empty node
children.push(graph.connect(current, newTypePart()));
}
for (const alt of element.elements) {
const altType = graph.connect(current, newTypePart());
children.push(collectElement(graph, altType, alt, services));
}
const mergeNode = graph.merge(...children);
current.end = mergeNode;
return mergeNode;
}
else if (isGroup(element) || isUnorderedGroup(element)) {
let groupNode = graph.connect(current, newTypePart());
let skipNode;
if (optional) {
skipNode = graph.connect(current, newTypePart());
}
for (const item of element.elements) {
groupNode = collectElement(graph, groupNode, item, services);
}
if (skipNode) {
const mergeNode = graph.merge(skipNode, groupNode);
current.end = mergeNode;
return mergeNode;
}
else {
return groupNode;
}
}
else if (isAction(element)) {
return addAction(graph, current, element, services);
}
else if (isAssignment(element)) {
addAssignment(current, element, services);
}
else if (isRuleCall(element)) {
addRuleCall(graph, current, element, services);
}
return current;
}
function addAction(graph, parent, action, services) {
const commentProvider = services?.documentation.CommentProvider;
// We create a copy of the current type part
// This is essentially a leaf node of the current type
// Otherwise we might lose information, such as properties
// We do this if there's no leaf node for the current type yet
if (!graph.hasLeafNode(parent)) {
const copy = copyTypePart(parent);
graph.connect(parent, copy);
}
const typeNode = graph.connect(parent, newTypePart(action));
if (action.type) {
const type = action.type?.ref;
if (type && isNamed(type))
// cs: if the (named) type could be resolved properly also set the name on 'typeNode'
// for the sake of completeness and better comprehensibility during debugging,
// it's not supposed to have a effect on the flow of control!
typeNode.name = type.name;
}
if (action.feature && action.operator) {
typeNode.actionWithAssignment = true;
typeNode.properties.push({
name: action.feature,
optional: false,
type: toPropertyType(action.operator === '+=', undefined, graph.root.ruleCalls.length !== 0 ? graph.root.ruleCalls : graph.getSuperTypes(typeNode)),
astNodes: new Set([action]),
comment: commentProvider?.getComment(action),
});
}
return typeNode;
}
function addAssignment(current, assignment, services) {
const commentProvider = services?.documentation.CommentProvider;
const typeItems = { types: new Set() };
findTypes(assignment.terminal, typeItems);
const type = toPropertyType(assignment.operator === '+=', typeItems.reference, assignment.operator === '?=' ? ['boolean'] : Array.from(typeItems.types));
current.properties.push({
name: assignment.feature,
optional: isOptionalCardinality(assignment.cardinality),
type,
astNodes: new Set([assignment]),
comment: commentProvider?.getComment(assignment),
});
}
function findTypes(terminal, types) {
if (isAlternatives(terminal) || isUnorderedGroup(terminal) || isGroup(terminal)) {
for (const element of terminal.elements) {
findTypes(element, types);
}
}
else if (isKeyword(terminal)) {
types.types.add(`'${terminal.value}'`);
}
else if (isRuleCall(terminal) && terminal.rule.ref) {
types.types.add(getRuleTypeName(terminal.rule.ref));
}
else if (isCrossReference(terminal) && terminal.type.ref) {
const refTypeName = getTypeNameWithoutError(terminal.type.ref);
if (refTypeName) {
types.types.add(refTypeName);
}
types.reference ?? (types.reference = {});
if (terminal.isMulti) {
types.reference.isMulti = true;
}
else {
types.reference.isSingle = true;
}
}
}
function addRuleCall(graph, current, ruleCall, services) {
const rule = ruleCall.rule.ref;
// Add all properties of fragments to the current type
if (isParserRule(rule) && rule.fragment) {
const properties = getFragmentProperties(rule, graph.context, services);
if (isOptionalCardinality(ruleCall.cardinality)) {
current.properties.push(...properties.map(e => ({
...e,
optional: true
})));
}
else {
current.properties.push(...properties);
}
}
else if (isAbstractParserRule(rule)) {
current.ruleCalls.push(getRuleTypeName(rule));
}
}
function getFragmentProperties(fragment, context, services) {
const existing = context.fragments.get(fragment);
if (existing) {
return existing;
}
const properties = [];
context.fragments.set(fragment, properties);
const fragmentName = getTypeNameWithoutError(fragment);
const typeAlternatives = getRuleTypes(context, fragment, services).filter(e => e.alt.name === fragmentName);
properties.push(...typeAlternatives.flatMap(e => e.alt.properties));
return properties;
}
/**
* Calculate interfaces from all possible type branches.
* [some of these interfaces will become types in the generated AST]
* @param alternatives The type branches that will be squashed in interfaces.
* @returns Interfaces.
*/
function calculateInterfaces(alternatives, otherInterfaces) {
const interfaces = new Map(otherInterfaces.map(e => [e.name, e]));
const ruleCallAlternatives = [];
const flattened = alternatives.length > 0
? flattenTypes(alternatives, alternatives[0].current).map(e => e.alt)
: [];
for (const flat of flattened) {
const interfaceType = {
name: flat.name,
properties: flat.properties,
superTypes: new Set(flat.super),
subTypes: new Set(),
declared: false,
abstract: false,
comment: flat.comment,
};
interfaces.set(interfaceType.name, interfaceType);
if (flat.ruleCalls.length > 0) {
ruleCallAlternatives.push(flat);
flat.ruleCalls.forEach(e => {
if (e !== interfaceType.name) { // An interface cannot subtype itself
interfaceType.subTypes.add(e);
}
});
}
// all other cases assume we have a data type rule
// we do not generate an AST type for data type rules
}
for (const ruleCallType of ruleCallAlternatives) {
for (const ruleCall of ruleCallType.ruleCalls) {
const calledInterface = interfaces.get(ruleCall);
if (calledInterface) {
if (calledInterface.name !== ruleCallType.name) {
calledInterface.superTypes.add(ruleCallType.name);
}
}
}
}
return Array.from(interfaces.values());
}
function flattenTypes(alternatives, part) {
var _a;
const nameToAlternatives = alternatives.reduce((acc, e) => acc.add(e.alt.name, e), new MultiMap());
const types = [];
for (const [name, namedAlternatives] of nameToAlternatives.entriesGroupedByKey()) {
const properties = [];
const ruleCalls = new Set();
const type = { alt: { name, properties, ruleCalls: [], super: [] }, next: [], current: part };
for (const path of namedAlternatives) {
const alt = path.alt;
type.comment ?? (type.comment = path.comment);
(_a = type.alt).comment ?? (_a.comment = path.comment);
type.alt.super.push(...alt.super);
type.next.push(...path.next);
const altProperties = alt.properties;
for (const altProperty of altProperties) {
const existingProperty = properties.find(e => e.name === altProperty.name);
if (existingProperty) {
existingProperty.type = mergePropertyTypes(existingProperty.type, altProperty.type);
altProperty.astNodes.forEach(e => existingProperty.astNodes.add(e));
}
else {
properties.push({ ...altProperty });
}
}
alt.ruleCalls.forEach(ruleCall => ruleCalls.add(ruleCall));
}
for (const path of namedAlternatives) {
type.next = Array.from(new Set(type.next));
const alt = path.alt;
// A type with rule calls is not a real member of the type
// Any missing properties are therefore not associated with the current type
if (alt.ruleCalls.length === 0) {
for (const property of properties) {
if (!alt.properties.find(e => e.name === property.name)) {
property.optional = true;
}
}
}
}
type.alt.ruleCalls = Array.from(ruleCalls);
types.push(type);
}
return types;
}
function buildSuperUnions(interfaces) {
const interfaceMap = new Map(interfaces.map(e => [e.name, e]));
const unions = [];
const allSupertypes = new MultiMap();
for (const interfaceType of interfaces) {
for (const superType of interfaceType.superTypes) {
allSupertypes.add(superType, interfaceType.name);
}
}
for (const [superType, types] of allSupertypes.entriesGroupedByKey()) {
if (!interfaceMap.has(superType)) {
const union = {
declared: false,
name: superType,
subTypes: new Set(),
superTypes: new Set(),
type: toPropertyType(false, undefined, types)
};
unions.push(union);
}
}
return unions;
}
/**
* Filters interfaces, transforming some of them in unions.
* The transformation criterion: no properties, but have subtypes.
* @param interfaces The interfaces that have to be transformed on demand.
* @returns Types and not transformed interfaces.
*/
function extractUnions(interfaces, unions, declared) {
const subTypes = new MultiMap();
for (const interfaceType of interfaces) {
for (const superTypeName of interfaceType.superTypes) {
subTypes.add(superTypeName, interfaceType.name);
}
}
const declaredInterfaces = new Set(declared.interfaces.map(e => e.name));
const astTypes = { interfaces: [], unions };
const unionTypes = new Map(unions.map(e => [e.name, e]));
for (const interfaceType of interfaces) {
const interfaceSubTypes = new Set(subTypes.get(interfaceType.name));
// Convert an interface into a union type if it has subtypes and no properties on its own
if (interfaceType.properties.length === 0 && interfaceSubTypes.size > 0) {
// In case we have an explicitly declared interface
// Mark the interface as `abstract` and do not create a union type
if (declaredInterfaces.has(interfaceType.name)) {
interfaceType.abstract = true;
astTypes.interfaces.push(interfaceType);
}
else {
const interfaceTypeValue = toPropertyType(false, undefined, Array.from(interfaceSubTypes));
const existingUnion = unionTypes.get(interfaceType.name);
if (existingUnion) {
existingUnion.type = mergePropertyTypes(existingUnion.type, interfaceTypeValue);
}
else {
const unionType = {
name: interfaceType.name,
declared: false,
subTypes: interfaceSubTypes,
superTypes: interfaceType.superTypes,
type: interfaceTypeValue,
comment: interfaceType.comment,
};
astTypes.unions.push(unionType);
unionTypes.set(interfaceType.name, unionType);
}
}
}
else {
astTypes.interfaces.push(interfaceType);
}
}
// After converting some interfaces into union types, these interfaces are no longer valid super types
for (const interfaceType of astTypes.interfaces) {
interfaceType.superTypes = new Set([...interfaceType.superTypes].filter(superType => !unionTypes.has(superType)));
}
return astTypes;
}
function toPropertyType(array, reference, types) {
if (array) {
return {
elementType: toPropertyType(false, reference, types)
};
}
else if (reference) {
const isMulti = reference.isMulti ?? false;
const isSingle = reference.isSingle ?? !isMulti;
return {
referenceType: toPropertyType(false, undefined, types),
isMulti,
isSingle
};
}
else if (types.length === 1) {
const type = types[0];
if (type.startsWith("'")) {
return {
string: type.substring(1, type.length - 1)
};
}
if (isPrimitiveGrammarType(type)) {
return {
primitive: type
};
}
else {
return {
value: type
};
}
}
else {
return {
types: types.map(e => toPropertyType(false, undefined, [e]))
};
}
}
//# sourceMappingURL=inferred-types.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,76 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { Action, Assignment, TypeAttribute } from '../../../languages/generated/ast.js';
import type { AstTypes } from './types.js';
export interface PlainAstTypes {
interfaces: PlainInterface[];
unions: PlainUnion[];
}
export type PlainType = PlainInterface | PlainUnion;
export interface PlainInterface {
name: string;
superTypes: Set<string>;
subTypes: Set<string>;
properties: PlainProperty[];
declared: boolean;
abstract: boolean;
comment?: string;
}
export declare function isPlainInterface(type: PlainType): type is PlainInterface;
export interface PlainUnion {
name: string;
superTypes: Set<string>;
subTypes: Set<string>;
type: PlainPropertyType;
declared: boolean;
dataType?: string;
comment?: string;
}
export declare function isPlainUnion(type: PlainType): type is PlainUnion;
export interface PlainProperty {
name: string;
optional: boolean;
astNodes: Set<Assignment | Action | TypeAttribute>;
type: PlainPropertyType;
defaultValue?: PlainPropertyDefaultValue;
comment?: string;
}
export type PlainPropertyDefaultValue = string | number | boolean | PlainPropertyDefaultValue[];
export type PlainPropertyType = PlainReferenceType | PlainArrayType | PlainPropertyUnion | PlainValueType | PlainPrimitiveType | PlainStringType;
export interface PlainReferenceType {
referenceType: PlainPropertyType;
isMulti: boolean;
isSingle: boolean;
}
export declare function isPlainReferenceType(propertyType: PlainPropertyType): propertyType is PlainReferenceType;
export interface PlainArrayType {
elementType: PlainPropertyType;
}
export declare function isPlainArrayType(propertyType: PlainPropertyType): propertyType is PlainArrayType;
export interface PlainPropertyUnion {
types: PlainPropertyType[];
}
export declare function isPlainPropertyUnion(propertyType: PlainPropertyType): propertyType is PlainPropertyUnion;
export interface PlainValueType {
value: string;
}
export declare function isPlainValueType(propertyType: PlainPropertyType): propertyType is PlainValueType;
export interface PlainPrimitiveType {
primitive: string;
regex?: string;
}
export declare function isPlainPrimitiveType(propertyType: PlainPropertyType): propertyType is PlainPrimitiveType;
export interface PlainStringType {
string: string;
}
export declare function isPlainStringType(propertyType: PlainPropertyType): propertyType is PlainStringType;
export declare function plainToTypes(plain: PlainAstTypes): AstTypes;
export declare function mergePropertyTypes(first: PlainPropertyType, second: PlainPropertyType): PlainPropertyType;
export declare function flattenPlainType(type: PlainPropertyType): {
union: PlainPropertyType[];
array: PlainPropertyType[];
};
//# sourceMappingURL=plain-types.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"plain-types.d.ts","sourceRoot":"","sources":["../../../../src/grammar/type-system/type-collector/plain-types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,220 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { hasBooleanType } from '../types-util.js';
import { InterfaceType, UnionType, isArrayType } from './types.js';
export function isPlainInterface(type) {
return !isPlainUnion(type);
}
export function isPlainUnion(type) {
return 'type' in type;
}
export function isPlainReferenceType(propertyType) {
return 'referenceType' in propertyType;
}
export function isPlainArrayType(propertyType) {
return 'elementType' in propertyType;
}
export function isPlainPropertyUnion(propertyType) {
return 'types' in propertyType;
}
export function isPlainValueType(propertyType) {
return 'value' in propertyType;
}
export function isPlainPrimitiveType(propertyType) {
return 'primitive' in propertyType;
}
export function isPlainStringType(propertyType) {
return 'string' in propertyType;
}
export function plainToTypes(plain) {
const interfaceTypes = new Map();
const unionTypes = new Map();
for (const interfaceValue of plain.interfaces) {
const type = new InterfaceType(interfaceValue.name, interfaceValue.declared, interfaceValue.abstract, interfaceValue.comment);
interfaceTypes.set(interfaceValue.name, type);
}
for (const unionValue of plain.unions) {
const type = new UnionType(unionValue.name, {
declared: unionValue.declared,
dataType: unionValue.dataType,
comment: unionValue.comment,
});
unionTypes.set(unionValue.name, type);
}
for (const interfaceValue of plain.interfaces) {
const type = interfaceTypes.get(interfaceValue.name);
for (const superTypeName of interfaceValue.superTypes) {
const superType = interfaceTypes.get(superTypeName) || unionTypes.get(superTypeName);
if (superType) {
type.superTypes.add(superType);
}
}
for (const subTypeName of interfaceValue.subTypes) {
const subType = interfaceTypes.get(subTypeName) || unionTypes.get(subTypeName);
if (subType) {
type.subTypes.add(subType);
}
}
for (const property of interfaceValue.properties) {
const prop = plainToProperty(property, interfaceTypes, unionTypes);
type.properties.push(prop);
}
}
for (const unionValue of plain.unions) {
const type = unionTypes.get(unionValue.name);
type.type = plainToPropertyType(unionValue.type, type, interfaceTypes, unionTypes);
}
return {
interfaces: Array.from(interfaceTypes.values()),
unions: Array.from(unionTypes.values())
};
}
function plainToProperty(property, interfaces, unions) {
const prop = {
name: property.name,
optional: property.optional,
astNodes: property.astNodes,
type: plainToPropertyType(property.type, undefined, interfaces, unions),
comment: property.comment,
};
if (property.defaultValue !== undefined) {
prop.defaultValue = property.defaultValue;
}
else if (hasBooleanType(prop.type)) {
prop.defaultValue = false;
}
else if (isArrayType(prop.type)) {
prop.defaultValue = [];
}
return prop;
}
function plainToPropertyType(type, union, interfaces, unions) {
if (isPlainArrayType(type)) {
return {
elementType: plainToPropertyType(type.elementType, union, interfaces, unions)
};
}
else if (isPlainReferenceType(type)) {
return {
referenceType: plainToPropertyType(type.referenceType, undefined, interfaces, unions),
isMulti: type.isMulti,
isSingle: type.isSingle
};
}
else if (isPlainPropertyUnion(type)) {
return {
types: type.types.map(e => plainToPropertyType(e, union, interfaces, unions))
};
}
else if (isPlainStringType(type)) {
return {
string: type.string
};
}
else if (isPlainPrimitiveType(type)) {
return {
primitive: type.primitive,
regex: type.regex
};
}
else if (isPlainValueType(type)) {
const value = interfaces.get(type.value) || unions.get(type.value);
if (!value) {
return {
primitive: 'unknown'
};
}
if (union) {
union.subTypes.add(value);
}
return {
value
};
}
else {
throw new Error('Invalid property type');
}
}
export function mergePropertyTypes(first, second) {
const { union: flattenedFirstUnion, array: flattenedFirstArray } = flattenPlainType(first);
const { union: flattenedSecondUnion, array: flattenedSecondArray } = flattenPlainType(second);
const flattenedUnion = mergeTypeUnion(flattenedFirstUnion, flattenedSecondUnion);
const flattenedArray = mergeTypeUnion(flattenedFirstArray, flattenedSecondArray);
if (flattenedArray.length > 0) {
flattenedUnion.push({
elementType: flattenedArray.length === 1 ? flattenedArray[0] : {
types: flattenedArray
}
});
}
if (flattenedUnion.length === 1) {
return flattenedUnion[0];
}
else {
return {
types: flattenedUnion
};
}
}
function mergeTypeUnion(first, second) {
const result = [...first];
for (const type of second) {
if (!includesType(result, type)) {
result.push(type);
}
else if (isPlainReferenceType(type)) {
// Adjust the existing reference type to also include the multi/single flags of the new type
const existing = result.find((e) => isPlainReferenceType(e) && typeEquals(e.referenceType, type.referenceType));
if (existing) {
existing.isMulti || (existing.isMulti = type.isMulti);
existing.isSingle || (existing.isSingle = type.isSingle);
}
}
}
return result;
}
function includesType(list, value) {
return list.some(e => typeEquals(e, value));
}
function typeEquals(first, second) {
if (isPlainArrayType(first) && isPlainArrayType(second)) {
return typeEquals(first.elementType, second.elementType);
}
else if (isPlainReferenceType(first) && isPlainReferenceType(second)) {
return typeEquals(first.referenceType, second.referenceType);
}
else if (isPlainValueType(first) && isPlainValueType(second)) {
return first.value === second.value;
}
else if (isPlainPrimitiveType(first) && isPlainPrimitiveType(second)) {
return first.primitive === second.primitive;
}
else {
return false;
}
}
export function flattenPlainType(type) {
if (isPlainPropertyUnion(type)) {
const flattened = type.types.flatMap(e => flattenPlainType(e));
return {
union: flattened.map(e => e.union).flat(),
array: flattened.map(e => e.array).flat()
};
}
else if (isPlainArrayType(type)) {
return {
array: flattenPlainType(type.elementType).union,
union: []
};
}
else {
return {
array: [],
union: [type]
};
}
}
//# sourceMappingURL=plain-types.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,96 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { CstNode } from '../../../syntax-tree.js';
import type { Action, Assignment, TypeAttribute } from '../../../languages/generated/ast.js';
export interface Property {
name: string;
optional: boolean;
type: PropertyType;
defaultValue?: PropertyDefaultValue;
astNodes: Set<Assignment | Action | TypeAttribute>;
comment?: string;
}
export type PropertyDefaultValue = string | number | boolean | PropertyDefaultValue[];
export type PropertyType = ReferenceType | ArrayType | PropertyUnion | ValueType | PrimitiveType | StringType;
export interface ReferenceType {
referenceType: PropertyType;
isMulti: boolean;
isSingle: boolean;
}
export declare function isReferenceType(propertyType: PropertyType): propertyType is ReferenceType;
export interface ArrayType {
elementType: PropertyType | undefined;
}
export declare function isArrayType(propertyType: PropertyType): propertyType is ArrayType;
export interface PropertyUnion {
types: PropertyType[];
}
export declare function isPropertyUnion(propertyType: PropertyType): propertyType is PropertyUnion;
export declare function flattenPropertyUnion(propertyType: PropertyType): PropertyType[];
export interface ValueType {
value: TypeOption;
}
export declare function isValueType(propertyType: PropertyType): propertyType is ValueType;
export interface PrimitiveType {
primitive: string;
regex?: string;
}
export declare function isPrimitiveType(propertyType: PropertyType): propertyType is PrimitiveType;
export interface StringType {
string: string;
}
export declare function isStringType(propertyType: PropertyType): propertyType is StringType;
export type AstTypes = {
interfaces: InterfaceType[];
unions: UnionType[];
};
export declare function isUnionType(type: TypeOption): type is UnionType;
export declare function isInterfaceType(type: TypeOption): type is InterfaceType;
export type TypeOption = InterfaceType | UnionType;
export declare class UnionType {
name: string;
type: PropertyType;
superTypes: Set<TypeOption>;
subTypes: Set<TypeOption>;
typeNames: Set<string>;
declared: boolean;
dataType?: string;
comment?: string;
constructor(name: string, options?: {
declared: boolean;
dataType?: string;
comment?: string;
});
toAstTypesString(reflectionInfo: boolean): string;
toDeclaredTypesString(reservedWords: Set<string>): string;
}
export declare class InterfaceType {
name: string;
comment?: string;
superTypes: Set<TypeOption>;
subTypes: Set<TypeOption>;
containerTypes: Set<TypeOption>;
typeNames: Set<string>;
declared: boolean;
abstract: boolean;
properties: Property[];
get superProperties(): Property[];
private getSuperProperties;
get allProperties(): Property[];
private getSubTypeProperties;
get interfaceSuperTypes(): InterfaceType[];
constructor(name: string, declared: boolean, abstract: boolean, comment?: string);
toAstTypesString(reflectionInfo: boolean): string;
toDeclaredTypesString(reservedWords: Set<string>): string;
}
export declare class TypeResolutionError extends Error {
readonly target: CstNode | undefined;
constructor(message: string, target: CstNode | undefined);
}
export declare function isTypeAssignable(from: PropertyType, to: PropertyType): boolean;
export declare function propertyTypeToString(type?: PropertyType, mode?: 'AstType' | 'DeclaredType'): string;
export declare function isMandatoryPropertyType(propertyType: PropertyType): boolean;
//# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../../src/grammar/type-system/type-collector/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,503 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { expandToNode, expandToStringWithNL, joinToNode, toString } from '../../../generate/index.js';
import { distinctAndSorted, escapeQuotes } from '../types-util.js';
export function isReferenceType(propertyType) {
return 'referenceType' in propertyType;
}
export function isArrayType(propertyType) {
return 'elementType' in propertyType;
}
export function isPropertyUnion(propertyType) {
return 'types' in propertyType;
}
export function flattenPropertyUnion(propertyType) {
if (isPropertyUnion(propertyType)) {
const items = [];
for (const type of propertyType.types) {
items.push(...flattenPropertyUnion(type));
}
return items;
}
else {
return [propertyType];
}
}
export function isValueType(propertyType) {
return 'value' in propertyType;
}
export function isPrimitiveType(propertyType) {
return 'primitive' in propertyType;
}
export function isStringType(propertyType) {
return 'string' in propertyType;
}
export function isUnionType(type) {
return type && 'type' in type;
}
export function isInterfaceType(type) {
return type && 'properties' in type;
}
export class UnionType {
constructor(name, options) {
this.superTypes = new Set();
this.subTypes = new Set();
this.typeNames = new Set();
this.name = name;
this.declared = options?.declared ?? false;
this.dataType = options?.dataType;
this.comment = options?.comment;
}
toAstTypesString(reflectionInfo) {
const unionNode = expandToNode `${this.comment}`
.appendNewLineIfNotEmpty()
.append(`export type ${this.name} = ${propertyTypeToString(this.type, 'AstType')};`)
.appendNewLine();
if (reflectionInfo) {
unionNode.appendNewLine()
.append(addReflectionInfo(this.name));
}
if (this.dataType) {
unionNode.appendNewLine()
.append(addDataTypeReflectionInfo(this));
}
return toString(unionNode);
}
toDeclaredTypesString(reservedWords) {
return expandToStringWithNL `
type ${escapeReservedWords(this.name, reservedWords)} = ${propertyTypeToString(this.type, 'DeclaredType')};
`;
}
}
export class InterfaceType {
get superProperties() {
return this.getSuperProperties(new Set());
}
getSuperProperties(visited) {
if (visited.has(this.name)) {
return [];
}
else {
visited.add(this.name);
}
const map = new Map();
for (const property of this.properties) {
map.set(property.name, property);
}
for (const superType of this.interfaceSuperTypes) {
const allSuperProperties = superType.getSuperProperties(visited);
for (const superProp of allSuperProperties) {
if (!map.has(superProp.name)) {
map.set(superProp.name, superProp);
}
}
}
return Array.from(map.values());
}
get allProperties() {
const map = new Map(this.superProperties.map(e => [e.name, e]));
for (const subType of this.subTypes) {
this.getSubTypeProperties(subType, map, new Set());
}
const superProps = Array.from(map.values());
return superProps;
}
getSubTypeProperties(type, map, visited) {
if (visited.has(this.name)) {
return;
}
else {
visited.add(this.name);
}
const props = isInterfaceType(type) ? type.properties : [];
for (const prop of props) {
if (!map.has(prop.name)) {
map.set(prop.name, prop);
}
}
for (const subType of type.subTypes) {
this.getSubTypeProperties(subType, map, visited);
}
}
get interfaceSuperTypes() {
return Array.from(this.superTypes).filter(e => e instanceof InterfaceType);
}
constructor(name, declared, abstract, comment) {
this.superTypes = new Set();
this.subTypes = new Set();
this.containerTypes = new Set();
this.typeNames = new Set();
this.declared = false;
this.abstract = false;
this.properties = [];
this.name = name;
this.declared = declared;
this.abstract = abstract;
this.comment = comment;
}
toAstTypesString(reflectionInfo) {
const interfaceSuperTypes = this.interfaceSuperTypes.map(e => e.name);
const superTypes = interfaceSuperTypes.length > 0 ? distinctAndSorted([...interfaceSuperTypes]) : ['langium.AstNode'];
const interfaceNode = expandToNode `${this.comment}`
.appendNewLineIfNotEmpty()
.append(`export interface ${this.name} extends ${superTypes.join(', ')} {`)
.appendNewLine();
interfaceNode.indent(body => {
if (this.containerTypes.size > 0) {
body.append(`readonly $container: ${distinctAndSorted([...this.containerTypes].map(e => e.name)).join(' | ')};`).appendNewLine();
}
if (this.typeNames.size > 0) {
body.append(`readonly $type: ${distinctAndSorted([...this.typeNames]).map(e => `'${e}'`).join(' | ')};`).appendNewLine();
}
body.append(pushProperties(this.properties, 'AstType'));
});
interfaceNode.append('}').appendNewLine();
if (reflectionInfo) {
interfaceNode
.appendNewLine()
.append(addReflectionInfo(this.name, this.superProperties));
}
return toString(interfaceNode);
}
toDeclaredTypesString(reservedWords) {
const name = escapeReservedWords(this.name, reservedWords);
const superTypes = distinctAndSorted(this.interfaceSuperTypes.map(e => e.name)).join(', ');
return toString(expandToNode `
interface ${name}${superTypes.length > 0 ? ` extends ${superTypes}` : ''} {
${pushProperties(this.properties, 'DeclaredType')}
}
`.appendNewLine());
}
}
export class TypeResolutionError extends Error {
constructor(message, target) {
super(message);
this.name = 'TypeResolutionError';
this.target = target;
}
}
export function isTypeAssignable(from, to) {
return isTypeAssignableInternal(from, to, new Map());
}
function isTypeAssignableInternal(from, to, visited) {
if (!from) {
return true;
}
else if (!to) {
return false;
}
const key = `${propertyTypeToKeyString(from)}»${propertyTypeToKeyString(to)}`;
let result = visited.get(key);
if (result !== undefined) {
return result;
}
visited.set(key, false);
result = false;
if (isPropertyUnion(from)) {
result = from.types.every(fromType => isTypeAssignableInternal(fromType, to, visited));
}
else if (isPropertyUnion(to)) {
result = to.types.some(toType => isTypeAssignableInternal(from, toType, visited));
}
else if (isReferenceType(from)) {
result = isReferenceType(to)
&& from.isMulti === to.isMulti
&& from.isSingle === to.isSingle
&& isTypeAssignableInternal(from.referenceType, to.referenceType, visited);
}
else if (isArrayType(from)) {
result = isArrayType(to) && isTypeAssignableInternal(from.elementType, to.elementType, visited);
}
else if (isValueType(from)) {
if (isUnionType(from.value)) {
if (from.value.dataType) {
// We can test the primitive data type directly
// This potentially skips a expensive recursive call
// This also helps in case the computed internal data type does not fit the declared data type
const primitiveType = {
primitive: from.value.dataType
};
result = isTypeAssignableInternal(primitiveType, to, visited);
}
if (!result) {
result = isTypeAssignableInternal(from.value.type, to, visited);
}
}
else if (!isValueType(to)) {
result = false;
}
else if (isUnionType(to.value)) {
result = isTypeAssignableInternal(from, to.value.type, visited);
}
else {
result = isInterfaceAssignable(from.value, to.value, new Set());
}
}
else if (isValueType(to) && isUnionType(to.value)) {
if (isValueType(from) && isUnionType(from.value) && to.value.name === from.value.name) {
result = true;
}
else {
result = isTypeAssignableInternal(from, to.value.type, visited);
}
}
else if (isPrimitiveType(from)) {
result = isPrimitiveType(to) && from.primitive === to.primitive;
}
else if (isStringType(from)) {
result = (isPrimitiveType(to) && to.primitive === 'string') || (isStringType(to) && to.string === from.string);
}
if (result) {
visited.set(key, result);
}
return result;
}
function isInterfaceAssignable(from, to, visited) {
const key = from.name;
if (visited.has(key)) {
return false;
}
else {
visited.add(key);
}
if (from.name === to.name) {
return true;
}
for (const superType of from.superTypes) {
if (isInterfaceType(superType) && isInterfaceAssignable(superType, to, visited)) {
return true;
}
}
return false;
}
function propertyTypeToKeyString(type) {
if (isReferenceType(type)) {
return `@(${propertyTypeToKeyString(type.referenceType)})${type.isMulti ? '*' : ''}`;
}
else if (isArrayType(type)) {
return type.elementType ? `(${propertyTypeToKeyString(type.elementType)})[]` : 'unknown[]';
}
else if (isPropertyUnion(type)) {
const union = type.types.map(e => propertyTypeToKeyString(e)).join(' | ');
if (type.types.length <= 1) {
return `Union<${union}>`;
}
return union;
}
else if (isValueType(type)) {
return `Value<${type.value.name}>`;
}
else if (isPrimitiveType(type)) {
return type.primitive;
}
else if (isStringType(type)) {
return `'${type.string}'`;
}
throw new Error('Invalid type');
}
export function propertyTypeToString(type, mode = 'AstType') {
if (!type) {
return 'unknown';
}
if (isReferenceType(type)) {
const refType = propertyTypeToString(type.referenceType, mode);
return mode === 'AstType' ? `langium.${type.isMulti ? 'Multi' : ''}Reference<${refType}>` : `@${typeParenthesis(type.referenceType, refType)}${type.isMulti ? '+' : ''}`;
}
else if (isArrayType(type)) {
const arrayType = propertyTypeToString(type.elementType, mode);
return mode === 'AstType' ? `Array<${arrayType}>` : `${type.elementType ? typeParenthesis(type.elementType, arrayType) : 'unknown'}[]`;
}
else if (isPropertyUnion(type)) {
const types = type.types.map(e => typeParenthesis(e, propertyTypeToString(e, mode)));
return distinctAndSorted(types).join(' | ');
}
else if (isValueType(type)) {
return type.value.name;
}
else if (isPrimitiveType(type)) {
return type.primitive;
}
else if (isStringType(type)) {
const delimiter = mode === 'AstType' ? "'" : '"';
return `${delimiter}${escapeQuotes(type.string, delimiter)}${delimiter}`;
}
throw new Error('Invalid type');
}
function typeParenthesis(type, name) {
const needsParenthesis = isPropertyUnion(type);
if (needsParenthesis) {
name = `(${name})`;
}
return name;
}
function pushProperties(properties, mode) {
function propertyToNode(property) {
// We don't need to escape reserved words in the property name
// The parser will be able to handle it just fine
const name = property.name;
const optional = property.optional && !isMandatoryPropertyType(property.type);
const propType = propertyTypeToString(property.type, mode);
return expandToNode `${property.comment}`
.appendNewLineIfNotEmpty()
.append(`${name}${optional ? '?' : ''}: ${propType};`);
}
return joinToNode(distinctAndSorted(properties, (a, b) => a.name.localeCompare(b.name)), propertyToNode, { appendNewLineIfNotEmpty: true });
}
export function isMandatoryPropertyType(propertyType) {
if (isArrayType(propertyType)) {
return true;
}
else if (isReferenceType(propertyType)) {
return false;
}
else if (isPropertyUnion(propertyType)) {
return propertyType.types.every(e => isMandatoryPropertyType(e));
}
else if (isPrimitiveType(propertyType)) {
const value = propertyType.primitive;
return value === 'boolean';
}
else {
return false;
}
}
function addReflectionInfo(name, properties = []) {
return expandToNode `
export const ${name} = {
$type: '${name}'${properties.length > 0 ? ',' : ''}
${joinToNode(properties.sort((a, b) => a.name.localeCompare(b.name)), prop => `${prop.name}: '${escapeQuotes(prop.name, "'")}'`, { separator: ',', appendNewLineIfNotEmpty: true })}
} as const;
export function is${name}(item: unknown): item is ${name} {
return reflection.isInstance(item, ${name}.$type);
}
`.appendNewLine();
}
function addDataTypeReflectionInfo(union) {
switch (union.dataType) {
case 'string':
if (containsOnlyStringTypes(union.type)) {
const subTypes = Array.from(union.subTypes).map(e => e.name);
const strings = collectStringValuesFromDataType(union.type);
const regexes = collectRegexesFromDataType(union.type);
if (subTypes.length === 0 && strings.length === 0 && regexes.length === 0) {
return generateIsDataTypeFunction(union.name, `typeof item === '${union.dataType}'`);
}
else {
const returnString = createDataTypeCheckerFunctionReturnString(subTypes, strings, regexes);
return generateIsDataTypeFunction(union.name, returnString);
}
}
return;
case 'number':
case 'boolean':
case 'bigint':
return generateIsDataTypeFunction(union.name, `typeof item === '${union.dataType}'`);
case 'Date':
return generateIsDataTypeFunction(union.name, 'item instanceof Date');
default:
return;
}
}
function containsOnlyStringTypes(propertyType) {
let result = true;
if (isPrimitiveType(propertyType)) {
if (propertyType.primitive === 'string') {
return true;
}
else {
return false;
}
}
else if (isStringType(propertyType)) {
return true;
}
else if (!isPropertyUnion(propertyType)) {
return false;
}
else {
for (const type of propertyType.types) {
if (isValueType(type)) {
if (isUnionType(type.value)) {
if (!containsOnlyStringTypes(type.value.type)) {
return false;
}
}
else {
return false;
}
}
else if (isPrimitiveType(type)) {
if (type.primitive !== 'string' || !type.regex) {
return false;
}
}
else if (isPropertyUnion(type)) {
result = containsOnlyStringTypes(type);
}
else if (!isStringType(type)) {
return false;
}
}
}
return result;
}
function createDataTypeCheckerFunctionReturnString(subTypes, strings, regexes) {
const allArray = [
...subTypes.map(e => `is${e}(item)`),
...strings.map(e => `item === '${e}'`)
];
if (regexes.length > 0) {
const joinedRegexes = regexes.map(e => `${e}.test(item)`).join(' || ');
allArray.push(`(typeof item === 'string' && (${joinedRegexes}))`);
}
return allArray.join(' || ');
}
function escapeReservedWords(name, reserved) {
return reserved.has(name) ? `^${name}` : name;
}
function collectStringValuesFromDataType(propertyType) {
const values = [];
if (isStringType(propertyType)) {
return [propertyType.string];
}
if (isPropertyUnion(propertyType)) {
for (const type of propertyType.types) {
if (isStringType(type)) {
values.push(type.string);
}
else if (isPropertyUnion(type)) {
values.push(...collectStringValuesFromDataType(type));
}
}
}
return values;
}
function collectRegexesFromDataType(propertyType) {
const regexes = [];
if (isPrimitiveType(propertyType) && propertyType.primitive === 'string' && propertyType.regex) {
regexes.push(propertyType.regex);
}
if (isPropertyUnion(propertyType)) {
for (const type of propertyType.types) {
if (isPrimitiveType(type) && type.primitive === 'string' && type.regex) {
regexes.push(type.regex);
}
else if (isPropertyUnion(type)) {
regexes.push(...collectRegexesFromDataType(type));
}
}
}
return regexes;
}
function generateIsDataTypeFunction(unionName, returnString) {
return expandToNode `
export function is${unionName}(item: unknown): item is ${unionName} {
return ${returnString};
}
`.appendNewLine();
}
//# sourceMappingURL=types.js.map
File diff suppressed because one or more lines are too long
+34
View File
@@ -0,0 +1,34 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { References } from '../../references/references.js';
import type { AstNodeLocator } from '../../workspace/ast-node-locator.js';
import type { LangiumDocuments } from '../../workspace/documents.js';
import type { Interface, Type, AbstractType } from '../../languages/generated/ast.js';
import type { PlainInterface, PlainProperty } from './type-collector/plain-types.js';
import type { AstTypes, InterfaceType, PropertyType, TypeOption } from './type-collector/types.js';
import { MultiMap } from '../../utils/collections.js';
/**
* Collects all properties of all interface types. Includes super type properties.
* @param interfaces A topologically sorted array of interfaces.
*/
export declare function collectAllPlainProperties(interfaces: PlainInterface[]): MultiMap<string, PlainProperty>;
export declare function distinctAndSorted<T>(list: T[], compareFn?: (a: T, b: T) => number): T[];
export declare function collectChildrenTypes(interfaceNode: Interface, references: References, langiumDocuments: LangiumDocuments, nodeLocator: AstNodeLocator): Set<Interface | Type>;
export declare function collectTypeHierarchy(types: TypeOption[]): {
superTypes: MultiMap<string, string>;
subTypes: MultiMap<string, string>;
};
export declare function collectSuperTypes(ruleNode: AbstractType): Set<Interface>;
export declare function mergeInterfaces(inferred: AstTypes, declared: AstTypes): InterfaceType[];
export declare function mergeTypesAndInterfaces(astTypes: AstTypes): TypeOption[];
export declare function hasArrayType(type: PropertyType): boolean;
export declare function hasBooleanType(type: PropertyType): boolean;
export declare function findReferenceTypes(type: PropertyType): string[];
export declare function findAstTypes(type: PropertyType): string[];
export declare function isAstType(type: PropertyType): boolean;
export declare function isAstTypeInternal(type: PropertyType, visited: Map<PropertyType, boolean>): boolean;
export declare function escapeQuotes(str: string, type?: '"' | "'"): string;
//# sourceMappingURL=types-util.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"types-util.d.ts","sourceRoot":"","sources":["../../../src/grammar/type-system/types-util.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qCAAqC,CAAC;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,YAAY,EAAkB,MAAM,kCAAkC,CAAC;AACtG,OAAO,KAAK,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,iCAAiC,CAAC;AACrF,OAAO,KAAK,EAAE,QAAQ,EAAE,aAAa,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AACnG,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AAItD;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,UAAU,EAAE,cAAc,EAAE,GAAG,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC,CAcvG;AAED,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,EAAE,SAAS,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,KAAK,MAAM,GAAG,CAAC,EAAE,CAEvF;AAED,wBAAgB,oBAAoB,CAAC,aAAa,EAAE,SAAS,EAAE,UAAU,EAAE,UAAU,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,WAAW,EAAE,cAAc,GAAG,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,CAmB7K;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG;IACvD,UAAU,EAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IACpC,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CACrC,CA+BA;AAED,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,YAAY,GAAG,GAAG,CAAC,SAAS,CAAC,CAuBxE;AAcD,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,GAAG,aAAa,EAAE,CAEvF;AAED,wBAAgB,uBAAuB,CAAC,QAAQ,EAAE,QAAQ,GAAG,UAAU,EAAE,CAExE;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAQxD;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAQ1D;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,EAAE,CAY/D;AAED,wBAAgB,YAAY,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,EAAE,CAEzD;AAuBD,wBAAgB,SAAS,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAErD;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,GAAG,CAAC,YAAY,EAAE,OAAO,CAAC,GAAG,OAAO,CAyBlG;AAED,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,GAAE,GAAG,GAAG,GAAS,GAAG,MAAM,CAMvE"}
+227
View File
@@ -0,0 +1,227 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { MultiMap } from '../../utils/collections.js';
import { isInterface, isType, isUnionType, isSimpleType } from '../../languages/generated/ast.js';
import { isArrayType, isPrimitiveType, isPropertyUnion, isReferenceType, isValueType } from './type-collector/types.js';
/**
* Collects all properties of all interface types. Includes super type properties.
* @param interfaces A topologically sorted array of interfaces.
*/
export function collectAllPlainProperties(interfaces) {
const map = new MultiMap();
for (const interfaceType of interfaces) {
map.addAll(interfaceType.name, interfaceType.properties);
}
for (const interfaceType of interfaces) {
for (const superType of interfaceType.superTypes) {
const superTypeProperties = map.get(superType);
if (superTypeProperties) {
map.addAll(interfaceType.name, superTypeProperties);
}
}
}
return map;
}
export function distinctAndSorted(list, compareFn) {
return Array.from(new Set(list)).sort(compareFn);
}
export function collectChildrenTypes(interfaceNode, references, langiumDocuments, nodeLocator) {
const childrenTypes = new Set();
childrenTypes.add(interfaceNode);
const refs = references.findReferences(interfaceNode, {});
for (const ref of refs) {
const doc = langiumDocuments.getDocument(ref.sourceUri);
if (!doc) {
continue;
}
const astNode = nodeLocator.getAstNode(doc.parseResult.value, ref.sourcePath);
if (isInterface(astNode)) {
childrenTypes.add(astNode);
const childrenOfInterface = collectChildrenTypes(astNode, references, langiumDocuments, nodeLocator);
childrenOfInterface.forEach(child => childrenTypes.add(child));
}
else if (astNode && isType(astNode.$container)) {
childrenTypes.add(astNode.$container);
}
}
return childrenTypes;
}
export function collectTypeHierarchy(types) {
const allTypes = new Set(types);
const duplicateSuperTypes = new MultiMap();
const duplicateSubTypes = new MultiMap();
for (const type of allTypes) {
for (const superType of type.superTypes) {
if (allTypes.has(superType)) {
duplicateSuperTypes.add(type.name, superType.name);
duplicateSubTypes.add(superType.name, type.name);
}
}
for (const subType of type.subTypes) {
if (allTypes.has(subType)) {
duplicateSuperTypes.add(subType.name, type.name);
duplicateSubTypes.add(type.name, subType.name);
}
}
}
const superTypes = new MultiMap();
const subTypes = new MultiMap();
// Deduplicate and sort
for (const [name, superTypeList] of Array.from(duplicateSuperTypes.entriesGroupedByKey()).sort(([aName], [bName]) => aName.localeCompare(bName))) {
superTypes.addAll(name, Array.from(new Set(superTypeList)));
}
for (const [name, subTypeList] of Array.from(duplicateSubTypes.entriesGroupedByKey()).sort(([aName], [bName]) => aName.localeCompare(bName))) {
subTypes.addAll(name, Array.from(new Set(subTypeList)));
}
return {
superTypes,
subTypes
};
}
export function collectSuperTypes(ruleNode) {
const superTypes = new Set();
if (isInterface(ruleNode)) {
superTypes.add(ruleNode);
ruleNode.superTypes.forEach(superType => {
if (isInterface(superType.ref)) {
superTypes.add(superType.ref);
const collectedSuperTypes = collectSuperTypes(superType.ref);
for (const superType of collectedSuperTypes) {
superTypes.add(superType);
}
}
});
}
else if (isType(ruleNode)) {
const usedTypes = collectUsedTypes(ruleNode.type);
for (const usedType of usedTypes) {
const collectedSuperTypes = collectSuperTypes(usedType);
for (const superType of collectedSuperTypes) {
superTypes.add(superType);
}
}
}
return superTypes;
}
function collectUsedTypes(typeDefinition) {
if (isUnionType(typeDefinition)) {
return typeDefinition.types.flatMap(e => collectUsedTypes(e));
}
else if (isSimpleType(typeDefinition)) {
const value = typeDefinition.typeRef?.ref;
if (isType(value) || isInterface(value)) {
return [value];
}
}
return [];
}
export function mergeInterfaces(inferred, declared) {
return inferred.interfaces.concat(declared.interfaces);
}
export function mergeTypesAndInterfaces(astTypes) {
return astTypes.interfaces.concat(astTypes.unions);
}
export function hasArrayType(type) {
if (isPropertyUnion(type)) {
return type.types.some(e => hasArrayType(e));
}
else if (isArrayType(type)) {
return true;
}
else {
return false;
}
}
export function hasBooleanType(type) {
if (isPropertyUnion(type)) {
return type.types.some(e => hasBooleanType(e));
}
else if (isPrimitiveType(type)) {
return type.primitive === 'boolean';
}
else {
return false;
}
}
export function findReferenceTypes(type) {
if (isPropertyUnion(type)) {
return type.types.flatMap(e => findReferenceTypes(e));
}
else if (isReferenceType(type)) {
const refType = type.referenceType;
if (isValueType(refType)) {
return [refType.value.name];
}
}
else if (isArrayType(type)) {
return type.elementType ? findReferenceTypes(type.elementType) : [];
}
return [];
}
export function findAstTypes(type) {
return findAstTypesInternal(type, new Set());
}
function findAstTypesInternal(type, visited) {
if (visited.has(type)) {
return [];
}
else {
visited.add(type);
}
if (isPropertyUnion(type)) {
return type.types.flatMap(e => findAstTypesInternal(e, visited));
}
else if (isValueType(type)) {
const value = type.value;
if ('type' in value) {
return findAstTypesInternal(value.type, visited);
}
else {
return [value.name];
}
}
else if (isArrayType(type)) {
return type.elementType ? findAstTypesInternal(type.elementType, visited) : [];
}
return [];
}
export function isAstType(type) {
return isAstTypeInternal(type, new Map());
}
export function isAstTypeInternal(type, visited) {
if (visited.has(type)) {
return visited.get(type);
}
// This is supposed to prevent infinite recursion.
// Setting this to true is a pretty safe assumption.
// Setting it to false might lead to false negatives for property unions.
visited.set(type, true);
let result = false;
if (isPropertyUnion(type)) {
result = type.types.every(e => isAstTypeInternal(e, visited));
}
else if (isValueType(type)) {
const value = type.value;
if ('type' in value) {
result = isAstTypeInternal(value.type, visited);
}
else {
// Is definitely an interface type
result = true;
}
}
visited.set(type, result);
return result;
}
export function escapeQuotes(str, type = '"') {
if (type === '"') {
return str.replace(/"/g, '\\"');
}
else {
return str.replace(/'/g, "\\'");
}
}
//# sourceMappingURL=types-util.js.map
File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More