完成世界书、骰子、apiconfig页面处理

This commit is contained in:
2026-04-30 01:35:10 +08:00
parent a3e3711b2b
commit ba9b925c32
4602 changed files with 785225 additions and 23 deletions

View File

@@ -0,0 +1,59 @@
/******************************************************************************
* 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.
******************************************************************************/
/**
* A `Module<I>` is a description of possibly grouped service factories.
*
* Given a type I = { group: { service: A } },
* Module<I> := { group: { service: (injector: I) => A } }
*
* Making `I` available during the creation of `I` allows us to create cyclic
* dependencies.
*/
export type Module<I, T = I> = {
[K in keyof T]: Module<I, T[K]> | ((injector: I) => T[K]);
};
export declare namespace Module {
/**
* Merges two dependency injection modules into a new (third) one that is returned.
* At that `m1` and `m2` stay unchanged. Therefore, `m1` is deep-copied first,
* and m2 is merged onto the copy afterwards.
*
* Note that the leaf values of `m1` and `m2`, i.e. the service constructor functions,
* cannot be copied generically, since they are functions. They are shared by the source and merged modules.
*
* @returns the merged module being a deep copy of `m1` with `m2` merged onto it.
*/
const merge: <M1, M2, R extends M1 & M2>(m1: Module<R, M1>, m2: Module<R, M2>) => Module<R, M1 & M2>;
}
/**
* Given a set of modules, the inject function returns a lazily evaluated injector
* that injects dependencies into the requested service when it is requested the
* first time. Subsequent requests will return the same service.
*
* In the case of cyclic dependencies, an Error will be thrown. This can be fixed
* by injecting a provider `() => T` instead of a `T`.
*
* Please note that the arguments may be objects or arrays. However, the result will
* be an object. Using it with for..of will have no effect.
*
* @param module1 first Module
* @param module2 (optional) second Module
* @param module3 (optional) third Module
* @param module4 (optional) fourth Module
* @param module5 (optional) fifth Module
* @param module6 (optional) sixth Module
* @param module7 (optional) seventh Module
* @param module8 (optional) eighth Module
* @param module9 (optional) ninth Module
* @returns a new object of type I
*/
export declare function inject<I1, I2, I3, I4, I5, I6, I7, I8, I9, I extends I1 & I2 & I3 & I4 & I5 & I6 & I7 & I8 & I9>(module1: Module<I, I1>, module2?: Module<I, I2>, module3?: Module<I, I3>, module4?: Module<I, I4>, module5?: Module<I, I5>, module6?: Module<I, I6>, module7?: Module<I, I7>, module8?: Module<I, I8>, module9?: Module<I, I9>): I;
/**
* Eagerly load all services in the given dependency injection container. This is sometimes
* necessary because services can register event listeners in their constructors.
*/
export declare function eagerLoad<T>(item: T): T;
//# sourceMappingURL=dependency-injection.d.ts.map

View File

@@ -0,0 +1,19 @@
/******************************************************************************
* 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 { isAstNodeWithComment } from '../serializer/json-serializer.js';
import { findCommentNode } from '../utils/cst-utils.js';
export class DefaultCommentProvider {
constructor(services) {
this.grammarConfig = () => services.parser.GrammarConfig;
}
getComment(node) {
if (isAstNodeWithComment(node)) {
return node.$comment;
}
return findCommentNode(node.$cstNode, this.grammarConfig().multilineCommentRules)?.text;
}
}
//# sourceMappingURL=comment-provider.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"documentation-provider.d.ts","sourceRoot":"","sources":["../../src/documentation/documentation-provider.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAC1D,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AACrE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAI3C;;GAEG;AACH,MAAM,WAAW,qBAAqB;IAClC;;;;OAIG;IACH,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;CACvD;AAED,qBAAa,0BAA2B,YAAW,qBAAqB;IAEpE,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IAC9C,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,eAAe,CAAC;gBAExC,QAAQ,EAAE,mBAAmB;IAKzC,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS;IAgBnD,SAAS,CAAC,yBAAyB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS;IAYrG,SAAS,CAAC,wBAAwB,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS;IAKtF,SAAS,CAAC,sBAAsB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAmB7F,SAAS,CAAC,qBAAqB,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;CAI/F"}

View File

@@ -0,0 +1,9 @@
/******************************************************************************
* 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.
******************************************************************************/
export * from './comment-provider.js';
export * from './documentation-provider.js';
export * from './jsdoc.js';
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1,93 @@
/******************************************************************************
* 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 { Position, Range } from 'vscode-languageserver-types';
import type { CstNode } from '../syntax-tree.js';
export interface JSDocComment extends JSDocValue {
readonly elements: JSDocElement[];
getTag(name: string): JSDocTag | undefined;
getTags(name: string): JSDocTag[];
}
export type JSDocElement = JSDocParagraph | JSDocTag;
export type JSDocInline = JSDocTag | JSDocLine;
export interface JSDocValue {
/**
* Represents the range that this JSDoc element occupies.
* If the JSDoc was parsed from a `CstNode`, the range will represent the location in the source document.
*/
readonly range: Range;
/**
* Renders this JSDoc element to a plain text representation.
*/
toString(): string;
/**
* Renders this JSDoc element to a markdown representation.
*
* @param options Rendering options to customize the markdown result.
*/
toMarkdown(options?: JSDocRenderOptions): string;
}
export interface JSDocParagraph extends JSDocValue {
readonly inlines: JSDocInline[];
}
export interface JSDocLine extends JSDocValue {
readonly text: string;
}
export interface JSDocTag extends JSDocValue {
readonly name: string;
readonly content: JSDocParagraph;
readonly inline: boolean;
}
export interface JSDocParseOptions {
/**
* The start symbol of your comment format. Defaults to `/**`.
*/
readonly start?: RegExp | string;
/**
* The symbol that start a line of your comment format. Defaults to `*`.
*/
readonly line?: RegExp | string;
/**
* The end symbol of your comment format. Defaults to `*\/`.
*/
readonly end?: RegExp | string;
}
export interface JSDocRenderOptions {
/**
* Determines the style for rendering tags. Defaults to `italic`.
*/
tag?: 'plain' | 'italic' | 'bold' | 'bold-italic';
/**
* Determines the default for rendering `@link` tags. Defaults to `plain`.
*/
link?: 'code' | 'plain';
/**
* Custom tag rendering function.
* Return a markdown formatted tag or `undefined` to fall back to the default rendering.
*/
renderTag?(tag: JSDocTag): string | undefined;
/**
* Custom link rendering function. Accepts a link target and a display value for the link.
* Return a markdown formatted link with the format `[$display]($link)` or `undefined` if the link is not a valid target.
*/
renderLink?(link: string, display: string): string | undefined;
}
/**
* Parses a JSDoc from a `CstNode` containing a comment.
*
* @param node A `CstNode` from a parsed Langium document.
* @param options Parsing options specialized to your language. See {@link JSDocParseOptions}.
*/
export declare function parseJSDoc(node: CstNode, options?: JSDocParseOptions): JSDocComment;
/**
* Parses a JSDoc from a string comment.
*
* @param content A string containing the source of the JSDoc comment.
* @param start The start position the comment occupies in the source document.
* @param options Parsing options specialized to your language. See {@link JSDocParseOptions}.
*/
export declare function parseJSDoc(content: string, start?: Position, options?: JSDocParseOptions): JSDocComment;
export declare function isJSDoc(node: CstNode | string, options?: JSDocParseOptions): boolean;
//# sourceMappingURL=jsdoc.d.ts.map

View File

@@ -0,0 +1,40 @@
/******************************************************************************
* 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 { Range } from 'vscode-languageserver-textdocument';
import type { AstNode, CstNode } from '../syntax-tree.js';
import type { DocumentSegment } from '../workspace/documents.js';
export interface TraceSourceSpec {
astNode: AstNode;
property?: string;
index?: number;
}
export type SourceRegion = TextRegion | TextRegion2 | DocumentSegmentWithFileURI;
export interface TextRegion {
fileURI?: string;
offset: number;
end: number;
length?: number;
range?: Range;
}
interface TextRegion2 {
fileURI?: string;
offset: number;
length: number;
end?: number;
range?: Range;
}
export interface TraceRegion {
sourceRegion?: TextRegion;
targetRegion: TextRegion;
children?: TraceRegion[];
}
interface DocumentSegmentWithFileURI extends Omit<DocumentSegment, 'range'> {
fileURI?: string;
range?: Range;
}
export declare function getSourceRegion(sourceSpec: TraceSourceSpec | undefined | SourceRegion | SourceRegion[]): DocumentSegmentWithFileURI | CstNode | undefined;
export {};
//# sourceMappingURL=generator-tracing.d.ts.map

View File

@@ -0,0 +1,135 @@
/******************************************************************************
* 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 { getDocument } from '../utils/ast-utils.js';
import { findNodesForProperty } from '../utils/grammar-utils.js';
import { TreeStreamImpl } from '../utils/stream.js';
export function getSourceRegion(sourceSpec) {
if (!sourceSpec) {
return undefined;
}
else if ('astNode' in sourceSpec) {
return getSourceRegionOfAstNode(sourceSpec);
}
else if (Array.isArray(sourceSpec)) {
return sourceSpec.reduce(mergeDocumentSegment, undefined); // apply mergeDocumentSegment for single entry sourcSpec lists, too, thus start with 'undefined' as initial value
}
else {
// some special treatment of cstNodes for revealing the uri of the defining DSL text file
// is currently only done for single cstNode tracings, like "expandTracedToNode(source.$cstNode)`...`",
// is _not done_ for multi node tracings like below, see if case above
// joinTracedToNode( [
// findNodeForKeyword(source.$cstNode, '{')!,
// findNodeForKeyword(source.$cstNode, '}')!
// ] )(source.children, c => c.name)
const sourceRegion = sourceSpec;
const sourceFileURIviaCstNode = isCstNode(sourceRegion)
? getDocumentURIOrUndefined(sourceRegion?.root?.astNode ?? sourceRegion?.astNode) : undefined;
return copyDocumentSegment(sourceRegion, sourceFileURIviaCstNode);
}
}
function isCstNode(segment) {
return typeof segment !== 'undefined' && 'element' in segment && 'text' in segment;
}
function getDocumentURIOrUndefined(astNode) {
try {
return getDocument(astNode).uri.toString();
}
catch (_error) {
return undefined;
}
}
function getSourceRegionOfAstNode(sourceSpec) {
const { astNode, property, index } = sourceSpec ?? {};
const textRegion = astNode?.$cstNode ?? astNode?.$textRegion;
if (astNode === undefined || textRegion === undefined) {
return undefined;
}
else if (property === undefined) {
return copyDocumentSegment(textRegion, getDocumentURI(astNode));
}
else {
const getSingleOrCompoundRegion = (regions) => {
if (index !== undefined && index > -1 && Array.isArray(astNode[property])) {
return index < regions.length ? regions[index] : undefined;
}
else {
return regions.reduce(mergeDocumentSegment, undefined);
}
};
if (textRegion.assignments?.[property]) {
const region = getSingleOrCompoundRegion(textRegion.assignments[property]);
return region && copyDocumentSegment(region, getDocumentURI(astNode));
}
else if (astNode.$cstNode) {
const region = getSingleOrCompoundRegion(findNodesForProperty(astNode.$cstNode, property));
return region && copyDocumentSegment(region, getDocumentURI(astNode));
}
else {
return undefined;
}
}
}
function getDocumentURI(astNode) {
if (astNode.$cstNode) {
return getDocument(astNode)?.uri?.toString();
}
else if (astNode.$textRegion) {
return astNode.$textRegion.documentURI
|| new TreeStreamImpl(astNode, n => n.$container ? [n.$container] : []).find(n => n.$textRegion?.documentURI)?.$textRegion?.documentURI;
}
else {
return undefined;
}
}
function copyDocumentSegment(region, fileURI) {
const result = {
offset: region.offset,
end: region.end ?? region.offset + region.length,
length: region.length ?? region.end - region.offset,
};
if (region.range) {
result.range = region.range;
}
fileURI ?? (fileURI = region.fileURI);
if (fileURI) {
result.fileURI = fileURI;
}
return result;
}
function mergeDocumentSegment(prev, curr) {
if (!prev) {
return curr && copyDocumentSegment(curr);
}
else if (!curr) {
return prev && copyDocumentSegment(prev);
}
const prevEnd = prev.end ?? prev.offset + prev.length;
const currEnd = curr.end ?? curr.offset + curr.length;
const offset = Math.min(prev.offset, curr.offset);
const end = Math.max(prevEnd, currEnd);
const length = end - offset;
const result = {
offset, end, length,
};
if (prev.range && curr.range) {
result.range = {
start: curr.range.start.line < prev.range.start.line
|| curr.range.start.line === prev.range.start.line && curr.range.start.character < prev.range.start.character
? curr.range.start : prev.range.start,
end: curr.range.end.line > prev.range.end.line
|| curr.range.end.line === prev.range.end.line && curr.range.end.character > prev.range.end.character
? curr.range.end : prev.range.end
};
}
if (prev.fileURI || curr.fileURI) {
const prevURI = prev.fileURI;
const currURI = curr.fileURI;
const fileURI = prevURI && currURI && prevURI !== currURI ? `<unmergable text regions of ${prevURI}, ${currURI}>` : prevURI ?? currURI;
result.fileURI = fileURI;
}
return result;
}
//# sourceMappingURL=generator-tracing.js.map

View File

@@ -0,0 +1,258 @@
/******************************************************************************
* 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 { CompositeGeneratorNode, IndentNode, NewLineNode } from './generator-node.js';
import { getSourceRegion } from './generator-tracing.js';
class Context {
constructor(defaultIndent) {
this.defaultIndentation = ' ';
this.pendingIndent = true;
this.currentIndents = [];
this.recentNonImmediateIndents = [];
this.traceData = [];
this.lines = [[]];
this.length = 0;
if (typeof defaultIndent === 'string') {
this.defaultIndentation = defaultIndent;
}
else if (typeof defaultIndent === 'number') {
this.defaultIndentation = ''.padStart(defaultIndent);
}
}
get content() {
return this.lines.map(e => e.join('')).join('');
}
get contentLength() {
return this.length;
}
get currentLineNumber() {
return this.lines.length - 1;
}
get currentLineContent() {
return this.lines[this.currentLineNumber].join('');
}
get currentPosition() {
return {
offset: this.contentLength,
line: this.currentLineNumber,
character: this.currentLineContent.length
};
}
append(value, isIndent) {
if (value.length > 0) {
const beforePos = isIndent && this.currentPosition;
this.lines[this.currentLineNumber].push(value);
this.length += value.length;
if (beforePos) {
this.indentPendingTraceRegions(beforePos);
}
}
}
indentPendingTraceRegions(before) {
for (let i = this.traceData.length - 1; i >= 0; i--) {
const tr = this.traceData[i];
if (tr.targetStart && tr.targetStart.offset === before.offset /* tr.targetStart.line == before.line && tr.targetStart.character === before.character*/)
tr.targetStart = this.currentPosition;
}
}
increaseIndent(node) {
this.currentIndents.push(node);
if (!node.indentImmediately) {
this.recentNonImmediateIndents.push(node);
}
}
decreaseIndent() {
this.currentIndents.pop();
}
get relevantIndents() {
return this.currentIndents.filter(i => !this.recentNonImmediateIndents.includes(i));
}
resetCurrentLine() {
this.length -= this.lines[this.currentLineNumber].join('').length;
this.lines[this.currentLineNumber] = [];
this.pendingIndent = true;
this.recentNonImmediateIndents.length = 0;
}
addNewLine() {
this.lines.push([]);
this.pendingIndent = true;
this.recentNonImmediateIndents.length = 0;
}
pushTraceRegion(sourceRegion) {
const region = createTraceRegion(sourceRegion, this.currentPosition, it => this.traceData[this.traceData.length - 1]?.children?.push(it));
this.traceData.push(region);
return region;
}
popTraceRegion(expected) {
const traceRegion = this.traceData.pop();
// the following assertion can be dropped once the tracing is considered stable
this.assertTrue(traceRegion === expected, 'Trace region mismatch!');
return traceRegion;
}
getParentTraceSourceFileURI() {
for (let i = this.traceData.length - 1; i > -1; i--) {
const fileUri = this.traceData[i].sourceRegion?.fileURI;
if (fileUri)
return fileUri;
}
return undefined;
}
assertTrue(condition, msg) {
if (!condition) {
throw new Error(msg);
}
}
}
function createTraceRegion(sourceRegion, targetStart, accept) {
const result = {
sourceRegion,
targetRegion: undefined,
children: [],
targetStart,
complete: (targetEnd) => {
result.targetRegion = {
offset: result.targetStart.offset,
end: targetEnd.offset,
length: targetEnd.offset - result.targetStart.offset,
range: {
start: {
line: result.targetStart.line,
character: result.targetStart.character
},
end: {
line: targetEnd.line,
character: targetEnd.character
},
}
};
delete result.targetStart;
if (result.children?.length === 0) {
delete result.children;
}
if (result.targetRegion?.length) {
accept(result);
}
delete result.complete;
return result;
}
};
return result;
}
export function processGeneratorNode(node, defaultIndentation) {
const context = new Context(defaultIndentation);
const trace = context.pushTraceRegion(undefined);
processNodeInternal(node, context);
context.popTraceRegion(trace);
trace.complete && trace.complete(context.currentPosition);
const singleChild = trace.children && trace.children.length === 1 ? trace.children[0] : undefined;
const singleChildTargetRegion = singleChild?.targetRegion;
const rootTargetRegion = trace.targetRegion;
if (singleChildTargetRegion && singleChild.sourceRegion
&& singleChildTargetRegion.offset === rootTargetRegion.offset
&& singleChildTargetRegion.length === rootTargetRegion.length) {
// some optimization:
// if (the root) `node` is traced (`singleChild.sourceRegion` !== undefined) and spans the entire `context.content`
// we skip the wrapping root trace object created above at the beginning of this method
return { text: context.content, trace: singleChild };
}
else {
return { text: context.content, trace };
}
}
function processNodeInternal(node, context) {
if (typeof (node) === 'string') {
processStringNode(node, context);
}
else if (node instanceof IndentNode) {
processIndentNode(node, context);
}
else if (node instanceof CompositeGeneratorNode) {
processCompositeNode(node, context);
}
else if (node instanceof NewLineNode) {
processNewLineNode(node, context);
}
}
function hasContent(node, ctx) {
if (typeof (node) === 'string') {
return node.length !== 0; // cs: do not ignore ws only content here, enclosed within other nodes it will matter!
}
else if (node instanceof CompositeGeneratorNode) {
return node.contents.some(e => hasContent(e, ctx));
}
else if (node instanceof NewLineNode) {
return !(node.ifNotEmpty && ctx.currentLineContent.length === 0);
}
else {
return false;
}
}
function processStringNode(node, context) {
if (node) {
handlePendingIndent(context, false);
context.append(node);
}
}
function handlePendingIndent(ctx, endOfLine) {
if (ctx.pendingIndent) {
let indent = '';
for (const indentNode of ctx.relevantIndents.filter(e => e.indentEmptyLines || !endOfLine)) {
indent += indentNode.indentation ?? ctx.defaultIndentation;
}
ctx.append(indent, true);
ctx.pendingIndent = false;
}
}
function processCompositeNode(node, context) {
let traceRegion = undefined;
const sourceRegion = getSourceRegion(node.tracedSource);
if (sourceRegion) {
traceRegion = context.pushTraceRegion(sourceRegion);
}
for (const child of node.contents) {
processNodeInternal(child, context);
}
if (traceRegion) {
context.popTraceRegion(traceRegion);
const parentsFileURI = context.getParentTraceSourceFileURI();
if (parentsFileURI && sourceRegion?.fileURI === parentsFileURI) {
// if some parent's sourceRegion refers to the same source file uri (and no other source file was referenced inbetween)
// we can drop the file uri in order to reduce repeated strings
delete sourceRegion.fileURI;
}
traceRegion.complete && traceRegion.complete(context.currentPosition);
}
}
function processIndentNode(node, context) {
if (hasContent(node, context)) {
if (node.indentImmediately && !context.pendingIndent) {
context.append(node.indentation ?? context.defaultIndentation, true);
}
try {
context.increaseIndent(node);
processCompositeNode(node, context);
}
finally {
context.decreaseIndent();
}
}
}
function processNewLineNode(node, context) {
if (node.ifNotEmpty && !hasNonWhitespace(context.currentLineContent)) {
context.resetCurrentLine();
}
else {
handlePendingIndent(context, true);
let count = node.count;
while (count-- > 0) {
context.append(node.lineDelimiter);
context.addNewLine();
}
}
}
function hasNonWhitespace(text) {
return text.trimStart() !== '';
}
//# sourceMappingURL=node-processor.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"version":3,"file":"template-string.d.ts","sourceRoot":"","sources":["../../src/generate/template-string.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAKhF,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,oBAAoB,EAAE,GAAG,aAAa,EAAE,OAAO,EAAE,GAAG,MAAM,CAE3G;AAED,wBAAgB,sBAAsB,CAAC,WAAW,EAAE,oBAAoB,EAAE,GAAG,aAAa,EAAE,OAAO,EAAE,GAAG,MAAM,CAE7G;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,WAAW,EAAE,oBAAoB,EAAE,GAAG,aAAa,EAAE,OAAO,EAAE,GAAG,MAAM,CAErG;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,oBAAoB,EAAE,GAAG,aAAa,EAAE,OAAO,EAAE,GAAG,MAAM,CAEvG;AAyCD,eAAO,MAAM,IAAI,QAAgD,CAAC;AAWlE,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,CAIvD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAElD"}

View File

@@ -0,0 +1,7 @@
/******************************************************************************
* This file was generated by langium-cli 4.2.0.
* DO NOT EDIT MANUALLY!
******************************************************************************/
import type { Grammar } from '../../languages/generated/ast.js';
export declare const LangiumGrammarGrammar: () => Grammar;
//# sourceMappingURL=grammar.d.ts.map

File diff suppressed because one or more lines are too long

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"}

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

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

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

View File

@@ -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"}

View File

@@ -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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"}

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

View File

@@ -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"}

View File

@@ -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"}

View File

@@ -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"}

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

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 } 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

View File

@@ -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"}

View File

@@ -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"}

View File

@@ -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

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

View File

@@ -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

View File

@@ -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

File diff suppressed because one or more lines are too long

View File

@@ -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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"}

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

View File

@@ -0,0 +1 @@
{"version":3,"file":"types-validator.d.ts","sourceRoot":"","sources":["../../../src/grammar/validation/types-validator.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAGhF,OAAO,KAAK,EAAkB,kBAAkB,EAAoB,MAAM,yCAAyC,CAAC;AACpH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,8BAA8B,CAAC;AAG3E,OAAO,KAAK,GAAG,MAAM,kCAAkC,CAAC;AAQxD,wBAAgB,4BAA4B,CAAC,QAAQ,EAAE,sBAAsB,GAAG,IAAI,CAuBnF;AAED,qBAAa,4BAA4B;IAErC,0BAA0B,CAAC,gBAAgB,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAiB7F,eAAe,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAMjE,oBAAoB,CAAC,IAAI,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAM3E,6BAA6B,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAarF,wCAAwC,CAAC,OAAO,EAAE,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAchG,yBAAyB,CAAC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAM/E,gCAAgC,CAAC,SAAS,EAAE,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,kBAAkB,GAAG,IAAI;IAgE5F,OAAO,CAAC,2BAA2B;IAOnC,OAAO,CAAC,4BAA4B;CAQvC"}

View File

@@ -0,0 +1,17 @@
/******************************************************************************
* 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 { ValidationResources } from '../workspace/documents.js';
import type { LangiumGrammarServices } from '../langium-grammar-module.js';
export declare class LangiumGrammarValidationResourcesCollector {
private readonly services;
constructor(services: LangiumGrammarServices);
collectValidationResources(grammar: Grammar): ValidationResources;
private collectValidationInfo;
private collectSuperProperties;
private addSuperProperties;
}
//# sourceMappingURL=validation-resources-collector.d.ts.map

View File

@@ -0,0 +1,93 @@
/******************************************************************************
* 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 { stream } from '../../utils/stream.js';
import { isAction, isAlternatives, isGroup, isUnorderedGroup } from '../../languages/generated/ast.js';
import { mergeInterfaces, mergeTypesAndInterfaces } from '../type-system/types-util.js';
import { collectValidationAst } from '../type-system/ast-collector.js';
import { getActionType, getRuleTypeName } from '../../utils/grammar-utils.js';
export class LangiumGrammarValidationResourcesCollector {
constructor(services) {
this.services = services;
}
collectValidationResources(grammar) {
try {
const typeResources = collectValidationAst(grammar, this.services);
return {
typeToValidationInfo: this.collectValidationInfo(typeResources),
typeToSuperProperties: this.collectSuperProperties(typeResources),
};
}
catch (err) {
console.error('Error collecting validation resources', err);
return { typeToValidationInfo: new Map(), typeToSuperProperties: new Map() };
}
}
collectValidationInfo({ astResources, inferred, declared }) {
const res = new Map();
const typeNameToRulesActions = collectNameToRulesActions(astResources);
for (const type of mergeTypesAndInterfaces(inferred)) {
res.set(type.name, { inferred: type, inferredNodes: typeNameToRulesActions.get(type.name) });
}
const typeNametoInterfacesUnions = stream(astResources.interfaces)
.concat(astResources.types)
.reduce((acc, type) => acc.set(type.name, type), new Map());
for (const type of mergeTypesAndInterfaces(declared)) {
const node = typeNametoInterfacesUnions.get(type.name);
if (node) {
const inferred = res.get(type.name);
res.set(type.name, { ...inferred ?? {}, declared: type, declaredNode: node });
}
}
return res;
}
collectSuperProperties({ inferred, declared }) {
const typeToSuperProperties = new Map();
const interfaces = mergeInterfaces(inferred, declared);
const interfaceMap = new Map(interfaces.map(e => [e.name, e]));
for (const type of mergeInterfaces(inferred, declared)) {
typeToSuperProperties.set(type.name, this.addSuperProperties(type, interfaceMap, new Set()));
}
return typeToSuperProperties;
}
addSuperProperties(interfaceType, map, visited) {
if (visited.has(interfaceType.name)) {
return [];
}
visited.add(interfaceType.name);
const properties = [...interfaceType.properties];
for (const superType of interfaceType.superTypes) {
const value = map.get(superType.name);
if (value) {
properties.push(...this.addSuperProperties(value, map, visited));
}
}
return properties;
}
}
function collectNameToRulesActions({ parserRules, datatypeRules }) {
const acc = new MultiMap();
// collect rules
stream(parserRules)
.concat(datatypeRules)
.forEach(rule => acc.add(getRuleTypeName(rule), rule));
// collect actions
function collectActions(element) {
if (isAction(element)) {
const name = getActionType(element);
if (name) {
acc.add(name, element);
}
}
if (isAlternatives(element) || isGroup(element) || isUnorderedGroup(element)) {
element.elements.forEach(e => collectActions(e));
}
}
parserRules
.forEach(rule => collectActions(rule.definition));
return acc;
}
//# sourceMappingURL=validation-resources-collector.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"validation-resources-collector.js","sourceRoot":"","sources":["../../../src/grammar/validation/validation-resources-collector.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,33 @@
/******************************************************************************
* 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 { LangiumDocument } from '../../workspace/documents.js';
import type { Action, Grammar, Interface, ParserRule, Type } from '../../languages/generated/ast.js';
import type { Property, TypeOption } from '../type-system/type-collector/types.js';
/**
* A Langium document holds the parse result (AST and CST) and any additional state that is derived
* from the AST, e.g. the result of scope precomputation.
*/
export interface LangiumGrammarDocument extends LangiumDocument<Grammar> {
validationResources?: ValidationResources;
}
export type ValidationResources = {
typeToValidationInfo: TypeToValidationInfo;
typeToSuperProperties: Map<string, Property[]>;
};
export type TypeToValidationInfo = Map<string, InferredInfo | DeclaredInfo | InferredInfo & DeclaredInfo>;
export type InferredInfo = {
inferred: TypeOption;
inferredNodes: ReadonlyArray<ParserRule | Action>;
};
export type DeclaredInfo = {
declared: TypeOption;
declaredNode: Type | Interface;
};
export declare function isDeclared(type: InferredInfo | DeclaredInfo | InferredInfo & DeclaredInfo): type is DeclaredInfo;
export declare function isInferred(type: InferredInfo | DeclaredInfo | InferredInfo & DeclaredInfo): type is InferredInfo;
export declare function isInferredAndDeclared(type: InferredInfo | DeclaredInfo | InferredInfo & DeclaredInfo): type is InferredInfo & DeclaredInfo;
export declare function getTypeOption(info: InferredInfo | DeclaredInfo): TypeOption;
//# sourceMappingURL=documents.d.ts.map

25
frontend/node_modules/langium/lib/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,25 @@
/******************************************************************************
* 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.
*
* @module langium
*/
export * from './default-module.js';
export * from './dependency-injection.js';
export * from './service-registry.js';
export * from './services.js';
export * from './syntax-tree.js';
export * from './documentation/index.js';
export * from './languages/index.js';
export * from './parser/index.js';
export * from './references/index.js';
export * from './serializer/index.js';
export * from './utils/index.js';
export * from './validation/index.js';
export * from './workspace/index.js';
import * as GrammarAST from './languages/generated/ast.js';
import type { Grammar } from './languages/generated/ast.js';
export type { Grammar };
export { GrammarAST };
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"grammar-config.js","sourceRoot":"","sources":["../../src/languages/grammar-config.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAGhF,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAapD;;;GAGG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAA6B;IAC7D,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAC/B,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,iBAAiB,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC;YAC7F,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC1B,CAAC;IACL,CAAC;IACD,OAAO;QACH,qBAAqB,EAAE,KAAK;QAC5B,UAAU,EAAE,iBAAiB;KAChC,CAAC;AACN,CAAC"}

View File

@@ -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.
******************************************************************************/
/**
* Metadata of a language.
*/
export interface LanguageMetaData {
languageId: string;
fileExtensions: readonly string[];
fileNames?: readonly string[];
caseInsensitive: boolean;
/**
* Mode used to optimize code for development or production environments.
*
* In production mode, all Chevrotain lexer/parser validations are disabled.
*/
mode: 'development' | 'production';
}
//# sourceMappingURL=language-meta-data.d.ts.map

View File

@@ -0,0 +1,45 @@
/******************************************************************************
* 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 { CallHierarchyIncomingCall, CallHierarchyIncomingCallsParams, CallHierarchyItem, CallHierarchyOutgoingCall, CallHierarchyOutgoingCallsParams, CallHierarchyPrepareParams } from 'vscode-languageserver';
import type { CancellationToken } from '../utils/cancellation.js';
import type { GrammarConfig } from '../languages/grammar-config.js';
import type { NameProvider } from '../references/name-provider.js';
import type { References } from '../references/references.js';
import type { LangiumServices } from './lsp-services.js';
import type { AstNode } from '../syntax-tree.js';
import type { Stream } from '../utils/stream.js';
import type { ReferenceDescription } from '../workspace/ast-descriptions.js';
import type { LangiumDocument, LangiumDocuments } from '../workspace/documents.js';
import type { MaybePromise } from '../utils/promise-utils.js';
/**
* Language-specific service for handling call hierarchy requests.
*/
export interface CallHierarchyProvider {
prepareCallHierarchy(document: LangiumDocument, params: CallHierarchyPrepareParams, cancelToken?: CancellationToken): MaybePromise<CallHierarchyItem[] | undefined>;
incomingCalls(params: CallHierarchyIncomingCallsParams, cancelToken?: CancellationToken): MaybePromise<CallHierarchyIncomingCall[] | undefined>;
outgoingCalls(params: CallHierarchyOutgoingCallsParams, cancelToken?: CancellationToken): MaybePromise<CallHierarchyOutgoingCall[] | undefined>;
}
export declare abstract class AbstractCallHierarchyProvider implements CallHierarchyProvider {
protected readonly grammarConfig: GrammarConfig;
protected readonly nameProvider: NameProvider;
protected readonly documents: LangiumDocuments;
protected readonly references: References;
constructor(services: LangiumServices);
prepareCallHierarchy(document: LangiumDocument<AstNode>, params: CallHierarchyPrepareParams): MaybePromise<CallHierarchyItem[] | undefined>;
protected getCallHierarchyItems(targetNode: AstNode, document: LangiumDocument<AstNode>): CallHierarchyItem[] | undefined;
protected getCallHierarchyItem(_targetNode: AstNode): Partial<CallHierarchyItem> | undefined;
incomingCalls(params: CallHierarchyIncomingCallsParams): Promise<CallHierarchyIncomingCall[] | undefined>;
/**
* Override this method to collect the incoming calls for your language
*/
protected abstract getIncomingCalls(node: AstNode, references: Stream<ReferenceDescription>): MaybePromise<CallHierarchyIncomingCall[] | undefined>;
outgoingCalls(params: CallHierarchyOutgoingCallsParams): Promise<CallHierarchyOutgoingCall[] | undefined>;
/**
* Override this method to collect the outgoing calls for your language
*/
protected abstract getOutgoingCalls(node: AstNode): MaybePromise<CallHierarchyOutgoingCall[] | undefined>;
}
//# sourceMappingURL=call-hierarchy-provider.d.ts.map

7
frontend/node_modules/langium/lib/lsp/code-action.js generated vendored Normal file
View File

@@ -0,0 +1,7 @@
/******************************************************************************
* 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.
******************************************************************************/
export {};
//# sourceMappingURL=code-action.js.map

View File

@@ -0,0 +1,7 @@
/******************************************************************************
* 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 {};
//# sourceMappingURL=code-lens-provider.js.map

View File

@@ -0,0 +1,312 @@
/******************************************************************************
* 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 * as ast from '../../languages/generated/ast.js';
import { getCrossReferenceTerminal, getExplicitRuleType, getTypeName, isArrayCardinality, isOptionalCardinality, terminalRegex } from '../../utils/grammar-utils.js';
import { getContainerOfType } from '../../utils/ast-utils.js';
/**
* Calculates any features that can follow the given feature stack.
* This also includes features following optional features and features from previously called rules that could follow the last feature.
* @param featureStack A stack of features starting at the entry rule and ending at the feature of the current cursor position.
* @param unparsedTokens All tokens which haven't been parsed successfully yet. This is the case when we call this function inside an alternative or before parsing any tokens.
* @returns Any `AbstractElement` that could be following the given feature stack.
*/
export function findNextFeatures(featureStack, unparsedTokens) {
const context = {
stacks: featureStack,
tokens: unparsedTokens
};
interpretTokens(context);
// Reset the container property
context.stacks.flat().forEach(feature => { feature.property = undefined; });
const nextStacks = findNextFeatureStacks(context.stacks);
// We only need the last element of each stack
return nextStacks.map(e => e[e.length - 1]);
}
function findNextFeaturesInternal(stack) {
const features = [];
if (stack.length === 0) {
return features;
}
const top = stack[stack.length - 1];
const { group, child } = findGroupAndChild(top.feature);
if (isArrayCardinality(child.cardinality)) {
// The feature can appear again, so we try to find its first features again
const repeatingFeatures = findFirstFeaturesInternal({
feature: child,
type: top.type,
property: top.property
});
features.push(...repeatingFeatures);
}
let groupIndex = -1;
if (group) {
groupIndex = group.elements.indexOf(child);
}
const parentStack = stack.slice(0, -1);
if (!group) {
const parent = getAbstractElementParent(child);
if (parent) {
// The feature is not part of a group
// But the parent might be
features.push(...findNextFeaturesInternal([
...parentStack,
{
feature: parent,
}
]));
}
else {
// The feature is "standalone", meaning it is the top-level feature of a rule
// The next elements are defined by the previous stack elements
features.push(...findNextFeaturesInternal(parentStack));
}
}
else {
// The feature is somewhere within the group
const nextIndex = groupIndex + 1;
const { stacks, end } = findNextFeaturesInGroup({
feature: group,
type: top.type
}, nextIndex);
for (const newStack of stacks) {
features.push([...parentStack, ...newStack]);
}
// If we reached the end of the group, continue searching for following features
if (end) {
// Set groupIndex to the last element index to indicate that we are at the end of the group
// This will trigger the parent search below
groupIndex = group.elements.length - 1;
}
}
if (group && groupIndex === group.elements.length - 1) {
// The feature is the last element of a group
// The next elements are defined by the parent group
features.push(...findNextFeaturesInternal([
...parentStack,
{
feature: group,
}
]));
}
return features;
}
/**
* Calculates the first child feature of any `AbstractElement`.
* @param next The `AbstractElement` whose first child features should be calculated.
*/
export function findFirstFeatures(next) {
return findFirstFeaturesInternal({ feature: next });
}
function findFirstFeaturesInternal(next) {
const { feature, type } = next;
if (ast.isGroup(feature)) {
return findNextFeaturesInGroup(next, 0).stacks;
}
else if (ast.isAlternatives(feature) || ast.isUnorderedGroup(feature)) {
return feature.elements.flatMap(e => findFirstFeaturesInternal({
feature: e,
type,
property: next.property
}));
}
else if (ast.isAssignment(feature)) {
return findFirstFeaturesInternal({
feature: feature.terminal,
type,
property: next.property ?? feature.feature
});
}
else if (ast.isAction(feature)) {
return findNextFeaturesInternal([{
feature,
type: getTypeName(feature),
property: next.property ?? feature.feature
}]);
}
else if (ast.isRuleCall(feature) && ast.isParserRule(feature.rule.ref)) {
const rule = feature.rule.ref;
const stacks = findFirstFeaturesInternal({
feature: rule.definition,
type: rule.fragment || rule.dataType ? undefined : (getExplicitRuleType(rule) ?? rule.name),
property: next.property
});
for (const stack of stacks) {
stack.unshift(next);
}
return stacks;
}
else if (ast.isRuleCall(feature) && ast.isInfixRule(feature.rule.ref)) {
const rule = feature.rule.ref;
const call = rule.call.rule.ref;
if (!ast.isParserRule(call)) {
console.error('Failed to resolve reference to ' + rule.call.rule.$refText);
return [];
}
const stacks = findFirstFeaturesInternal({
feature: call.definition,
type: getExplicitRuleType(call) ?? call.name,
property: 'parts'
});
for (const stack of stacks) {
stack.unshift(next);
}
return stacks;
}
else {
return [[next]];
}
}
function findNextFeaturesInGroup(next, index) {
const features = [];
let firstFeature;
while (index < next.feature.elements.length) {
const feature = next.feature.elements[index];
firstFeature = {
feature,
type: next.type
};
const stacks = findFirstFeaturesInternal(firstFeature);
features.push(...stacks);
if (isElementOptional(feature, new Map())) {
// Continue with the next element
index++;
}
else {
break;
}
}
return {
stacks: features,
end: index >= next.feature.elements.length
};
}
/**
* Determines recursively whether an element is optional. It is not sufficient to check only the cardinality of the element itself,
* because it could a group or alternative that contains only optional elements.
*/
function isElementOptional(feature, visited) {
const visitedResult = visited.get(feature);
if (visitedResult !== undefined) {
return visitedResult;
}
visited.set(feature, false);
if (isOptionalCardinality(feature.cardinality, feature)) {
visited.set(feature, true);
return true;
}
if (ast.isGroup(feature)) {
for (const element of feature.elements) {
if (!isElementOptional(element, visited)) {
visited.set(feature, false);
return false;
}
}
visited.set(feature, true);
return true;
}
else if (ast.isAlternatives(feature) || ast.isUnorderedGroup(feature)) {
for (const element of feature.elements) {
if (isElementOptional(element, visited)) {
visited.set(feature, true);
return true;
}
}
visited.set(feature, false);
return false;
}
else if (ast.isRuleCall(feature) && ast.isParserRule(feature.rule.ref)) {
const rule = feature.rule.ref;
const result = isElementOptional(rule.definition, visited);
visited.set(feature, result);
return result;
}
return false;
}
function interpretTokens(context) {
for (const token of context.tokens) {
const nextFeatureStacks = findNextFeatureStacks(context.stacks, token);
context.stacks = nextFeatureStacks;
}
}
function findNextFeatureStacks(stacks, token) {
const newStacks = [];
for (const stack of stacks) {
newStacks.push(...interpretStackToken(stack, token));
}
return newStacks;
}
function interpretStackToken(stack, token) {
const allNextFeatures = findNextFeaturesInternal(stack);
const matchingNextFeatures = allNextFeatures.filter(next => token ? featureMatches(next[next.length - 1].feature, token) : true);
return matchingNextFeatures;
}
export function findGroupAndChild(feature) {
let parent;
let item = feature;
while (item.$container) {
if (ast.isGroup(item.$container)) {
parent = item.$container;
break;
}
else if (ast.isAbstractElement(item.$container)) {
item = item.$container;
}
else {
break;
}
}
if (parent) {
return { group: parent, child: item };
}
return {
group: undefined,
// Even if there is no group, return the feature parent if it is an assignment
// We need this later to handle the cardinality of the feature correctly
child: getContainerOfType(feature, ast.isAssignment) ?? feature
};
}
function getAbstractElementParent(element) {
const parent = element.$container;
const assignment = getContainerOfType(parent, ast.isAssignment);
if (assignment) {
return getAbstractElementParent(assignment);
}
else {
if (parent && ast.isAbstractElement(parent)) {
return parent;
}
}
return undefined;
}
function featureMatches(feature, token) {
if (ast.isKeyword(feature)) {
const content = feature.value;
return content === token.tokenType.name;
}
else if (ast.isRuleCall(feature)) {
return ruleMatches(feature.rule.ref, token);
}
else if (ast.isCrossReference(feature)) {
const crossRefTerminal = getCrossReferenceTerminal(feature);
if (crossRefTerminal) {
return featureMatches(crossRefTerminal, token);
}
}
return false;
}
function ruleMatches(rule, token) {
if (ast.isParserRule(rule)) {
const ruleFeatures = findFirstFeatures(rule.definition);
return ruleFeatures.some(e => featureMatches(e[e.length - 1].feature, token));
}
else if (ast.isTerminalRule(rule)) {
return terminalRegex(rule).test(token.image);
}
else {
return false;
}
}
//# sourceMappingURL=follow-element-computation.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,7 @@
/******************************************************************************
* 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 {};
//# sourceMappingURL=declaration-provider.js.map

View File

@@ -0,0 +1,43 @@
/******************************************************************************
* 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 { Connection } from 'vscode-languageserver';
import { type DefaultCoreModuleContext, type DefaultSharedCoreModuleContext } from '../default-module.js';
import { Module } from '../dependency-injection.js';
import type { LangiumDefaultCoreServices, LangiumDefaultSharedCoreServices } from '../services.js';
import type { LangiumLSPServices, LangiumServices, LangiumSharedLSPServices, LangiumSharedServices } from './lsp-services.js';
/**
* Context required for creating the default language-specific dependency injection module.
*/
export interface DefaultModuleContext extends DefaultCoreModuleContext {
readonly shared: LangiumSharedServices;
}
/**
* Creates a dependency injection module configuring the default Core & LSP services for a Langium-based language implementation.
* This is a set of services that are dedicated to a specific language.
*/
export declare function createDefaultModule(context: DefaultModuleContext): Module<LangiumServices, LangiumDefaultCoreServices & LangiumLSPServices>;
/**
* Creates a dependency injection module configuring the default LSP services.
* This is a set of services that are dedicated to a specific language.
*/
export declare function createDefaultLSPModule(context: DefaultModuleContext): Module<LangiumServices, LangiumLSPServices>;
export interface DefaultSharedModuleContext extends DefaultSharedCoreModuleContext {
/**
* Represents an abstract language server connection
*/
readonly connection?: Connection;
}
/**
* Creates a dependency injection module configuring the default core & LSP services shared among languages supported by a Langium-based language server.
* This is the set of services that are shared between multiple languages.
*/
export declare function createDefaultSharedModule(context: DefaultSharedModuleContext): Module<LangiumSharedServices, LangiumDefaultSharedCoreServices & LangiumSharedLSPServices>;
/**
* Creates a dependency injection module configuring the default shared LSP services.
* This is the set of services that are shared between multiple languages.
*/
export declare function createDefaultSharedLSPModule(context: DefaultSharedModuleContext): Module<LangiumSharedServices, LangiumSharedLSPServices>;
//# sourceMappingURL=default-lsp-module.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"default-lsp-module.d.ts","sourceRoot":"","sources":["../../src/lsp/default-lsp-module.ts"],"names":[],"mappings":"AAAA;;;;+EAI+E;AAE/E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAA0D,KAAK,wBAAwB,EAAE,KAAK,8BAA8B,EAAE,MAAM,sBAAsB,CAAC;AAClK,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AACpD,OAAO,KAAK,EAAE,0BAA0B,EAAE,gCAAgC,EAAE,MAAM,gBAAgB,CAAC;AAWnG,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,wBAAwB,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAO9H;;GAEG;AACH,MAAM,WAAW,oBAAqB,SAAQ,wBAAwB;IAClE,QAAQ,CAAC,MAAM,EAAE,qBAAqB,CAAC;CAC1C;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAAC,eAAe,EAAE,0BAA0B,GAAG,kBAAkB,CAAC,CAK3I;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,oBAAoB,GAAG,MAAM,CAAC,eAAe,EAAE,kBAAkB,CAAC,CAcjH;AAED,MAAM,WAAW,0BAA2B,SAAQ,8BAA8B;IAC9E;;OAEG;IACH,QAAQ,CAAC,UAAU,CAAC,EAAE,UAAU,CAAC;CACpC;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,0BAA0B,GAAG,MAAM,CAAC,qBAAqB,EAAE,gCAAgC,GAAG,wBAAwB,CAAC,CAKzK;AAED;;;GAGG;AACH,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,0BAA0B,GAAG,MAAM,CAAC,qBAAqB,EAAE,wBAAwB,CAAC,CAezI"}

View File

@@ -0,0 +1 @@
{"version":3,"file":"definition-provider.js","sourceRoot":"","sources":["../../src/lsp/definition-provider.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAWhF,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,2BAA2B,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AA0BrF,MAAM,OAAO,yBAAyB;IAMlC,YAAY,QAAyB;QACjC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;QACrD,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC,UAAU,CAAC,UAAU,CAAC;QACjD,IAAI,CAAC,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,aAAa,CAAC;IACvD,CAAC;IAED,aAAa,CAAC,QAAyB,EAAE,MAAwB,EAAE,YAAgC;QAC/F,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC;QAC5C,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,CAAC;YAC9B,MAAM,aAAa,GAAG,2BAA2B,CAAC,GAAG,EAAE,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;YACvI,IAAI,aAAa,EAAE,CAAC;gBAChB,OAAO,IAAI,CAAC,oBAAoB,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC;YAC5D,CAAC;QACL,CAAC;QACD,OAAO,SAAS,CAAC;IACrB,CAAC;IAES,oBAAoB,CAAC,aAAsB,EAAE,OAAyB;QAC5E,MAAM,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;QAChD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,YAAY,CAAC,MAAM,CAC5C,IAAI,CAAC,cAAc,CAAC,YAAY,CAAC,GAAG,EACpC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,EACnD,IAAI,CAAC,MAAM,CAAC,KAAK,EACjB,IAAI,CAAC,MAAM,CAAC,KAAK,CACpB,CAAC,CAAC;QACP,CAAC;QACD,OAAO,SAAS,CAAC;IACrB,CAAC;IAES,SAAS,CAAC,MAAe;QAC/B,MAAM,kBAAkB,GAAG,eAAe,CAAC,MAAM,CAAC,IAAI,MAAM,CAAC;QAC7D,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC;QAC7D,MAAM,KAAK,GAAe,EAAE,CAAC;QAC7B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC3B,MAAM,cAAc,GAAG,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;YACnD,IAAI,OAAO,IAAI,cAAc,EAAE,CAAC;gBAC5B,KAAK,CAAC,IAAI,CAAC;oBACP,MAAM,EAAE,kBAAkB;oBAC1B,MAAM;oBACN,cAAc;iBACjB,CAAC,CAAC;YACP,CAAC;QACL,CAAC;QACD,OAAO,KAAK,CAAC;IACjB,CAAC;CACJ"}

View File

@@ -0,0 +1,43 @@
/******************************************************************************
* 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 { DocumentHighlightParams } from 'vscode-languageserver';
import type { CancellationToken } from '../utils/cancellation.js';
import type { GrammarConfig } from '../languages/grammar-config.js';
import type { NameProvider } from '../references/name-provider.js';
import type { References } from '../references/references.js';
import type { LangiumServices } from './lsp-services.js';
import type { MaybePromise } from '../utils/promise-utils.js';
import type { ReferenceDescription } from '../workspace/ast-descriptions.js';
import type { LangiumDocument } from '../workspace/documents.js';
import { DocumentHighlight } from 'vscode-languageserver';
/**
* Language-specific service for handling document highlight requests.
*/
export interface DocumentHighlightProvider {
/**
* Handle a document highlight request.
*
* @param document The document in which the request was received.
* @param params The parameters of the document highlight request.
* @param cancelToken A cancellation token that can be used to cancel the request.
* @returns The document highlights or `undefined` if no highlights are available.
* @throws `OperationCancelled` if cancellation is detected during execution
* @throws `ResponseError` if an error is detected that should be sent as response to the client
*/
getDocumentHighlight(document: LangiumDocument, params: DocumentHighlightParams, cancelToken?: CancellationToken): MaybePromise<DocumentHighlight[] | undefined>;
}
export declare class DefaultDocumentHighlightProvider implements DocumentHighlightProvider {
protected readonly references: References;
protected readonly nameProvider: NameProvider;
protected readonly grammarConfig: GrammarConfig;
constructor(services: LangiumServices);
getDocumentHighlight(document: LangiumDocument, params: DocumentHighlightParams, _cancelToken?: CancellationToken): MaybePromise<DocumentHighlight[] | undefined>;
/**
* Override this method to determine the highlight kind of the given reference.
*/
protected createDocumentHighlight(reference: ReferenceDescription): DocumentHighlight;
}
//# sourceMappingURL=document-highlight-provider.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"document-link-provider.d.ts","sourceRoot":"","sources":["../../src/lsp/document-link-provider.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC9E,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACjC;;;;;OAKG;IACH,gBAAgB,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,kBAAkB,EAAE,WAAW,CAAC,EAAE,iBAAiB,GAAG,YAAY,CAAC,YAAY,EAAE,CAAC,CAAC;CAC1I"}

View File

@@ -0,0 +1,40 @@
/******************************************************************************
* 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 { DocumentSymbol, DocumentSymbolParams } from 'vscode-languageserver-protocol';
import type { CancellationToken } from '../utils/cancellation.js';
import type { NameProvider } from '../references/name-provider.js';
import type { LangiumServices } from './lsp-services.js';
import type { AstNode, CstNode } from '../syntax-tree.js';
import type { MaybePromise } from '../utils/promise-utils.js';
import type { LangiumDocument } from '../workspace/documents.js';
import type { NodeKindProvider } from './node-kind-provider.js';
/**
* Language-specific service for handling document symbols requests.
*/
export interface DocumentSymbolProvider {
/**
* Handle a document symbols request.
*
* @param document The document in the workspace.
* @param params The parameters of the request.
* @param cancelToken A cancellation token that migh be used to cancel the request.
* @returns The symbols for the given document.
*
* @throws `OperationCancelled` if cancellation is detected during execution
* @throws `ResponseError` if an error is detected that should be sent as response to the client
*/
getSymbols(document: LangiumDocument, params: DocumentSymbolParams, cancelToken?: CancellationToken): MaybePromise<DocumentSymbol[]>;
}
export declare class DefaultDocumentSymbolProvider implements DocumentSymbolProvider {
protected readonly nameProvider: NameProvider;
protected readonly nodeKindProvider: NodeKindProvider;
constructor(services: LangiumServices);
getSymbols(document: LangiumDocument, _params: DocumentSymbolParams, _cancelToken?: CancellationToken): MaybePromise<DocumentSymbol[]>;
protected getSymbol(document: LangiumDocument, astNode: AstNode): DocumentSymbol[];
protected createSymbol(document: LangiumDocument, astNode: AstNode, cstNode: CstNode, nameNode: CstNode, computedName?: string): DocumentSymbol;
protected getChildSymbols(document: LangiumDocument, astNode: AstNode): DocumentSymbol[] | undefined;
}
//# sourceMappingURL=document-symbol-provider.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"document-symbol-provider.js","sourceRoot":"","sources":["../../src/lsp/document-symbol-provider.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAOhF,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAuBvD,MAAM,OAAO,6BAA6B;IAKtC,YAAY,QAAyB;QACjC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;QACrD,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC,MAAM,CAAC,GAAG,CAAC,gBAAgB,CAAC;IACjE,CAAC;IAED,UAAU,CAAC,QAAyB,EAAE,OAA6B,EAAE,YAAgC;QACjG,OAAO,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAChE,CAAC;IAES,SAAS,CAAC,QAAyB,EAAE,OAAgB;QAC3D,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QACxD,IAAI,QAAQ,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;YAC/B,MAAM,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YACxD,OAAO,CAAE,IAAI,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAE,CAAC;QAC9F,CAAC;aAAM,CAAC;YACJ,OAAO,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;QACzD,CAAC;IACL,CAAC;IAES,YAAY,CAAC,QAAyB,EAAE,OAAgB,EAAE,OAAgB,EAAE,QAAiB,EAAE,YAAqB;QAC1H,OAAO;YACH,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,OAAO,CAAC;YAClD,IAAI,EAAE,YAAY,IAAI,QAAQ,CAAC,IAAI;YACnC,KAAK,EAAE,OAAO,CAAC,KAAK;YACpB,cAAc,EAAE,QAAQ,CAAC,KAAK;YAC9B,QAAQ,EAAE,IAAI,CAAC,eAAe,CAAC,QAAQ,EAAE,OAAO,CAAC;SACpD,CAAC;IACN,CAAC;IAES,eAAe,CAAC,QAAyB,EAAE,OAAgB;QACjE,MAAM,QAAQ,GAAqB,EAAE,CAAC;QAEtC,KAAK,MAAM,KAAK,IAAI,cAAc,CAAC,OAAO,CAAC,EAAE,CAAC;YAC1C,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC/C,QAAQ,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;QAC7B,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACtB,OAAO,QAAQ,CAAC;QACpB,CAAC;QACD,OAAO,SAAS,CAAC;IACrB,CAAC;CACJ"}

View File

@@ -0,0 +1,110 @@
/******************************************************************************
* 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 { FoldingRange, FoldingRangeKind } from 'vscode-languageserver';
import { streamAllContents } from '../utils/ast-utils.js';
import { flattenCst } from '../utils/cst-utils.js';
export class DefaultFoldingRangeProvider {
constructor(services) {
this.commentNames = services.parser.GrammarConfig.multilineCommentRules;
}
getFoldingRanges(document, _params, _cancelToken) {
const foldings = [];
const acceptor = (foldingRange) => foldings.push(foldingRange);
this.collectFolding(document, acceptor);
return foldings;
}
collectFolding(document, acceptor) {
const root = document.parseResult?.value;
if (root) {
if (this.shouldProcessContent(root)) {
const treeIterator = streamAllContents(root).iterator();
let result;
do {
result = treeIterator.next();
if (!result.done) {
const node = result.value;
if (this.shouldProcess(node)) {
this.collectObjectFolding(document, node, acceptor);
}
if (!this.shouldProcessContent(node)) {
treeIterator.prune();
}
}
} while (!result.done);
}
this.collectCommentFolding(document, root, acceptor);
}
}
/**
* Template method to determine whether the specified `AstNode` should be handled by the folding range provider.
* Returns true by default for all nodes. Returning false only ignores the specified node and not its content.
* To ignore the content of a node use `shouldProcessContent`.
*/
shouldProcess(_node) {
return true;
}
/**
* Template method to determine whether the content/children of the specified `AstNode` should be handled by the folding range provider.
* Returns true by default for all nodes. Returning false ignores _all_ content of this node, even transitive ones.
* For more precise control over foldings use the `shouldProcess` method.
*/
shouldProcessContent(_node) {
return true;
}
collectObjectFolding(document, node, acceptor) {
const cstNode = node.$cstNode;
if (cstNode) {
const foldingRange = this.toFoldingRange(document, cstNode);
if (foldingRange) {
acceptor(foldingRange);
}
}
}
collectCommentFolding(document, node, acceptor) {
const cstNode = node.$cstNode;
if (cstNode) {
for (const node of flattenCst(cstNode)) {
if (this.commentNames.includes(node.tokenType.name)) {
const foldingRange = this.toFoldingRange(document, node, FoldingRangeKind.Comment);
if (foldingRange) {
acceptor(foldingRange);
}
}
}
}
}
toFoldingRange(document, node, kind) {
const range = node.range;
const start = range.start;
let end = range.end;
// Don't generate foldings for nodes that are less than 3 lines
if (end.line - start.line < 2) {
return undefined;
}
// As we don't want to hide the end token like 'if { ... --> } <--',
// we simply select the end of the previous line as the end position
if (!this.includeLastFoldingLine(node, kind)) {
end = document.textDocument.positionAt(document.textDocument.offsetAt({ line: end.line, character: 0 }) - 1);
}
return FoldingRange.create(start.line, end.line, start.character, end.character, kind);
}
/**
* Template method to determine whether the folding range for this cst node should include its last line.
* Returns false by default for ast nodes which end in braces and for comments.
*/
includeLastFoldingLine(node, kind) {
if (kind === FoldingRangeKind.Comment) {
return false;
}
const nodeText = node.text;
const endChar = nodeText.charAt(nodeText.length - 1);
if (endChar === '}' || endChar === ')' || endChar === ']') {
return false;
}
return true;
}
}
//# sourceMappingURL=folding-range-provider.js.map

664
frontend/node_modules/langium/lib/lsp/formatter.js generated vendored Normal file
View File

@@ -0,0 +1,664 @@
/******************************************************************************
* 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 { findNodeForKeyword, findNodesForKeyword, findNodeForProperty, findNodesForProperty } from '../utils/grammar-utils.js';
import { isCompositeCstNode, isLeafCstNode } from '../syntax-tree.js';
import { streamAllContents } from '../utils/ast-utils.js';
import { getInteriorNodes, getNextNode } from '../utils/cst-utils.js';
import { DONE_RESULT, EMPTY_STREAM, StreamImpl, TreeStreamImpl } from '../utils/stream.js';
export class AbstractFormatter {
constructor() {
this.collector = () => { };
}
/**
* Creates a formatter scoped to the supplied AST node.
* Allows to define fine-grained formatting rules for elements.
*
* Example usage:
*
* ```ts
* export class CustomFormatter extends AbstractFormatter {
* protected override format(node: AstNode): void {
* if (isPerson(node)) {
* const formatter = this.getNodeFormatter(node);
* formatter.property('name').prepend(Formatting.oneSpace());
* }
* }
* }
* ```
* @param node The specific node the formatter should be scoped to. Every call to properties or keywords will only select those which belong to the supplied AST node.
*/
getNodeFormatter(node) {
return new DefaultNodeFormatter(node, this.collector);
}
formatDocument(document, params) {
const pr = document.parseResult;
if (pr.lexerErrors.length === 0 && pr.parserErrors.length === 0) {
// safe to format
return this.doDocumentFormat(document, params.options);
}
else {
// don't format a potentially broken document, return no edits
return [];
}
}
/**
* Returns whether a range for a given document is error free, i.e. safe to format
*
* @param document Document to inspect for lexer & parser errors that may produce an unsafe range
* @param range Formatting range to check for safety
* @returns Whether the given formatting range does not overlap with or follow any regions with an error
*/
isFormatRangeErrorFree(document, range) {
const pr = document.parseResult;
if (pr.lexerErrors.length || pr.parserErrors.length) {
// collect the earliest error line from either
const earliestErrLine = Math.min(...pr.lexerErrors.map(e => e.line ?? Number.MAX_VALUE), ...pr.parserErrors.map(e => e.token.startLine ?? Number.MAX_VALUE));
// if the earliest error line occurs before or at the end line of the range, then don't format
return earliestErrLine > range.end.line;
}
else {
// no errors, ok to format
return true;
}
}
formatDocumentRange(document, params) {
if (this.isFormatRangeErrorFree(document, params.range)) {
return this.doDocumentFormat(document, params.options, params.range);
}
else {
return [];
}
}
formatDocumentOnType(document, params) {
// Format the current line after typing something
const range = {
start: {
character: 0,
line: params.position.line
},
end: params.position
};
if (this.isFormatRangeErrorFree(document, range)) {
return this.doDocumentFormat(document, params.options, range);
}
else {
return [];
}
}
get formatOnTypeOptions() {
return undefined;
}
doDocumentFormat(document, options, range) {
const map = new Map();
const collector = (node, mode, formatting) => {
const key = this.nodeModeToKey(node, mode);
const existing = map.get(key);
const priority = formatting.options.priority ?? 0;
const existingPriority = existing?.options.priority ?? 0;
if (!existing || existingPriority <= priority) {
map.set(key, formatting);
}
};
this.collector = collector;
this.iterateAstFormatting(document, range);
const edits = this.iterateCstFormatting(document, map, options, range);
return this.avoidOverlappingEdits(document.textDocument, edits);
}
avoidOverlappingEdits(textDocument, textEdits) {
const edits = [];
for (const edit of textEdits) {
let last = edits[edits.length - 1];
while (last) {
const currentStart = textDocument.offsetAt(edit.range.start);
const lastEnd = textDocument.offsetAt(last.range.end);
if (currentStart < lastEnd) {
edits.pop();
last = edits[edits.length - 1];
}
else {
break;
}
}
edits.push(edit);
}
return edits.filter(edit => this.isNecessary(edit, textDocument));
}
iterateAstFormatting(document, range) {
const root = document.parseResult.value;
this.format(root);
const treeIterator = streamAllContents(root).iterator();
let result;
do {
result = treeIterator.next();
if (!result.done) {
const node = result.value;
const inside = this.insideRange(node.$cstNode.range, range);
if (inside) {
this.format(node);
}
else {
treeIterator.prune();
}
}
} while (!result.done);
}
nodeModeToKey(node, mode) {
return `${node.offset}:${node.end}:${mode}`;
}
insideRange(inside, total) {
if (!total) {
return true;
}
if ((inside.start.line <= total.start.line && inside.end.line >= total.end.line) ||
(inside.start.line >= total.start.line && inside.end.line <= total.end.line) ||
(inside.start.line <= total.end.line && inside.end.line >= total.end.line)) {
return true;
}
return false;
}
isNecessary(edit, document) {
return edit.newText !== document.getText(edit.range).replace(/\r/g, '');
}
iterateCstFormatting(document, formattings, options, range) {
const context = {
indentation: 0,
options,
document: document.textDocument
};
const edits = [];
const cstTreeStream = this.iterateCstTree(document, context);
const iterator = cstTreeStream.iterator();
let lastNode;
let result;
do {
result = iterator.next();
if (!result.done) {
const node = result.value;
const isLeaf = isLeafCstNode(node);
const prependKey = this.nodeModeToKey(node, 'prepend');
const prependFormatting = formattings.get(prependKey);
formattings.delete(prependKey);
if (prependFormatting) {
const nodeEdits = this.createTextEdit(lastNode, node, prependFormatting, context);
for (const edit of nodeEdits) {
if (edit && this.insideRange(edit.range, range)) {
edits.push(edit);
}
}
}
const appendKey = this.nodeModeToKey(node, 'append');
const appendFormatting = formattings.get(appendKey);
formattings.delete(appendKey);
if (appendFormatting) {
const nextNode = getNextNode(node);
if (nextNode) {
const nodeEdits = this.createTextEdit(node, nextNode, appendFormatting, context);
for (const edit of nodeEdits) {
if (edit && this.insideRange(edit.range, range)) {
edits.push(edit);
}
}
}
}
if (!prependFormatting && node.hidden) {
const hiddenEdits = this.createHiddenTextEdits(lastNode, node, undefined, context);
for (const edit of hiddenEdits) {
if (edit && this.insideRange(edit.range, range)) {
edits.push(edit);
}
}
}
if (isLeaf) {
lastNode = node;
}
}
} while (!result.done);
return edits;
}
createHiddenTextEdits(previous, hidden, formatting, context) {
// Don't format the hidden node if it is on the same line as its previous node
const startLine = hidden.range.start.line;
if (previous && previous.range.end.line === startLine) {
return [];
}
const edits = [];
const startRange = {
start: {
character: 0,
line: startLine
},
end: hidden.range.start
};
const hiddenStartText = context.document.getText(startRange);
const move = this.findFittingMove(startRange, formatting?.moves ?? [], context);
const hiddenStartChar = this.getExistingIndentationCharacterCount(hiddenStartText, context);
const expectedStartChar = this.getIndentationCharacterCount(context, move);
const characterIncrease = expectedStartChar - hiddenStartChar;
if (characterIncrease === 0) {
return [];
}
let newText = '';
if (characterIncrease > 0) {
newText = (context.options.insertSpaces ? ' ' : '\t').repeat(characterIncrease);
}
const lines = hidden.text.split('\n');
lines[0] = hiddenStartText + lines[0];
for (let i = 0; i < lines.length; i++) {
const currentLine = startLine + i;
const pos = {
character: 0,
line: currentLine
};
if (characterIncrease > 0) {
edits.push({
newText,
range: {
start: pos,
end: pos
}
});
}
else {
const currentText = lines[i];
let j = 0;
for (; j < currentText.length; j++) {
const char = currentText.charAt(j);
if (char !== ' ' && char !== '\t') {
break;
}
}
edits.push({
newText: '',
range: {
start: pos,
end: {
line: currentLine,
// Remove as much whitespace characters as necessary
// In some cases `characterIncrease` is actually larger than the amount of whitespace available
// So we simply remove all whitespace characters `j`
character: Math.min(j, Math.abs(characterIncrease))
}
}
});
}
}
return edits;
}
getExistingIndentationCharacterCount(text, context) {
const tabWhitespace = ' '.repeat(context.options.tabSize);
let replacement = '';
let regex;
if (context.options.insertSpaces) {
regex = new RegExp('\\t', 'g');
replacement = tabWhitespace;
}
else {
regex = new RegExp(tabWhitespace, 'g');
replacement = '\t';
}
const normalized = text.replace(regex, replacement);
return normalized.length;
}
getIndentationCharacterCount(context, formattingMove) {
let indentation = context.indentation;
if (formattingMove && formattingMove.tabs) {
indentation += formattingMove.tabs;
}
return (context.options.insertSpaces ? context.options.tabSize : 1) * indentation;
}
createTextEdit(a, b, formatting, context) {
if (b.hidden) {
return this.createHiddenTextEdits(a, b, formatting, context);
}
// Ignore the edit if the previous node ends after the current node starts
if (a && (a.range.end.line > b.range.start.line ||
(a.range.end.line === b.range.start.line && a.range.end.character > b.range.start.character))) {
return [];
}
const betweenRange = {
start: a?.range.end ?? {
character: 0,
line: 0
},
end: b.range.start
};
const move = this.findFittingMove(betweenRange, formatting.moves, context);
if (!move) {
return [];
}
const chars = move.characters;
const lines = move.lines;
const tabs = move.tabs;
const existingIndentation = context.indentation;
context.indentation += (tabs ?? 0);
const edits = [];
if (chars !== undefined) {
// Do not apply formatting on the same line if preceding node is hidden
if (!a?.hidden) {
edits.push(this.createSpaceTextEdit(betweenRange, chars, formatting.options));
}
}
else if (lines !== undefined) {
edits.push(this.createLineTextEdit(betweenRange, lines, context, formatting.options));
}
else if (tabs !== undefined) {
edits.push(this.createTabTextEdit(betweenRange, Boolean(a), context));
}
if (isLeafCstNode(b)) {
context.indentation = existingIndentation;
}
return edits;
}
createSpaceTextEdit(range, spaces, options) {
if (range.start.line === range.end.line) {
const existingSpaces = range.end.character - range.start.character;
spaces = this.fitIntoOptions(spaces, existingSpaces, options);
}
const newText = ' '.repeat(spaces);
return {
newText,
range
};
}
createLineTextEdit(range, lines, context, options) {
const existingLines = range.end.line - range.start.line;
lines = this.fitIntoOptions(lines, existingLines, options);
const indent = context.options.insertSpaces ? ' '.repeat(context.options.tabSize) : '\t';
const nodeIndent = indent.repeat(context.indentation);
const newText = `${'\n'.repeat(lines)}${nodeIndent}`;
return {
newText,
range
};
}
createTabTextEdit(range, hasPrevious, context) {
const indent = context.options.insertSpaces ? ' '.repeat(context.options.tabSize) : '\t';
const nodeIndent = indent.repeat(context.indentation);
const minimumLines = hasPrevious ? 1 : 0;
const lines = Math.max(range.end.line - range.start.line, minimumLines);
const newText = `${'\n'.repeat(lines)}${nodeIndent}`;
return {
newText,
range
};
}
fitIntoOptions(value, existing, options) {
if (options.allowMore) {
value = Math.max(existing, value);
}
else if (options.allowLess) {
value = Math.min(existing, value);
}
return value;
}
findFittingMove(range, moves, _context) {
if (moves.length === 0) {
return undefined;
}
else if (moves.length === 1) {
return moves[0];
}
const existingLines = range.end.line - range.start.line;
for (const move of moves) {
if (move.lines !== undefined && existingLines <= move.lines) {
return move;
}
else if (move.lines === undefined && existingLines === 0) {
return move;
}
}
// Return the last move
return moves[moves.length - 1];
}
iterateCstTree(document, context) {
const root = document.parseResult.value;
const rootCst = root.$cstNode;
if (!rootCst) {
return EMPTY_STREAM;
}
return new TreeStreamImpl(rootCst, node => this.iterateCst(node, context));
}
iterateCst(node, context) {
if (!isCompositeCstNode(node)) {
return EMPTY_STREAM;
}
const initial = context.indentation;
return new StreamImpl(() => ({ index: 0 }), (state) => {
if (state.index < node.content.length) {
return { done: false, value: node.content[state.index++] };
}
else {
// Reset the indentation to the level when we entered the node
context.indentation = initial;
return DONE_RESULT;
}
});
}
}
export class DefaultNodeFormatter {
constructor(astNode, collector) {
this.astNode = astNode;
this.collector = collector;
}
node(node) {
return new FormattingRegion(node.$cstNode ? [node.$cstNode] : [], this.collector);
}
nodes(...nodes) {
const cstNodes = [];
for (const node of nodes) {
if (node.$cstNode) {
cstNodes.push(node.$cstNode);
}
}
return new FormattingRegion(cstNodes, this.collector);
}
property(feature, index) {
const cstNode = findNodeForProperty(this.astNode.$cstNode, feature, index);
return new FormattingRegion(cstNode ? [cstNode] : [], this.collector);
}
properties(...features) {
const nodes = [];
for (const feature of features) {
const cstNodes = findNodesForProperty(this.astNode.$cstNode, feature);
nodes.push(...cstNodes);
}
return new FormattingRegion(nodes, this.collector);
}
keyword(keyword, index) {
const cstNode = findNodeForKeyword(this.astNode.$cstNode, keyword, index);
return new FormattingRegion(cstNode ? [cstNode] : [], this.collector);
}
keywords(...keywords) {
const nodes = [];
for (const feature of keywords) {
const cstNodes = findNodesForKeyword(this.astNode.$cstNode, feature);
nodes.push(...cstNodes);
}
return new FormattingRegion(nodes, this.collector);
}
cst(nodes) {
return new FormattingRegion([...nodes], this.collector);
}
interior(start, end) {
const startNodes = start.nodes;
const endNodes = end.nodes;
if (startNodes.length !== 1 || endNodes.length !== 1) {
return new FormattingRegion([], this.collector);
}
let startNode = startNodes[0];
let endNode = endNodes[0];
if (startNode.offset > endNode.offset) {
const intermediate = startNode;
startNode = endNode;
endNode = intermediate;
}
return new FormattingRegion(getInteriorNodes(startNode, endNode), this.collector);
}
}
export class FormattingRegion {
constructor(nodes, collector) {
this.nodes = nodes;
this.collector = collector;
}
/**
* Prepends the specified formatting to all nodes of this region.
*/
prepend(formatting) {
for (const node of this.nodes) {
this.collector(node, 'prepend', formatting);
}
return this;
}
/**
* Appends the specified formatting to all nodes of this region.
*/
append(formatting) {
for (const node of this.nodes) {
this.collector(node, 'append', formatting);
}
return this;
}
/**
* Sorrounds all nodes of this region with the specified formatting.
* Functionally the same as invoking `prepend` and `append` with the same formatting.
*/
surround(formatting) {
for (const node of this.nodes) {
this.collector(node, 'prepend', formatting);
this.collector(node, 'append', formatting);
}
return this;
}
/**
* Creates a copy of this region with a slice of the selected nodes.
* For both start and end, a negative index can be used to indicate an offset from the end of the array.
* For example, -2 refers to the second to last element of the array.
* @param start The beginning index of the specified portion of the region. If start is undefined, then the slice begins at index 0.
* @param end The end index of the specified portion of the region. This is exclusive of the element at the index 'end'. If end is undefined, then the slice extends to the end of the region.
*/
slice(start, end) {
return new FormattingRegion(this.nodes.slice(start, end), this.collector);
}
}
/**
* Contains utilities to easily create formatting actions that can be applied to a {@link FormattingRegion}.
*/
export var Formatting;
(function (Formatting) {
/**
* Creates a new formatting that tries to fit the existing text into one of the specified formattings.
* @param formattings All possible formattings.
*/
function fit(...formattings) {
return {
options: {},
moves: formattings.flatMap(e => e.moves).sort(compareMoves)
};
}
Formatting.fit = fit;
/**
* Creates a new formatting that removes all spaces
*/
function noSpace(options) {
return spaces(0, options);
}
Formatting.noSpace = noSpace;
/**
* Creates a new formatting that creates a single space
*/
function oneSpace(options) {
return spaces(1, options);
}
Formatting.oneSpace = oneSpace;
/**
* Creates a new formatting that creates the specified amount of spaces
*
* @param count The amount of spaces to be inserted
*/
function spaces(count, options) {
return {
options: options ?? {},
moves: [{
characters: count
}]
};
}
Formatting.spaces = spaces;
/**
* Creates a new formatting that moves an element to the next line
*/
function newLine(options) {
return newLines(1, options);
}
Formatting.newLine = newLine;
/**
* Creates a new formatting that creates the specified amount of new lines.
*/
function newLines(count, options) {
return {
options: options ?? {},
moves: [{
lines: count
}]
};
}
Formatting.newLines = newLines;
/**
* Creates a new formatting that moves the element to a new line and indents that line.
*/
function indent(options) {
return {
options: options ?? {},
moves: [{
tabs: 1,
lines: 1
}]
};
}
Formatting.indent = indent;
/**
* Creates a new formatting that removes all indentation.
*/
function noIndent(options) {
return {
options: options ?? {},
moves: [{
tabs: 0
}]
};
}
Formatting.noIndent = noIndent;
function compareMoves(a, b) {
const aLines = a.lines ?? 0;
const bLines = b.lines ?? 0;
const aTabs = a.tabs ?? 0;
const bTabs = b.tabs ?? 0;
const aSpaces = a.characters ?? 0;
const bSpaces = b.characters ?? 0;
if (aLines < bLines) {
return -1;
}
else if (aLines > bLines) {
return 1;
}
else if (aTabs < bTabs) {
return -1;
}
else if (aTabs > bTabs) {
return 1;
}
else if (aSpaces < bSpaces) {
return -1;
}
else if (aSpaces > bSpaces) {
return 1;
}
else {
return 0;
}
}
})(Formatting || (Formatting = {}));
//# sourceMappingURL=formatter.js.map

48
frontend/node_modules/langium/lib/lsp/fuzzy-matcher.js generated vendored Normal file
View File

@@ -0,0 +1,48 @@
/******************************************************************************
* 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.
******************************************************************************/
export class DefaultFuzzyMatcher {
match(query, text) {
if (query.length === 0) {
return true;
}
let matchedFirstCharacter = false;
let previous;
let character = 0;
const len = text.length;
for (let i = 0; i < len; i++) {
const strChar = text.charCodeAt(i);
const testChar = query.charCodeAt(character);
if (strChar === testChar || this.toUpperCharCode(strChar) === this.toUpperCharCode(testChar)) {
matchedFirstCharacter || (matchedFirstCharacter = previous === undefined || // Beginning of word
this.isWordTransition(previous, strChar));
if (matchedFirstCharacter) {
character++;
}
if (character === query.length) {
return true;
}
}
previous = strChar;
}
return false;
}
isWordTransition(previous, current) {
return a <= previous && previous <= z && A <= current && current <= Z || // camelCase transition
previous === _ && current !== _; // snake_case transition
}
toUpperCharCode(charCode) {
if (a <= charCode && charCode <= z) {
return charCode - 32;
}
return charCode;
}
}
const a = 'a'.charCodeAt(0);
const z = 'z'.charCodeAt(0);
const A = 'A'.charCodeAt(0);
const Z = 'Z'.charCodeAt(0);
const _ = '_'.charCodeAt(0);
//# sourceMappingURL=fuzzy-matcher.js.map

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 { findCommentNode, findDeclarationNodeAtOffset } from '../utils/cst-utils.js';
import { isKeyword } from '../languages/generated/ast.js';
import { isJSDoc, parseJSDoc } from '../documentation/jsdoc.js';
import { isAstNodeWithComment } from '../serializer/json-serializer.js';
export class AstNodeHoverProvider {
constructor(services) {
this.references = services.references.References;
this.grammarConfig = services.parser.GrammarConfig;
}
async getHoverContent(document, params) {
const rootNode = document.parseResult?.value?.$cstNode;
if (rootNode) {
const offset = document.textDocument.offsetAt(params.position);
const cstNode = findDeclarationNodeAtOffset(rootNode, offset, this.grammarConfig.nameRegexp);
if (cstNode && cstNode.offset + cstNode.length > offset) {
const contents = [];
const targetNodes = this.references.findDeclarations(cstNode);
for (const targetNode of targetNodes) {
const content = await this.getAstNodeHoverContent(targetNode);
if (typeof content === 'string') {
contents.push(content);
}
}
if (contents.length > 0) {
return {
contents: {
kind: 'markdown',
value: contents.join(' ')
}
};
}
// Add support for documentation on keywords
if (isKeyword(cstNode.grammarSource)) {
return this.getKeywordHoverContent(cstNode.grammarSource);
}
}
}
return undefined;
}
getKeywordHoverContent(node) {
let comment = isAstNodeWithComment(node) ? node.$comment : undefined;
if (!comment) {
comment = findCommentNode(node.$cstNode, ['ML_COMMENT'])?.text;
}
if (comment && isJSDoc(comment)) {
const content = parseJSDoc(comment).toMarkdown();
if (content) {
return {
contents: {
kind: 'markdown',
value: content
}
};
}
}
return undefined;
}
}
export class MultilineCommentHoverProvider extends AstNodeHoverProvider {
constructor(services) {
super(services);
this.documentationProvider = services.documentation.DocumentationProvider;
}
getAstNodeHoverContent(node) {
const content = this.documentationProvider.getDocumentation(node);
if (content) {
return content;
}
return undefined;
}
}
//# sourceMappingURL=hover-provider.js.map

View File

@@ -0,0 +1,28 @@
/******************************************************************************
* 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 { InlayHint, InlayHintParams } from 'vscode-languageserver';
import type { AstNode } from '../syntax-tree.js';
import { CancellationToken } from '../utils/cancellation.js';
import type { MaybePromise } from '../utils/promise-utils.js';
import type { LangiumDocument } from '../workspace/documents.js';
export type InlayHintAcceptor = (inlayHint: InlayHint) => void;
/**
* Provider for the inlay hint LSP type.
*/
export interface InlayHintProvider {
/**
* Handle the `textDocument.inlayHint` language server request.
*
* @throws `OperationCancelled` if cancellation is detected during execution
* @throws `ResponseError` if an error is detected that should be sent as response to the client
*/
getInlayHints(document: LangiumDocument, params: InlayHintParams, cancelToken?: CancellationToken): MaybePromise<InlayHint[] | undefined>;
}
export declare abstract class AbstractInlayHintProvider implements InlayHintProvider {
getInlayHints(document: LangiumDocument, params: InlayHintParams, cancelToken?: CancellationToken): Promise<InlayHint[] | undefined>;
abstract computeInlayHint(astNode: AstNode, acceptor: InlayHintAcceptor): void;
}
//# sourceMappingURL=inlay-hint-provider.d.ts.map

View File

@@ -0,0 +1,21 @@
/******************************************************************************
* 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 { CancellationToken } from '../utils/cancellation.js';
import { streamAst } from '../utils/ast-utils.js';
import { interruptAndCheck } from '../utils/promise-utils.js';
export class AbstractInlayHintProvider {
async getInlayHints(document, params, cancelToken = CancellationToken.None) {
const root = document.parseResult.value;
const inlayHints = [];
const acceptor = hint => inlayHints.push(hint);
for (const node of streamAst(root, { range: params.range })) {
await interruptAndCheck(cancelToken);
this.computeInlayHint(node, acceptor);
}
return inlayHints;
}
}
//# sourceMappingURL=inlay-hint-provider.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"inlay-hint-provider.js","sourceRoot":"","sources":["../../src/lsp/inlay-hint-provider.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAIhF,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAG7D,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAiB9D,MAAM,OAAgB,yBAAyB;IAC3C,KAAK,CAAC,aAAa,CAAC,QAAyB,EAAE,MAAuB,EAAE,WAAW,GAAG,iBAAiB,CAAC,IAAI;QACxG,MAAM,IAAI,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC;QACxC,MAAM,UAAU,GAAgB,EAAE,CAAC;QACnC,MAAM,QAAQ,GAAsB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAClE,KAAK,MAAM,IAAI,IAAI,SAAS,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,EAAE,CAAC;YAC1D,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;YACrC,IAAI,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;QAC1C,CAAC;QACD,OAAO,UAAU,CAAC;IACtB,CAAC;CAGJ"}

View File

@@ -0,0 +1 @@
{"version":3,"file":"lsp-services.d.ts","sourceRoot":"","sources":["../../src/lsp/lsp-services.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,7 @@
/******************************************************************************
* 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.
******************************************************************************/
export {};
//# sourceMappingURL=lsp-services.js.map

View File

@@ -0,0 +1,25 @@
/******************************************************************************
* 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, SymbolKind } from 'vscode-languageserver';
/**
* Default implementation of the `NodeKindProvider` interface.
* @remarks This implementation returns `SymbolKind.Field` for all nodes and `CompletionItemKind.Reference` for all nodes. Extend this class to customize symbol and completion types your langauge.
*/
export class DefaultNodeKindProvider {
/**
* @remarks The default implementation returns `SymbolKind.Field` for all nodes.
*/
getSymbolKind(_node) {
return SymbolKind.Field;
}
/**
* @remarks The default implementation returns `CompletionItemKind.Reference` for all nodes.
*/
getCompletionItemKind(_node) {
return CompletionItemKind.Reference;
}
}
//# sourceMappingURL=node-kind-provider.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"references-provider.d.ts","sourceRoot":"","sources":["../../src/lsp/references-provider.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAC7D,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACrD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAGjD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IAC/B;;;;;;;;;;OAUG;IACH,cAAc,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,eAAe,EAAE,WAAW,CAAC,EAAE,iBAAiB,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAC,CAAC;CACjI;AAED,qBAAa,yBAA0B,YAAW,kBAAkB;IAChE,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IAC9C,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAC1C,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;gBAEpC,QAAQ,EAAE,eAAe;IAMrC,cAAc,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,eAAe,EAAE,YAAY,CAAC,EAAE,iBAAiB,GAAG,YAAY,CAAC,QAAQ,EAAE,CAAC;IAc9H,SAAS,CAAC,aAAa,CAAC,YAAY,EAAE,WAAW,EAAE,MAAM,EAAE,eAAe,EAAE,SAAS,EAAE,eAAe,GAAG,QAAQ,EAAE;CAWtH"}

View File

@@ -0,0 +1,54 @@
/******************************************************************************
* 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 { Position, Range, RenameParams, TextDocumentPositionParams, WorkspaceEdit } from 'vscode-languageserver-protocol';
import type { CancellationToken } from '../utils/cancellation.js';
import type { GrammarConfig } from '../languages/grammar-config.js';
import type { NameProvider } from '../references/name-provider.js';
import type { References } from '../references/references.js';
import type { LangiumServices } from './lsp-services.js';
import type { CstNode } from '../syntax-tree.js';
import type { MaybePromise } from '../utils/promise-utils.js';
import type { LangiumDocument } from '../workspace/documents.js';
/**
* Language-specific service for handling rename requests and prepare rename requests.
*/
export interface RenameProvider {
/**
* Handle a rename request.
*
* @param document The document in which the rename request was triggered.
* @param params The rename parameters.
* @param cancelToken A cancellation token that can be used to cancel the request.
* @returns A workspace edit that describes the changes to be applied to the workspace.
*
* @throws `OperationCancelled` if cancellation is detected during execution
* @throws `ResponseError` if an error is detected that should be sent as response to the client
*/
rename(document: LangiumDocument, params: RenameParams, cancelToken?: CancellationToken): MaybePromise<WorkspaceEdit | undefined>;
/**
* Handle a prepare rename request.
*
* @param document The document in which the prepare rename request was triggered.
* @param params The prepare rename parameters.
* @param cancelToken A cancellation token that can be used to cancel the request.
* @returns A range that describes the range of the symbol to be renamed.
*
* @throws `OperationCancelled` if cancellation is detected during execution
* @throws `ResponseError` if an error is detected that should be sent as response to the client
*/
prepareRename(document: LangiumDocument, params: TextDocumentPositionParams, cancelToken?: CancellationToken): MaybePromise<Range | undefined>;
}
export declare class DefaultRenameProvider implements RenameProvider {
protected readonly references: References;
protected readonly nameProvider: NameProvider;
protected readonly grammarConfig: GrammarConfig;
constructor(services: LangiumServices);
rename(document: LangiumDocument, params: RenameParams, _cancelToken?: CancellationToken): Promise<WorkspaceEdit | undefined>;
prepareRename(document: LangiumDocument, params: TextDocumentPositionParams, _cancelToken?: CancellationToken): MaybePromise<Range | undefined>;
protected renameNodeRange(doc: LangiumDocument, position: Position): Range | undefined;
protected isNameNode(leafNode: CstNode | undefined): boolean | undefined;
}
//# sourceMappingURL=rename-provider.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"rename-provider.d.ts","sourceRoot":"","sources":["../../src/lsp/rename-provider.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,YAAY,EAAE,0BAA0B,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AAC/H,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAClE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AACnE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,6BAA6B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACzD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAKjE;;GAEG;AACH,MAAM,WAAW,cAAc;IAC3B;;;;;;;;;;OAUG;IACH,MAAM,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,YAAY,EAAE,WAAW,CAAC,EAAE,iBAAiB,GAAG,YAAY,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;IAElI;;;;;;;;;;OAUG;IACH,aAAa,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,0BAA0B,EAAE,WAAW,CAAC,EAAE,iBAAiB,GAAG,YAAY,CAAC,KAAK,GAAG,SAAS,CAAC,CAAC;CAClJ;AAED,qBAAa,qBAAsB,YAAW,cAAc;IAExD,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAC1C,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IAC9C,SAAS,CAAC,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;gBAEpC,QAAQ,EAAE,eAAe;IAM/B,MAAM,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,CAAC,EAAE,iBAAiB,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC;IAgCnI,aAAa,CAAC,QAAQ,EAAE,eAAe,EAAE,MAAM,EAAE,0BAA0B,EAAE,YAAY,CAAC,EAAE,iBAAiB,GAAG,YAAY,CAAC,KAAK,GAAG,SAAS,CAAC;IAI/I,SAAS,CAAC,eAAe,CAAC,GAAG,EAAE,eAAe,EAAE,QAAQ,EAAE,QAAQ,GAAG,KAAK,GAAG,SAAS;IAiBtF,SAAS,CAAC,UAAU,CAAC,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS;CAG3E"}

View File

@@ -0,0 +1,70 @@
/******************************************************************************
* 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 { TextEdit } from 'vscode-languageserver-types';
import { isNamed } from '../references/name-provider.js';
import { findDeclarationNodeAtOffset } from '../utils/cst-utils.js';
export class DefaultRenameProvider {
constructor(services) {
this.references = services.references.References;
this.nameProvider = services.references.NameProvider;
this.grammarConfig = services.parser.GrammarConfig;
}
async rename(document, params, _cancelToken) {
const changes = {};
const rootNode = document.parseResult.value.$cstNode;
if (!rootNode) {
return undefined;
}
const offset = document.textDocument.offsetAt(params.position);
const leafNode = findDeclarationNodeAtOffset(rootNode, offset, this.grammarConfig.nameRegexp);
if (!leafNode) {
return undefined;
}
const targetNodes = this.references.findDeclarations(leafNode);
if (targetNodes.length === 0) {
return undefined;
}
// We only need to find the references to a single target node
// All other nodes should be found via `findReferences` if done correctly
const targetNode = targetNodes[0];
const options = { onlyLocal: false, includeDeclaration: true };
const references = this.references.findReferences(targetNode, options);
for (const ref of references) {
const change = TextEdit.replace(ref.segment.range, params.newName);
const uri = ref.sourceUri.toString();
if (changes[uri]) {
changes[uri].push(change);
}
else {
changes[uri] = [change];
}
}
return { changes };
}
prepareRename(document, params, _cancelToken) {
return this.renameNodeRange(document, params.position);
}
renameNodeRange(doc, position) {
const rootNode = doc.parseResult.value.$cstNode;
const offset = doc.textDocument.offsetAt(position);
if (rootNode) {
const leafNode = findDeclarationNodeAtOffset(rootNode, offset, this.grammarConfig.nameRegexp);
if (!leafNode) {
return undefined;
}
const isCrossRef = this.references.findDeclarations(leafNode).length > 0;
// return range if selected CstNode is the name node or it is a crosslink which points to a declaration
if (isCrossRef || this.isNameNode(leafNode)) {
return leafNode.range;
}
}
return undefined;
}
isNameNode(leafNode) {
return leafNode?.astNode && isNamed(leafNode.astNode) && leafNode === this.nameProvider.getNameNode(leafNode.astNode);
}
}
//# sourceMappingURL=rename-provider.js.map

View File

@@ -0,0 +1,415 @@
/******************************************************************************
* 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 { SemanticTokensBuilder as BaseSemanticTokensBuilder, SemanticTokenModifiers, SemanticTokenTypes } from 'vscode-languageserver';
import { CancellationToken } from '../utils/cancellation.js';
import { streamAst } from '../utils/ast-utils.js';
import { inRange } from '../utils/cst-utils.js';
import { findNodeForKeyword, findNodeForProperty, findNodesForKeyword, findNodesForProperty } from '../utils/grammar-utils.js';
import { interruptAndCheck } from '../utils/promise-utils.js';
export const AllSemanticTokenTypes = {
[SemanticTokenTypes.class]: 0,
[SemanticTokenTypes.comment]: 1,
[SemanticTokenTypes.enum]: 2,
[SemanticTokenTypes.enumMember]: 3,
[SemanticTokenTypes.event]: 4,
[SemanticTokenTypes.function]: 5,
[SemanticTokenTypes.interface]: 6,
[SemanticTokenTypes.keyword]: 7,
[SemanticTokenTypes.macro]: 8,
[SemanticTokenTypes.method]: 9,
[SemanticTokenTypes.modifier]: 10,
[SemanticTokenTypes.namespace]: 11,
[SemanticTokenTypes.number]: 12,
[SemanticTokenTypes.operator]: 13,
[SemanticTokenTypes.parameter]: 14,
[SemanticTokenTypes.property]: 15,
[SemanticTokenTypes.regexp]: 16,
[SemanticTokenTypes.string]: 17,
[SemanticTokenTypes.struct]: 18,
[SemanticTokenTypes.type]: 19,
[SemanticTokenTypes.typeParameter]: 20,
[SemanticTokenTypes.variable]: 21,
[SemanticTokenTypes.decorator]: 22
};
export const AllSemanticTokenModifiers = {
[SemanticTokenModifiers.abstract]: 1 << 0,
[SemanticTokenModifiers.async]: 1 << 1,
[SemanticTokenModifiers.declaration]: 1 << 2,
[SemanticTokenModifiers.defaultLibrary]: 1 << 3,
[SemanticTokenModifiers.definition]: 1 << 4,
[SemanticTokenModifiers.deprecated]: 1 << 5,
[SemanticTokenModifiers.documentation]: 1 << 6,
[SemanticTokenModifiers.modification]: 1 << 7,
[SemanticTokenModifiers.readonly]: 1 << 8,
[SemanticTokenModifiers.static]: 1 << 9
};
/**
* @deprecated Since 3.2.0. `SemanticTokenProvider` now supplies its own options.
*/
export const DefaultSemanticTokenOptions = {
legend: {
tokenTypes: Object.keys(AllSemanticTokenTypes),
tokenModifiers: Object.keys(AllSemanticTokenModifiers)
},
full: {
delta: false
},
range: true
};
export function mergeSemanticTokenProviderOptions(options) {
const tokenTypes = [];
const tokenModifiers = [];
let full = true;
let delta = true;
let range = true;
for (const option of options) {
if (!option) {
continue;
}
option.legend.tokenTypes.forEach((tokenType, index) => {
const existing = tokenTypes[index];
if (existing && existing !== tokenType) {
throw new Error(`Cannot merge '${existing}' and '${tokenType}' token types. They use the same index ${index}.`);
}
else {
tokenTypes[index] = tokenType;
}
});
option.legend.tokenModifiers.forEach((tokenModifier, index) => {
const existing = tokenModifiers[index];
if (existing && existing !== tokenModifier) {
throw new Error(`Cannot merge '${existing}' and '${tokenModifier}' token modifier. They use the same index ${index}.`);
}
else {
tokenModifiers[index] = tokenModifier;
}
});
if (!option.full) {
full = false;
}
else if (typeof option.full === 'object' && !option.full.delta) {
delta = false;
}
if (!option.range) {
range = false;
}
}
return {
legend: {
tokenTypes,
tokenModifiers,
},
full: full && { delta },
range,
};
}
export class SemanticTokensBuilder extends BaseSemanticTokensBuilder {
constructor() {
super(...arguments);
this._tokens = [];
}
push(line, char, length, tokenType, tokenModifiers) {
this._tokens.push({
line,
char,
length,
tokenType,
tokenModifiers
});
}
build() {
this.applyTokens();
return super.build();
}
buildEdits() {
this.applyTokens();
return super.buildEdits();
}
/**
* Flushes the cached delta token values
*/
flush() {
this.previousResult(this.id);
}
applyTokens() {
for (const token of this._tokens.sort(this.compareTokens)) {
super.push(token.line, token.char, token.length, token.tokenType, token.tokenModifiers);
}
this._tokens = [];
}
compareTokens(a, b) {
// Branchless comparison for line and character
return (a.line - b.line) || (a.char - b.char);
}
}
/**
* A basic super class for providing semantic token data.
* Users of Langium should extend this class to create their own `SemanticTokenProvider`.
*
* The entry method for generating semantic tokens based on an `AstNode` is the `highlightElement` method.
*/
export class AbstractSemanticTokenProvider {
constructor(services) {
/**
* Store a token builder for each open document.
*/
this.tokensBuilders = new Map();
// Delete the token builder once the text document has been closed
services.shared.workspace.TextDocuments.onDidClose(e => {
this.tokensBuilders.delete(e.document.uri);
});
services.shared.lsp.LanguageServer.onInitialize(params => {
this.initialize(params.capabilities.textDocument?.semanticTokens);
});
}
initialize(clientCapabilities) {
this.clientCapabilities = clientCapabilities;
}
get tokenTypes() {
return AllSemanticTokenTypes;
}
get tokenModifiers() {
return AllSemanticTokenModifiers;
}
get semanticTokensOptions() {
return {
legend: {
tokenTypes: Object.keys(this.tokenTypes),
tokenModifiers: Object.keys(this.tokenModifiers),
},
full: {
// The semantic token delta support is disabled by default in Langium.
// Since Langium recomputes the whole document on every change, we cannot provide a good delta.
// Adopters can override this if they support it.
delta: false
},
range: true,
};
}
async semanticHighlight(document, _params, cancelToken = CancellationToken.None) {
this.currentRange = undefined;
this.currentDocument = document;
this.currentTokensBuilder = this.getDocumentTokensBuilder(document);
this.currentTokensBuilder.flush();
await this.computeHighlighting(document, this.createAcceptor(), cancelToken);
return this.currentTokensBuilder.build();
}
async semanticHighlightRange(document, params, cancelToken = CancellationToken.None) {
this.currentRange = params.range;
this.currentDocument = document;
this.currentTokensBuilder = this.getDocumentTokensBuilder(document);
this.currentTokensBuilder.flush();
await this.computeHighlighting(document, this.createAcceptor(), cancelToken);
return this.currentTokensBuilder.build();
}
async semanticHighlightDelta(document, params, cancelToken = CancellationToken.None) {
this.currentRange = undefined;
this.currentDocument = document;
this.currentTokensBuilder = this.getDocumentTokensBuilder(document);
this.currentTokensBuilder.previousResult(params.previousResultId);
await this.computeHighlighting(document, this.createAcceptor(), cancelToken);
return this.currentTokensBuilder.buildEdits();
}
createAcceptor() {
const acceptor = options => {
if ('line' in options) {
this.highlightToken({
range: {
start: {
line: options.line,
character: options.char
},
end: {
line: options.line,
character: options.char + options.length
}
},
type: options.type,
modifier: options.modifier
});
}
else if ('range' in options) {
this.highlightToken(options);
}
else if ('keyword' in options) {
this.highlightKeyword(options);
}
else if ('property' in options) {
this.highlightProperty(options);
}
else {
this.highlightNode({
node: options.cst,
type: options.type,
modifier: options.modifier
});
}
};
return acceptor;
}
getDocumentTokensBuilder(document) {
const existing = this.tokensBuilders.get(document.uri.toString());
if (existing) {
return existing;
}
const builder = new SemanticTokensBuilder();
this.tokensBuilders.set(document.uri.toString(), builder);
return builder;
}
async computeHighlighting(document, acceptor, cancelToken) {
const root = document.parseResult.value;
const treeIterator = streamAst(root, { range: this.currentRange }).iterator();
let result;
do {
result = treeIterator.next();
if (!result.done) {
await interruptAndCheck(cancelToken);
const node = result.value;
if (this.highlightElement(node, acceptor) === 'prune') {
treeIterator.prune();
}
}
} while (!result.done);
}
highlightToken(options) {
const { range, type } = options;
let modifiers = options.modifier;
if ((this.currentRange && !inRange(range, this.currentRange)) || !this.currentDocument || !this.currentTokensBuilder) {
return;
}
const intType = this.tokenTypes[type];
let totalModifier = 0;
if (modifiers !== undefined) {
if (typeof modifiers === 'string') {
modifiers = [modifiers];
}
for (const modifier of modifiers) {
const intModifier = this.tokenModifiers[modifier];
totalModifier |= intModifier;
}
}
const startLine = range.start.line;
const endLine = range.end.line;
if (startLine === endLine) {
// Token only spans a single line
const char = range.start.character;
const length = range.end.character - char;
this.currentTokensBuilder.push(startLine, char, length, intType, totalModifier);
}
else if (this.clientCapabilities?.multilineTokenSupport) {
// Let token span multiple lines
const startChar = range.start.character;
const startOffset = this.currentDocument.textDocument.offsetAt(range.start);
const endOffset = this.currentDocument.textDocument.offsetAt(range.end);
this.currentTokensBuilder.push(startLine, startChar, endOffset - startOffset, intType, totalModifier);
}
else {
// Token spans multiple lines, but the client doesn't support it
// Split the range into multiple semantic tokens
const firstLineStart = range.start;
let nextLineOffset = this.currentDocument.textDocument.offsetAt({
line: startLine + 1,
character: 0
});
// Build first line
this.currentTokensBuilder.push(firstLineStart.line, firstLineStart.character, nextLineOffset - firstLineStart.character - 1, intType, totalModifier);
// Build all lines in between first and last
for (let i = startLine + 1; i < endLine; i++) {
const currentLineOffset = nextLineOffset;
nextLineOffset = this.currentDocument.textDocument.offsetAt({
line: i + 1,
character: 0
});
this.currentTokensBuilder.push(i, 0, nextLineOffset - currentLineOffset - 1, intType, totalModifier);
}
// Build last line
this.currentTokensBuilder.push(endLine, 0, range.end.character, intType, totalModifier);
}
}
highlightProperty(options) {
const nodes = [];
if (typeof options.index === 'number') {
const node = findNodeForProperty(options.node.$cstNode, options.property, options.index);
if (node) {
nodes.push(node);
}
}
else {
nodes.push(...findNodesForProperty(options.node.$cstNode, options.property));
}
const { type, modifier } = options;
for (const node of nodes) {
this.highlightNode({
node,
type,
modifier
});
}
}
highlightKeyword(options) {
const { node, keyword, type, index, modifier } = options;
const nodes = [];
if (typeof index === 'number') {
const keywordNode = findNodeForKeyword(node.$cstNode, keyword, index);
if (keywordNode) {
nodes.push(keywordNode);
}
}
else {
nodes.push(...findNodesForKeyword(node.$cstNode, keyword));
}
for (const keywordNode of nodes) {
this.highlightNode({
node: keywordNode,
type,
modifier
});
}
}
highlightNode(options) {
const { node, type, modifier } = options;
const range = node.range;
this.highlightToken({
range,
type,
modifier
});
}
}
export var SemanticTokensDecoder;
(function (SemanticTokensDecoder) {
function decode(tokens, tokenTypes, document) {
const typeMap = new Map();
Object.entries(tokenTypes).forEach(([type, index]) => typeMap.set(index, type));
let line = 0;
let character = 0;
return sliceIntoChunks(tokens.data, 5).map(t => {
line += t[0];
if (t[0] !== 0) {
character = 0;
}
character += t[1];
const length = t[2];
const offset = document.textDocument.offsetAt({ line, character });
return {
offset,
tokenType: typeMap.get(t[3]),
tokenModifiers: t[4],
text: document.textDocument.getText({ start: { line, character }, end: { line, character: character + length } })
};
});
}
SemanticTokensDecoder.decode = decode;
function sliceIntoChunks(arr, chunkSize) {
const res = [];
for (let i = 0; i < arr.length; i += chunkSize) {
const chunk = arr.slice(i, i + chunkSize);
res.push(chunk);
}
return res;
}
})(SemanticTokensDecoder || (SemanticTokensDecoder = {}));
//# sourceMappingURL=semantic-token-provider.js.map

View File

@@ -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 { SymbolKind } from 'vscode-languageserver';
import { findDeclarationNodeAtOffset } from '../utils/cst-utils.js';
import { URI } from '../utils/uri-utils.js';
export class AbstractTypeHierarchyProvider {
constructor(services) {
this.grammarConfig = services.parser.GrammarConfig;
this.nameProvider = services.references.NameProvider;
this.documents = services.shared.workspace.LangiumDocuments;
this.references = services.references.References;
}
prepareTypeHierarchy(document, params, _cancelToken) {
const rootNode = document.parseResult.value;
const targetNode = findDeclarationNodeAtOffset(rootNode.$cstNode, document.textDocument.offsetAt(params.position), this.grammarConfig.nameRegexp);
if (!targetNode) {
return undefined;
}
const declarationNodes = this.references.findDeclarationNodes(targetNode);
const items = [];
for (const declarationNode of declarationNodes) {
items.push(...(this.getTypeHierarchyItems(declarationNode.astNode, document) ?? []));
}
return items;
}
getTypeHierarchyItems(targetNode, document) {
const nameNode = this.nameProvider.getNameNode(targetNode);
const name = this.nameProvider.getName(targetNode);
if (!nameNode || !targetNode.$cstNode || name === undefined) {
return undefined;
}
return [
{
kind: SymbolKind.Class,
name,
range: targetNode.$cstNode.range,
selectionRange: nameNode.range,
uri: document.uri.toString(),
...this.getTypeHierarchyItem(targetNode),
},
];
}
/**
* Override this method to change default properties of the type hierarchy item or add additional ones like `tags`
* or `details`.
*
* @example
* // Change the node kind to SymbolKind.Interface
* return { kind: SymbolKind.Interface }
*
* @see NodeKindProvider
*/
getTypeHierarchyItem(_targetNode) {
return undefined;
}
async supertypes(params, _cancelToken) {
const document = await this.documents.getOrCreateDocument(URI.parse(params.item.uri));
const rootNode = document.parseResult.value;
const targetNode = findDeclarationNodeAtOffset(rootNode.$cstNode, document.textDocument.offsetAt(params.item.range.start), this.grammarConfig.nameRegexp);
if (!targetNode) {
return undefined;
}
return this.getSupertypes(targetNode.astNode);
}
async subtypes(params, _cancelToken) {
const document = await this.documents.getOrCreateDocument(URI.parse(params.item.uri));
const rootNode = document.parseResult.value;
const targetNode = findDeclarationNodeAtOffset(rootNode.$cstNode, document.textDocument.offsetAt(params.item.range.start), this.grammarConfig.nameRegexp);
if (!targetNode) {
return undefined;
}
return this.getSubtypes(targetNode.astNode);
}
}
//# sourceMappingURL=type-hierarchy-provider.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"workspace-symbol-provider.js","sourceRoot":"","sources":["../../src/lsp/workspace-symbol-provider.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAShF,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AA8B9D,MAAM,OAAO,8BAA8B;IAMvC,YAAY,QAA+B;QACvC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,SAAS,CAAC,YAAY,CAAC;QACpD,IAAI,CAAC,gBAAgB,GAAG,QAAQ,CAAC,GAAG,CAAC,gBAAgB,CAAC;QACtD,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,YAAY,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,MAA6B,EAAE,WAAW,GAAG,iBAAiB,CAAC,IAAI;QAChF,MAAM,gBAAgB,GAAsB,EAAE,CAAC;QAC/C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC;QACzC,KAAK,MAAM,WAAW,IAAI,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE,EAAE,CAAC;YACxD,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;YACrC,IAAI,IAAI,CAAC,YAAY,CAAC,KAAK,CAAC,KAAK,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;gBACnD,MAAM,MAAM,GAAG,IAAI,CAAC,kBAAkB,CAAC,WAAW,CAAC,CAAC;gBACpD,IAAI,MAAM,EAAE,CAAC;oBACT,gBAAgB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;gBAClC,CAAC;YACL,CAAC;QACL,CAAC;QACD,OAAO,gBAAgB,CAAC;IAC5B,CAAC;IAES,kBAAkB,CAAC,cAAkC;QAC3D,MAAM,WAAW,GAAG,cAAc,CAAC,WAAW,CAAC;QAC/C,IAAI,WAAW,EAAE,CAAC;YACd,OAAO;gBACH,IAAI,EAAE,IAAI,CAAC,gBAAgB,CAAC,aAAa,CAAC,cAAc,CAAC;gBACzD,IAAI,EAAE,cAAc,CAAC,IAAI;gBACzB,QAAQ,EAAE;oBACN,KAAK,EAAE,WAAW,CAAC,KAAK;oBACxB,GAAG,EAAE,cAAc,CAAC,WAAW,CAAC,QAAQ,EAAE;iBAC7C;aACJ,CAAC;QACN,CAAC;aAAM,CAAC;YACJ,OAAO,SAAS,CAAC;QACrB,CAAC;IACL,CAAC;CACJ"}

10
frontend/node_modules/langium/lib/node/index.d.ts generated vendored Normal file
View File

@@ -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.
*
* @module langium/node
*/
export * from './node-file-system-provider.js';
export * from './worker-thread-async-parser.js';
//# sourceMappingURL=index.d.ts.map

View File

@@ -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 { LangiumCoreServices } from '../services.js';
import { ParserWorker } from '../parser/async-parser.js';
import { AbstractThreadedAsyncParser } from '../parser/async-parser.js';
import { Worker } from 'node:worker_threads';
export declare class WorkerThreadAsyncParser extends AbstractThreadedAsyncParser {
protected workerPath: string | (() => string);
constructor(services: LangiumCoreServices, workerPath: string | (() => string));
protected createWorker(): ParserWorker;
}
export declare class WorkerThreadParserWorker extends ParserWorker {
constructor(worker: Worker);
}
//# sourceMappingURL=worker-thread-async-parser.d.ts.map

View File

@@ -0,0 +1,26 @@
/******************************************************************************
* 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 { ParserWorker } from '../parser/async-parser.js';
import { AbstractThreadedAsyncParser } from '../parser/async-parser.js';
import { Worker } from 'node:worker_threads';
export class WorkerThreadAsyncParser extends AbstractThreadedAsyncParser {
constructor(services, workerPath) {
super(services);
this.workerPath = workerPath;
}
createWorker() {
const path = typeof this.workerPath === 'function' ? this.workerPath() : this.workerPath;
const worker = new Worker(path);
const parserWorker = new WorkerThreadParserWorker(worker);
return parserWorker;
}
}
export class WorkerThreadParserWorker extends ParserWorker {
constructor(worker) {
super((message) => worker.postMessage(message), cb => worker.on('message', cb), cb => worker.on('error', cb), () => worker.terminate());
}
}
//# sourceMappingURL=worker-thread-async-parser.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"worker-thread-async-parser.js","sourceRoot":"","sources":["../../src/node/worker-thread-async-parser.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAGhF,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAE7C,MAAM,OAAO,uBAAwB,SAAQ,2BAA2B;IAIpE,YAAY,QAA6B,EAAE,UAAmC;QAC1E,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IACjC,CAAC;IAEkB,YAAY;QAC3B,MAAM,IAAI,GAAG,OAAO,IAAI,CAAC,UAAU,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,CAAC;QACzF,MAAM,MAAM,GAAG,IAAI,MAAM,CAAC,IAAI,CAAC,CAAC;QAChC,MAAM,YAAY,GAAG,IAAI,wBAAwB,CAAC,MAAM,CAAC,CAAC;QAC1D,OAAO,YAAY,CAAC;IACxB,CAAC;CAEJ;AAED,MAAM,OAAO,wBAAyB,SAAQ,YAAY;IAEtD,YAAY,MAAc;QACtB,KAAK,CACD,CAAC,OAAO,EAAE,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,EACxC,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,EAAE,CAAC,EAC9B,EAAE,CAAC,EAAE,CAAC,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,EAC5B,GAAG,EAAE,CAAC,MAAM,CAAC,SAAS,EAAE,CAC3B,CAAC;IACN,CAAC;CAEJ"}

View File

@@ -0,0 +1 @@
{"version":3,"file":"async-parser.js","sourceRoot":"","sources":["../../src/parser/async-parser.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1 @@
{"version":3,"file":"completion-parser-builder.js","sourceRoot":"","sources":["../../src/parser/completion-parser-builder.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAGhF,OAAO,EAAE,uBAAuB,EAAE,MAAM,qBAAqB,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAExD,MAAM,UAAU,sBAAsB,CAAC,QAA6B;IAChE,MAAM,OAAO,GAAG,QAAQ,CAAC,OAAO,CAAC;IACjC,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,KAAK,CAAC;IACpC,MAAM,MAAM,GAAG,IAAI,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACrD,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;IAChD,MAAM,CAAC,QAAQ,EAAE,CAAC;IAClB,OAAO,MAAM,CAAC;AAClB,CAAC"}

View File

@@ -0,0 +1 @@
{"version":3,"file":"cst-node-builder.d.ts","sourceRoot":"","sources":["../../src/parser/cst-node-builder.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,183 @@
/******************************************************************************
* Copyright 2024 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 { CustomPatternMatcherFunc, TokenType, IToken, TokenVocabulary } from 'chevrotain';
import type { Grammar, TerminalRule } from '../languages/generated/ast.js';
import type { LexingReport, TokenBuilderOptions } from './token-builder.js';
import type { LexerResult, TokenizeOptions } from './lexer.js';
import type { LangiumCoreServices } from '../services.js';
import { DefaultTokenBuilder } from './token-builder.js';
import { DefaultLexer } from './lexer.js';
type IndentationAwareDelimiter<TokenName extends string> = [begin: TokenName, end: TokenName];
export interface IndentationTokenBuilderOptions<TerminalName extends string = string, KeywordName extends string = string> {
/**
* The name of the token used to denote indentation in the grammar.
* A possible definition in the grammar could look like this:
* ```langium
* terminal INDENT: ':synthetic-indent:';
* ```
*
* @default 'INDENT'
*/
indentTokenName: TerminalName;
/**
* The name of the token used to denote deindentation in the grammar.
* A possible definition in the grammar could look like this:
* ```langium
* terminal DEDENT: ':synthetic-dedent:';
* ```
*
* @default 'DEDENT'
*/
dedentTokenName: TerminalName;
/**
* The name of the token used to denote whitespace other than indentation and newlines in the grammar.
* A possible definition in the grammar could look like this:
* ```langium
* hidden terminal WS: /[ \t]+/;
* ```
*
* @default 'WS'
*/
whitespaceTokenName: TerminalName;
/**
* The delimiter tokens inside of which indentation should be ignored and treated as normal whitespace.
* For example, Python doesn't treat any whitespace between `(` and `)` as significant.
*
* Can be either terminal tokens or keyword tokens.
*
* @default []
*/
ignoreIndentationDelimiters: Array<IndentationAwareDelimiter<TerminalName | KeywordName>>;
}
export declare const indentationBuilderDefaultOptions: IndentationTokenBuilderOptions;
export declare enum LexingMode {
REGULAR = "indentation-sensitive",
IGNORE_INDENTATION = "ignore-indentation"
}
export interface IndentationLexingReport extends LexingReport {
/** Dedent tokens that are necessary to close the remaining indents. */
remainingDedents: IToken[];
}
/**
* A token builder that is sensitive to indentation in the input text.
* It will generate tokens for indentation and dedentation based on the indentation level.
*
* The first generic parameter corresponds to the names of terminal tokens,
* while the second one corresponds to the names of keyword tokens.
* Both parameters are optional and can be imported from `./generated/ast.js`.
*
* Inspired by https://github.com/chevrotain/chevrotain/blob/master/examples/lexer/python_indentation/python_indentation.js
*/
export declare class IndentationAwareTokenBuilder<Terminals extends string = string, KeywordName extends string = string> extends DefaultTokenBuilder {
/**
* The stack stores all the previously matched indentation levels to understand how deeply the next tokens are nested.
* The stack is valid for lexing
*/
protected indentationStack: number[];
readonly options: IndentationTokenBuilderOptions<Terminals, KeywordName>;
/**
* The token type to be used for indentation tokens
*/
readonly indentTokenType: TokenType;
/**
* The token type to be used for dedentation tokens
*/
readonly dedentTokenType: TokenType;
/**
* A regular expression to match a series of tabs and/or spaces.
* Override this to customize what the indentation is allowed to consist of.
*/
protected whitespaceRegExp: RegExp;
constructor(options?: Partial<IndentationTokenBuilderOptions<NoInfer<Terminals>, NoInfer<KeywordName>>>);
buildTokens(grammar: Grammar, options?: TokenBuilderOptions | undefined): TokenVocabulary;
flushLexingReport(text: string): IndentationLexingReport;
/**
* Helper function to check if the current position is the start of a new line.
*
* @param text The full input string.
* @param offset The current position at which to check
* @returns Whether the current position is the start of a new line
*/
protected isStartOfLine(text: string, offset: number): boolean;
/**
* A helper function used in matching both indents and dedents.
*
* @param text The full input string.
* @param offset The current position at which to attempt a match
* @param tokens Previously scanned tokens
* @param groups Token Groups
* @returns The current and previous indentation levels and the matched whitespace
*/
protected matchWhitespace(text: string, offset: number, tokens: IToken[], groups: Record<string, IToken[]>): {
currIndentLevel: number;
prevIndentLevel: number;
match: RegExpExecArray | null;
};
/**
* Helper function to create an instance of an indentation token.
*
* @param tokenType Indent or dedent token type
* @param text Full input string, used to calculate the line number
* @param image The original image of the token (tabs or spaces)
* @param offset Current position in the input string
* @returns The indentation token instance
*/
protected createIndentationTokenInstance(tokenType: TokenType, text: string, image: string, offset: number): IToken;
/**
* Helper function to get the line number at a given offset.
*
* @param text Full input string, used to calculate the line number
* @param offset Current position in the input string
* @returns The line number at the given offset
*/
protected getLineNumber(text: string, offset: number): number;
/**
* A custom pattern for matching indents
*
* @param text The full input string.
* @param offset The offset at which to attempt a match
* @param tokens Previously scanned tokens
* @param groups Token Groups
*/
protected indentMatcher(text: string, offset: number, tokens: IToken[], groups: Record<string, IToken[]>): ReturnType<CustomPatternMatcherFunc>;
/**
* A custom pattern for matching dedents
*
* @param text The full input string.
* @param offset The offset at which to attempt a match
* @param tokens Previously scanned tokens
* @param groups Token Groups
*/
protected dedentMatcher(text: string, offset: number, tokens: IToken[], groups: Record<string, IToken[]>): ReturnType<CustomPatternMatcherFunc>;
protected buildTerminalToken(terminal: TerminalRule): TokenType;
/**
* Resets the indentation stack between different runs of the lexer
*
* @param text Full text that was tokenized
* @returns Remaining dedent tokens to match all previous indents at the end of the file
*/
flushRemainingDedents(text: string): IToken[];
}
/**
* A lexer that is aware of indentation in the input text.
* The only purpose of this lexer is to reset the internal state of the {@link IndentationAwareTokenBuilder}
* between the tokenization of different text inputs.
*
* In your module, you can override the default lexer with this one as such:
* ```ts
* parser: {
* TokenBuilder: () => new IndentationAwareTokenBuilder(),
* Lexer: (services) => new IndentationAwareLexer(services),
* }
* ```
*/
export declare class IndentationAwareLexer extends DefaultLexer {
protected readonly indentationTokenBuilder: IndentationAwareTokenBuilder;
constructor(services: LangiumCoreServices);
tokenize(text: string, options?: TokenizeOptions): LexerResult;
}
export {};
//# sourceMappingURL=indentation-aware.d.ts.map

17
frontend/node_modules/langium/lib/parser/index.d.ts generated vendored Normal file
View File

@@ -0,0 +1,17 @@
/******************************************************************************
* 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.
******************************************************************************/
export * from './async-parser.js';
export * from './completion-parser-builder.js';
export * from './cst-node-builder.js';
export * from './indentation-aware.js';
export * from './langium-parser-builder.js';
export * from './langium-parser.js';
export * from './lexer.js';
export * from './parser-builder-base.js';
export * from './parser-config.js';
export * from './token-builder.js';
export * from './value-converter.js';
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"parser-builder-base.d.ts","sourceRoot":"","sources":["../../src/parser/parser-builder-base.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAqB,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACzE,OAAO,KAAK,EAAgF,OAAO,EAAkF,MAAM,+BAA+B,CAAC;AAC3N,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AA+BtD,wBAAgB,YAAY,CAAC,CAAC,SAAS,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,mBAAmB,GAAG,CAAC,CAQ9G"}

View File

@@ -0,0 +1,474 @@
/******************************************************************************
* 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 { EMPTY_ALT, EOF } from 'chevrotain';
import { isAction, isAlternatives, isEndOfFile, isAssignment, isConjunction, isCrossReference, isDisjunction, isGroup, isKeyword, isNegation, isParameterReference, isParserRule, isRuleCall, isTerminalRule, isUnorderedGroup, isBooleanLiteral, isInfixRule, isAbstractParserRule } from '../languages/generated/ast.js';
import { assertUnreachable, ErrorWithLocation } from '../utils/errors.js';
import { stream } from '../utils/stream.js';
import { findNameAssignment, getAllReachableRules, getTypeName } from '../utils/grammar-utils.js';
export function createParser(grammar, parser, tokens) {
const parserContext = {
parser,
tokens,
ruleNames: new Map()
};
buildRules(parserContext, grammar);
return parser;
}
function buildRules(parserContext, grammar) {
const reachable = getAllReachableRules(grammar, false);
const parserRules = stream(grammar.rules).filter(isParserRule).filter(rule => reachable.has(rule));
for (const rule of parserRules) {
const ctx = {
...parserContext,
consume: 1,
optional: 1,
subrule: 1,
many: 1,
or: 1
};
parserContext.parser.rule(rule, buildElement(ctx, rule.definition));
}
const infixRules = stream(grammar.rules).filter(isInfixRule).filter(rule => reachable.has(rule));
for (const rule of infixRules) {
parserContext.parser.rule(rule, buildInfixRule(parserContext, rule));
}
}
function buildInfixRule(ctx, rule) {
const expressionRule = rule.call.rule.ref;
if (!expressionRule) {
throw new Error('Could not resolve reference to infix operator rule: ' + rule.call.rule.$refText);
}
if (isTerminalRule(expressionRule)) {
throw new Error('Cannot use terminal rule in infix expression');
}
// We need to construct a bunch of synthetic grammar AST nodes here
// This ensures that the CST and completion engine get populated as expected
const allKeywords = rule.operators.precedences.flatMap(e => e.operators);
// The outer group represents the first expression call and the whole (optional) loop
const outerGroup = {
$type: 'Group',
elements: []
};
const part1Assignment = {
$container: outerGroup,
$type: 'Assignment',
feature: 'parts',
operator: '+=',
terminal: rule.call
};
// The inner group represents the loop that contains the operator and expression call
// It can be infinitely repeated
const innerGroup = {
$container: outerGroup,
$type: 'Group',
elements: [],
cardinality: '*'
};
outerGroup.elements.push(part1Assignment, innerGroup);
// Store all operator keywords in one alternative/assignment
const alternatives = {
$type: 'Alternatives',
elements: allKeywords
};
const operatorAssignment = {
$container: innerGroup,
$type: 'Assignment',
feature: 'operators',
operator: '+=',
terminal: alternatives
};
// We need a second assignment of the called expression here
const part2Assignment = {
...part1Assignment,
$container: innerGroup
};
innerGroup.elements.push(operatorAssignment, part2Assignment);
const tokens = allKeywords.map(e => ctx.tokens[e.value]);
const orAlts = tokens.map((token, index) => ({
ALT: () => ctx.parser.consume(index, token, operatorAssignment)
}));
let subrule;
return (args) => {
subrule ?? (subrule = getRule(ctx, expressionRule));
ctx.parser.subrule(0, subrule, false, part1Assignment, args);
ctx.parser.many(0, {
DEF: () => {
ctx.parser.alternatives(0, orAlts);
ctx.parser.subrule(1, subrule, false, part2Assignment, args);
}
});
};
}
function buildElement(ctx, element, ignoreGuard = false) {
let method;
if (isKeyword(element)) {
method = buildKeyword(ctx, element);
}
else if (isAction(element)) {
method = buildAction(ctx, element);
}
else if (isAssignment(element)) {
method = buildElement(ctx, element.terminal);
}
else if (isCrossReference(element)) {
method = buildCrossReference(ctx, element);
}
else if (isRuleCall(element)) {
method = buildRuleCall(ctx, element);
}
else if (isAlternatives(element)) {
method = buildAlternatives(ctx, element);
}
else if (isUnorderedGroup(element)) {
method = buildUnorderedGroup(ctx, element);
}
else if (isGroup(element)) {
method = buildGroup(ctx, element);
}
else if (isEndOfFile(element)) {
const idx = ctx.consume++;
method = () => ctx.parser.consume(idx, EOF, element);
}
else {
throw new ErrorWithLocation(element.$cstNode, `Unexpected element type: ${element.$type}`);
}
return wrap(ctx, ignoreGuard ? undefined : getGuardCondition(element), method, element.cardinality);
}
function buildAction(ctx, action) {
const actionType = getTypeName(action);
return () => ctx.parser.action(actionType, action);
}
function buildRuleCall(ctx, ruleCall) {
const rule = ruleCall.rule.ref;
if (isAbstractParserRule(rule)) {
const idx = ctx.subrule++;
const fragment = isParserRule(rule) && rule.fragment;
const predicate = ruleCall.arguments.length > 0 ? buildRuleCallPredicate(rule, ruleCall.arguments) : () => ({});
let subrule;
return (args) => {
subrule ?? (subrule = getRule(ctx, rule));
ctx.parser.subrule(idx, subrule, fragment, ruleCall, predicate(args));
};
}
else if (isTerminalRule(rule)) {
const idx = ctx.consume++;
const method = getToken(ctx, rule.name);
return () => ctx.parser.consume(idx, method, ruleCall);
}
else if (!rule) {
throw new ErrorWithLocation(ruleCall.$cstNode, `Undefined rule: ${ruleCall.rule.$refText}`);
}
else {
assertUnreachable(rule);
}
}
function buildRuleCallPredicate(rule, namedArgs) {
const hasNamedArguments = namedArgs.some(arg => arg.calledByName);
if (hasNamedArguments) {
const namedPredicates = namedArgs.map(arg => ({
parameterName: arg.parameter?.ref?.name,
predicate: buildPredicate(arg.value)
}));
return (args) => {
const ruleArgs = {};
for (const { parameterName, predicate } of namedPredicates) {
if (parameterName) {
ruleArgs[parameterName] = predicate(args);
}
}
return ruleArgs;
};
}
else {
const predicates = namedArgs.map(arg => buildPredicate(arg.value));
return (args) => {
const ruleArgs = {};
for (let i = 0; i < predicates.length; i++) {
if (i < rule.parameters.length) {
const parameterName = rule.parameters[i].name;
const predicate = predicates[i];
ruleArgs[parameterName] = predicate(args);
}
}
return ruleArgs;
};
}
}
function buildPredicate(condition) {
if (isDisjunction(condition)) {
const left = buildPredicate(condition.left);
const right = buildPredicate(condition.right);
return (args) => (left(args) || right(args));
}
else if (isConjunction(condition)) {
const left = buildPredicate(condition.left);
const right = buildPredicate(condition.right);
return (args) => (left(args) && right(args));
}
else if (isNegation(condition)) {
const value = buildPredicate(condition.value);
return (args) => !value(args);
}
else if (isParameterReference(condition)) {
const name = condition.parameter.ref.name;
return (args) => args !== undefined && args[name] === true;
}
else if (isBooleanLiteral(condition)) {
const value = Boolean(condition.true);
return () => value;
}
assertUnreachable(condition);
}
function buildAlternatives(ctx, alternatives) {
if (alternatives.elements.length === 1) {
return buildElement(ctx, alternatives.elements[0]);
}
else {
const methods = [];
for (const element of alternatives.elements) {
const predicatedMethod = {
// Since we handle the guard condition in the alternative already
// We can ignore the group guard condition inside
ALT: buildElement(ctx, element, true)
};
const guard = getGuardCondition(element);
if (guard) {
predicatedMethod.GATE = buildPredicate(guard);
}
methods.push(predicatedMethod);
}
const idx = ctx.or++;
return (args) => ctx.parser.alternatives(idx, methods.map(method => {
const alt = {
ALT: () => method.ALT(args)
};
const gate = method.GATE;
if (gate) {
alt.GATE = () => gate(args);
}
return alt;
}));
}
}
function buildUnorderedGroup(ctx, group) {
if (group.elements.length === 1) {
return buildElement(ctx, group.elements[0]);
}
const methods = [];
for (const element of group.elements) {
const predicatedMethod = {
// Since we handle the guard condition in the alternative already
// We can ignore the group guard condition inside
ALT: buildElement(ctx, element, true)
};
const guard = getGuardCondition(element);
if (guard) {
predicatedMethod.GATE = buildPredicate(guard);
}
methods.push(predicatedMethod);
}
const orIdx = ctx.or++;
const idFunc = (groupIdx, lParser) => {
const stackId = lParser.getRuleStack().join('-');
return `uGroup_${groupIdx}_${stackId}`;
};
const alternatives = (args) => ctx.parser.alternatives(orIdx, methods.map((method, idx) => {
const alt = { ALT: () => true };
const parser = ctx.parser;
alt.ALT = () => {
method.ALT(args);
if (!parser.isRecording()) {
const key = idFunc(orIdx, parser);
if (!parser.unorderedGroups.get(key)) {
// init after clear state
parser.unorderedGroups.set(key, []);
}
const groupState = parser.unorderedGroups.get(key);
if (typeof groupState?.[idx] === 'undefined') {
// Not accessed yet
groupState[idx] = true;
}
}
};
const gate = method.GATE;
if (gate) {
alt.GATE = () => gate(args);
}
else {
alt.GATE = () => {
const trackedAlternatives = parser.unorderedGroups.get(idFunc(orIdx, parser));
const allow = !trackedAlternatives?.[idx];
return allow;
};
}
return alt;
}));
const wrapped = wrap(ctx, getGuardCondition(group), alternatives, '*');
return (args) => {
wrapped(args);
if (!ctx.parser.isRecording()) {
ctx.parser.unorderedGroups.delete(idFunc(orIdx, ctx.parser));
}
};
}
function buildGroup(ctx, group) {
const methods = group.elements.map(e => buildElement(ctx, e));
return (args) => methods.forEach(method => method(args));
}
function getGuardCondition(element) {
if (isGroup(element)) {
return element.guardCondition;
}
return undefined;
}
function buildCrossReference(ctx, crossRef, terminal = crossRef.terminal) {
if (!terminal) {
if (!crossRef.type.ref) {
throw new Error('Could not resolve reference to type: ' + crossRef.type.$refText);
}
const assignment = findNameAssignment(crossRef.type.ref);
const assignTerminal = assignment?.terminal;
if (!assignTerminal) {
throw new Error('Could not find name assignment for type: ' + getTypeName(crossRef.type.ref));
}
return buildCrossReference(ctx, crossRef, assignTerminal);
}
else if (isRuleCall(terminal) && isParserRule(terminal.rule.ref)) {
// The terminal is a data type rule here. Everything else will result in a validation error.
const rule = terminal.rule.ref;
const idx = ctx.subrule++;
let subrule;
return (args) => {
subrule ?? (subrule = getRule(ctx, rule));
ctx.parser.subrule(idx, subrule, false, crossRef, args);
};
}
else if (isRuleCall(terminal) && isTerminalRule(terminal.rule.ref)) {
const idx = ctx.consume++;
const terminalRule = getToken(ctx, terminal.rule.ref.name);
return () => ctx.parser.consume(idx, terminalRule, crossRef);
}
else if (isKeyword(terminal)) {
const idx = ctx.consume++;
const keyword = getToken(ctx, terminal.value);
return () => ctx.parser.consume(idx, keyword, crossRef);
}
else {
throw new Error('Could not build cross reference parser');
}
}
function buildKeyword(ctx, keyword) {
const idx = ctx.consume++;
const token = ctx.tokens[keyword.value];
if (!token) {
throw new Error('Could not find token for keyword: ' + keyword.value);
}
return () => ctx.parser.consume(idx, token, keyword);
}
function wrap(ctx, guard, method, cardinality) {
const gate = guard && buildPredicate(guard);
if (!cardinality) {
if (gate) {
const idx = ctx.or++;
return (args) => ctx.parser.alternatives(idx, [
{
ALT: () => method(args),
GATE: () => gate(args)
},
{
ALT: EMPTY_ALT(),
GATE: () => !gate(args)
}
]);
}
else {
return method;
}
}
if (cardinality === '*') {
const idx = ctx.many++;
return (args) => ctx.parser.many(idx, {
DEF: () => method(args),
GATE: gate ? () => gate(args) : undefined
});
}
else if (cardinality === '+') {
const idx = ctx.many++;
if (gate) {
const orIdx = ctx.or++;
// In the case of a guard condition for the `+` group
// We combine it with an empty alternative
// If the condition returns true, it needs to parse at least a single iteration
// If its false, it is not allowed to parse anything
return (args) => ctx.parser.alternatives(orIdx, [
{
ALT: () => ctx.parser.atLeastOne(idx, {
DEF: () => method(args)
}),
GATE: () => gate(args)
},
{
ALT: EMPTY_ALT(),
GATE: () => !gate(args)
}
]);
}
else {
return (args) => ctx.parser.atLeastOne(idx, {
DEF: () => method(args),
});
}
}
else if (cardinality === '?') {
const idx = ctx.optional++;
return (args) => ctx.parser.optional(idx, {
DEF: () => method(args),
GATE: gate ? () => gate(args) : undefined
});
}
else {
assertUnreachable(cardinality);
}
}
function getRule(ctx, element) {
const name = getRuleName(ctx, element);
const rule = ctx.parser.getRule(name);
if (!rule)
throw new Error(`Rule "${name}" not found."`);
return rule;
}
function getRuleName(ctx, element) {
if (isAbstractParserRule(element)) {
return element.name;
}
else if (ctx.ruleNames.has(element)) {
return ctx.ruleNames.get(element);
}
else {
let item = element;
let parent = item.$container;
let ruleName = element.$type;
while (!isParserRule(parent)) {
if (isGroup(parent) || isAlternatives(parent) || isUnorderedGroup(parent)) {
const index = parent.elements.indexOf(item);
ruleName = index.toString() + ':' + ruleName;
}
item = parent;
parent = parent.$container;
}
const rule = parent;
ruleName = rule.name + ':' + ruleName;
ctx.ruleNames.set(element, ruleName);
return ruleName;
}
}
function getToken(ctx, name) {
const token = ctx.tokens[name];
if (!token)
throw new Error(`Token "${name}" not found."`);
return token;
}
//# sourceMappingURL=parser-builder-base.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"token-builder.d.ts","sourceRoot":"","sources":["../../src/parser/token-builder.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,wBAAwB,EAAE,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AACnH,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAClG,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAQjD,MAAM,WAAW,mBAAmB;IAChC,eAAe,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED,MAAM,WAAW,YAAY;IACzB,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,eAAe,CAAC;IAC9E;;;;OAIG;IACH,iBAAiB,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAAC;CAClD;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IACzB,WAAW,EAAE,gBAAgB,EAAE,CAAC;CACnC;AAED,MAAM,MAAM,wBAAwB,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;AAE7E,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IAClD,QAAQ,CAAC,EAAE,wBAAwB,CAAC;CACvC;AAED,qBAAa,mBAAoB,YAAW,YAAY;IACpD;;OAEG;IACH,SAAS,CAAC,WAAW,EAAE,gBAAgB,EAAE,CAAM;IAE/C,WAAW,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,eAAe;IAe7E,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY;IAI7C,SAAS,CAAC,cAAc,IAAI,gBAAgB,EAAE;IAM9C,SAAS,CAAC,mBAAmB,CAAC,KAAK,EAAE,MAAM,CAAC,YAAY,CAAC,GAAG,SAAS,EAAE;IAKvE,SAAS,CAAC,kBAAkB,CAAC,QAAQ,EAAE,YAAY,GAAG,SAAS;IAiB/D,SAAS,CAAC,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IASvD,SAAS,CAAC,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,wBAAwB;IASvE,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,MAAM,CAAC,YAAY,CAAC,EAAE,cAAc,EAAE,SAAS,EAAE,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,SAAS,EAAE;IAWlI,SAAS,CAAC,iBAAiB,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,EAAE,eAAe,EAAE,OAAO,GAAG,SAAS;IAe/G,SAAS,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,eAAe,EAAE,OAAO,GAAG,YAAY;IAMvF,SAAS,CAAC,aAAa,CAAC,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,SAAS,EAAE,GAAG,SAAS,EAAE;CAStF"}

View File

@@ -0,0 +1,114 @@
/******************************************************************************
* 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 { Lexer } from 'chevrotain';
import { isAbstractParserRule, isKeyword, isTerminalRule } from '../languages/generated/ast.js';
import { streamAllContents } from '../utils/ast-utils.js';
import { getAllReachableRules, terminalRegex } from '../utils/grammar-utils.js';
import { escapeRegExp, isWhitespace, partialMatches } from '../utils/regexp-utils.js';
import { stream } from '../utils/stream.js';
export class DefaultTokenBuilder {
constructor() {
/**
* The list of diagnostics stored during the lexing process of a single text.
*/
this.diagnostics = [];
}
buildTokens(grammar, options) {
const reachableRules = stream(getAllReachableRules(grammar, false));
const terminalTokens = this.buildTerminalTokens(reachableRules);
const tokens = this.buildKeywordTokens(reachableRules, terminalTokens, options);
// Add all terminals tokens to the end in the order they were defined
// Chevrotain documentation recommends to add Whitespace-like tokens at the start
// However, assuming the lexer is able to optimize the tokens, it should not matter
tokens.push(...terminalTokens);
// We don't need to add the EOF token explicitly.
// It is automatically available at the end of the token stream.
return tokens;
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
flushLexingReport(text) {
return { diagnostics: this.popDiagnostics() };
}
popDiagnostics() {
const diagnostics = [...this.diagnostics];
this.diagnostics = [];
return diagnostics;
}
buildTerminalTokens(rules) {
return rules.filter(isTerminalRule).filter(e => !e.fragment)
.map(terminal => this.buildTerminalToken(terminal)).toArray();
}
buildTerminalToken(terminal) {
const regex = terminalRegex(terminal);
const pattern = this.requiresCustomPattern(regex) ? this.regexPatternFunction(regex) : regex;
const tokenType = {
name: terminal.name,
PATTERN: pattern,
};
if (typeof pattern === 'function') {
tokenType.LINE_BREAKS = true;
}
if (terminal.hidden) {
// Only skip tokens that are able to accept whitespace
tokenType.GROUP = isWhitespace(regex) ? Lexer.SKIPPED : 'hidden';
}
return tokenType;
}
requiresCustomPattern(regex) {
if (regex.flags.includes('u') || regex.flags.includes('s')) {
// Unicode and dotall regexes are not supported by Chevrotain.
return true;
}
else {
return false;
}
}
regexPatternFunction(regex) {
const stickyRegex = new RegExp(regex, regex.flags + 'y');
return (text, offset) => {
stickyRegex.lastIndex = offset;
const execResult = stickyRegex.exec(text);
return execResult;
};
}
buildKeywordTokens(rules, terminalTokens, options) {
return rules
// We filter by parser rules, since keywords in terminal rules get transformed into regex and are not actual tokens
.filter(isAbstractParserRule)
.flatMap(rule => streamAllContents(rule).filter(isKeyword))
.distinct(e => e.value).toArray()
// Sort keywords by descending length
.sort((a, b) => b.value.length - a.value.length)
.map(keyword => this.buildKeywordToken(keyword, terminalTokens, Boolean(options?.caseInsensitive)));
}
buildKeywordToken(keyword, terminalTokens, caseInsensitive) {
const keywordPattern = this.buildKeywordPattern(keyword, caseInsensitive);
const tokenType = {
name: keyword.value,
PATTERN: keywordPattern,
LONGER_ALT: this.findLongerAlt(keyword, terminalTokens)
};
if (typeof keywordPattern === 'function') {
tokenType.LINE_BREAKS = true;
}
return tokenType;
}
buildKeywordPattern(keyword, caseInsensitive) {
return caseInsensitive ?
new RegExp(escapeRegExp(keyword.value), 'i') :
keyword.value;
}
findLongerAlt(keyword, terminalTokens) {
return terminalTokens.reduce((longerAlts, token) => {
const pattern = token?.PATTERN;
if (pattern?.source && partialMatches('^' + pattern.source + '$', keyword.value)) {
longerAlts.push(token);
}
return longerAlts;
}, []);
}
}
//# sourceMappingURL=token-builder.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"token-builder.js","sourceRoot":"","sources":["../../src/parser/token-builder.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,12 @@
/******************************************************************************
* 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.
******************************************************************************/
export * from './linker.js';
export * from './name-provider.js';
export * from './references.js';
export * from './scope.js';
export * from './scope-computation.js';
export * from './scope-provider.js';
//# sourceMappingURL=index.d.ts.map

12
frontend/node_modules/langium/lib/references/index.js generated vendored Normal file
View File

@@ -0,0 +1,12 @@
/******************************************************************************
* 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.
******************************************************************************/
export * from './linker.js';
export * from './name-provider.js';
export * from './references.js';
export * from './scope.js';
export * from './scope-computation.js';
export * from './scope-provider.js';
//# sourceMappingURL=index.js.map

View File

@@ -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 { findNodeForProperty } from '../utils/grammar-utils.js';
export function isNamed(node) {
return typeof node.name === 'string';
}
export class DefaultNameProvider {
getName(node) {
if (isNamed(node)) {
return node.name;
}
return undefined;
}
getNameNode(node) {
return findNodeForProperty(node.$cstNode, 'name');
}
}
//# sourceMappingURL=name-provider.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"scope-computation.js","sourceRoot":"","sources":["../../src/references/scope-computation.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAIhF,OAAO,EAAE,iBAAiB,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAC1E,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAC7D,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AA2C9D;;;;;;;;;;;GAWG;AACH,MAAM,OAAO,uBAAuB;IAKhC,YAAY,QAA6B;QACrC,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,UAAU,CAAC,YAAY,CAAC;QACrD,IAAI,CAAC,YAAY,GAAG,QAAQ,CAAC,SAAS,CAAC,0BAA0B,CAAC;IACtE,CAAC;IAED,KAAK,CAAC,sBAAsB,CAAC,QAAyB,EAAE,WAAW,GAAG,iBAAiB,CAAC,IAAI;QACxF,OAAO,IAAI,CAAC,6BAA6B,CAAC,QAAQ,CAAC,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,WAAW,CAAC,CAAC;IAC5G,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,6BAA6B,CAAC,UAAmB,EAAE,QAAkC,EAAE,WAAiD,cAAc,EAAE,cAAiC,iBAAiB,CAAC,IAAI;QACjN,MAAM,OAAO,GAAyB,EAAE,CAAC;QAEzC,IAAI,CAAC,iBAAiB,CAAC,UAAU,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QACtD,KAAK,MAAM,IAAI,IAAI,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;YACtC,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;YACrC,IAAI,CAAC,iBAAiB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;QACpD,CAAC;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;IAED;;;OAGG;IACO,iBAAiB,CAAC,IAAa,EAAE,OAA6B,EAAE,QAAyB;QAC/F,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QAC7C,IAAI,IAAI,EAAE,CAAC;YACP,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC5E,CAAC;IACL,CAAC;IAED,kCAAkC;IAElC,KAAK,CAAC,mBAAmB,CAAC,QAAyB,EAAE,WAAW,GAAG,iBAAiB,CAAC,IAAI;QACrF,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC;QAC5C,MAAM,OAAO,GAAG,IAAI,QAAQ,EAA+B,CAAC;QAC5D,wFAAwF;QACxF,KAAK,MAAM,IAAI,IAAI,iBAAiB,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC7C,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;YACrC,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,OAAO,CAAC;IACnB,CAAC;IAED;;;;OAIG;IACO,cAAc,CAAC,IAAa,EAAE,QAAyB,EAAE,OAA8C;QAC7G,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC;QAClC,IAAI,SAAS,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAC7C,IAAI,IAAI,EAAE,CAAC;gBACP,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC;YACtF,CAAC;QACL,CAAC;IACL,CAAC;CAEJ"}

View File

@@ -0,0 +1,64 @@
/******************************************************************************
* 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 { MultiMapScope, StreamScope } from './scope.js';
import { getDocument } from '../utils/ast-utils.js';
import { stream } from '../utils/stream.js';
import { WorkspaceCache } from '../utils/caching.js';
export class DefaultScopeProvider {
constructor(services) {
this.reflection = services.shared.AstReflection;
this.nameProvider = services.references.NameProvider;
this.descriptions = services.workspace.AstNodeDescriptionProvider;
this.indexManager = services.shared.workspace.IndexManager;
this.globalScopeCache = new WorkspaceCache(services.shared);
}
getScope(context) {
const scopes = [];
const referenceType = this.reflection.getReferenceType(context);
const localSymbols = getDocument(context.container).localSymbols;
if (localSymbols) {
let currentNode = context.container;
do {
if (localSymbols.has(currentNode)) {
scopes.push(localSymbols.getStream(currentNode).filter(desc => this.reflection.isSubtype(desc.type, referenceType)));
}
currentNode = currentNode.$container;
} while (currentNode);
}
let result = this.getGlobalScope(referenceType, context);
for (let i = scopes.length - 1; i >= 0; i--) {
result = this.createScope(scopes[i], result);
}
return result;
}
/**
* Create a scope for the given collection of AST node descriptions.
*/
createScope(elements, outerScope, options) {
return new StreamScope(stream(elements), outerScope, options);
}
/**
* Create a scope for the given collection of AST nodes, which need to be transformed into respective
* descriptions first. This is done using the `NameProvider` and `AstNodeDescriptionProvider` services.
*/
createScopeForNodes(elements, outerScope, options) {
const s = stream(elements).map(e => {
const name = this.nameProvider.getName(e);
if (name) {
return this.descriptions.createDescription(e, name);
}
return undefined;
}).nonNullable();
return new StreamScope(s, outerScope, options);
}
/**
* Create a global scope filtered for the given reference type.
*/
getGlobalScope(referenceType, _context) {
return this.globalScopeCache.get(referenceType, () => new MultiMapScope(this.indexManager.allElements(referenceType)));
}
}
//# sourceMappingURL=scope-provider.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"scope.d.ts","sourceRoot":"","sources":["../../src/references/scope.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAGjD;;GAEG;AACH,MAAM,WAAW,KAAK;IAElB;;;;;;OAMG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS,CAAC;IAEzD;;;;OAIG;IACH,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAEtD;;;OAGG;IACH,cAAc,IAAI,MAAM,CAAC,kBAAkB,CAAC,CAAC;CAEhD;AAED,MAAM,WAAW,YAAY;IACzB;;;OAGG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B;AAED;;;;GAIG;AACH,qBAAa,WAAY,YAAW,KAAK;IACrC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAC9C,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC;IAC5B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;gBAEvB,QAAQ,EAAE,MAAM,CAAC,kBAAkB,CAAC,EAAE,UAAU,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,YAAY;IAO5F,cAAc,IAAI,MAAM,CAAC,kBAAkB,CAAC;IAQ5C,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAcxD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,kBAAkB,CAAC;CAWxD;AAED,qBAAa,QAAS,YAAW,KAAK;IAClC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACnD,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC;IAC5B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;gBAEvB,QAAQ,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,UAAU,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,YAAY;IAa9F,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAYxD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,kBAAkB,CAAC;IAWrD,cAAc,IAAI,MAAM,CAAC,kBAAkB,CAAC;CAQ/C;AAED,qBAAa,aAAc,YAAW,KAAK;IACvC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAC;IACxD,QAAQ,CAAC,UAAU,CAAC,EAAE,KAAK,CAAC;IAC5B,QAAQ,CAAC,eAAe,EAAE,OAAO,CAAC;IAClC,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;gBAEvB,QAAQ,EAAE,QAAQ,CAAC,kBAAkB,CAAC,EAAE,UAAU,CAAC,EAAE,KAAK,EAAE,OAAO,CAAC,EAAE,YAAY;IAa9F,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAYxD,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAAC,kBAAkB,CAAC;IAUrD,cAAc,IAAI,MAAM,CAAC,kBAAkB,CAAC;CAQ/C;AAED,eAAO,MAAM,WAAW,EAAE,KAUzB,CAAC"}

150
frontend/node_modules/langium/lib/references/scope.js generated vendored Normal file
View File

@@ -0,0 +1,150 @@
/******************************************************************************
* 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 { MultiMap } from '../utils/collections.js';
import { EMPTY_STREAM, stream } from '../utils/stream.js';
/**
* The default scope implementation is based on a `Stream`. It has an optional _outer scope_ describing
* the next level of elements, which are queried when a target element is not found in the stream provided
* to this scope.
*/
export class StreamScope {
constructor(elements, outerScope, options) {
this.elements = elements;
this.outerScope = outerScope;
this.caseInsensitive = options?.caseInsensitive ?? false;
this.concatOuterScope = options?.concatOuterScope ?? true;
}
getAllElements() {
if (this.outerScope) {
return this.elements.concat(this.outerScope.getAllElements());
}
else {
return this.elements;
}
}
getElement(name) {
const lowerCaseName = this.caseInsensitive ? name.toLowerCase() : name;
const local = this.caseInsensitive
? this.elements.find(e => e.name.toLowerCase() === lowerCaseName)
: this.elements.find(e => e.name === name);
if (local) {
return local;
}
if (this.outerScope) {
return this.outerScope.getElement(name);
}
return undefined;
}
getElements(name) {
const lowerCaseName = this.caseInsensitive ? name.toLowerCase() : name;
const local = this.caseInsensitive
? this.elements.filter(e => e.name.toLowerCase() === lowerCaseName)
: this.elements.filter(e => e.name === name);
if ((this.concatOuterScope || local.isEmpty()) && this.outerScope) {
return local.concat(this.outerScope.getElements(name));
}
else {
return local;
}
}
}
export class MapScope {
constructor(elements, outerScope, options) {
this.elements = new Map();
this.caseInsensitive = options?.caseInsensitive ?? false;
this.concatOuterScope = options?.concatOuterScope ?? true;
for (const element of elements) {
const name = this.caseInsensitive
? element.name.toLowerCase()
: element.name;
this.elements.set(name, element);
}
this.outerScope = outerScope;
}
getElement(name) {
const localName = this.caseInsensitive ? name.toLowerCase() : name;
const local = this.elements.get(localName);
if (local) {
return local;
}
if (this.outerScope) {
return this.outerScope.getElement(name);
}
return undefined;
}
getElements(name) {
const localName = this.caseInsensitive ? name.toLowerCase() : name;
const local = this.elements.get(localName);
const arr = local ? [local] : [];
if ((this.concatOuterScope || arr.length > 0) && this.outerScope) {
return stream(arr).concat(this.outerScope.getElements(name));
}
else {
return stream(arr);
}
}
getAllElements() {
let elementStream = stream(this.elements.values());
if (this.outerScope) {
elementStream = elementStream.concat(this.outerScope.getAllElements());
}
return elementStream;
}
}
export class MultiMapScope {
constructor(elements, outerScope, options) {
this.elements = new MultiMap();
this.caseInsensitive = options?.caseInsensitive ?? false;
this.concatOuterScope = options?.concatOuterScope ?? true;
for (const element of elements) {
const name = this.caseInsensitive
? element.name.toLowerCase()
: element.name;
this.elements.add(name, element);
}
this.outerScope = outerScope;
}
getElement(name) {
const localName = this.caseInsensitive ? name.toLowerCase() : name;
const local = this.elements.get(localName)[0];
if (local) {
return local;
}
if (this.outerScope) {
return this.outerScope.getElement(name);
}
return undefined;
}
getElements(name) {
const localName = this.caseInsensitive ? name.toLowerCase() : name;
const local = this.elements.get(localName);
if ((this.concatOuterScope || local.length === 0) && this.outerScope) {
return stream(local).concat(this.outerScope.getElements(name));
}
else {
return stream(local);
}
}
getAllElements() {
let elementStream = stream(this.elements.values());
if (this.outerScope) {
elementStream = elementStream.concat(this.outerScope.getAllElements());
}
return elementStream;
}
}
export const EMPTY_SCOPE = {
getElement() {
return undefined;
},
getElements() {
return EMPTY_STREAM;
},
getAllElements() {
return EMPTY_STREAM;
}
};
//# sourceMappingURL=scope.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"hydrator.d.ts","sourceRoot":"","sources":["../../src/serializer/hydrator.ts"],"names":[],"mappings":"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"}

View File

@@ -0,0 +1,8 @@
/******************************************************************************
* 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.
******************************************************************************/
export * from './hydrator.js';
export * from './json-serializer.js';
//# sourceMappingURL=index.d.ts.map

View File

@@ -0,0 +1,266 @@
/******************************************************************************
* 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 { URI } from 'vscode-uri';
import { isAstNode, isMultiReference, isReference } from '../syntax-tree.js';
import { getDocument } from '../utils/ast-utils.js';
import { findNodesForProperty } from '../utils/grammar-utils.js';
export function isAstNodeWithComment(node) {
return typeof node.$comment === 'string';
}
function isIntermediateReference(obj) {
return typeof obj === 'object' && !!obj && ('$ref' in obj || '$error' in obj);
}
export class DefaultJsonSerializer {
constructor(services) {
/** The set of AstNode properties to be ignored by the serializer. */
this.ignoreProperties = new Set(['$container', '$containerProperty', '$containerIndex', '$document', '$cstNode']);
this.langiumDocuments = services.shared.workspace.LangiumDocuments;
this.astNodeLocator = services.workspace.AstNodeLocator;
this.nameProvider = services.references.NameProvider;
this.commentProvider = services.documentation.CommentProvider;
}
serialize(node, options) {
const serializeOptions = options ?? {};
const specificReplacer = options?.replacer;
const defaultReplacer = (key, value) => this.replacer(key, value, serializeOptions);
const replacer = specificReplacer ? (key, value) => specificReplacer(key, value, defaultReplacer) : defaultReplacer;
try {
this.currentDocument = getDocument(node);
return JSON.stringify(node, replacer, options?.space);
}
finally {
this.currentDocument = undefined;
}
}
deserialize(content, options) {
const deserializeOptions = options ?? {};
const root = JSON.parse(content);
this.linkNode(root, root, deserializeOptions);
return root;
}
replacer(key, value, { refText, sourceText, textRegions, comments, uriConverter }) {
if (this.ignoreProperties.has(key)) {
return undefined;
}
else if (isReference(value)) {
const refValue = value.ref;
const $refText = refText ? value.$refText : undefined;
if (refValue) {
const targetDocument = getDocument(refValue);
let targetUri = '';
if (this.currentDocument && this.currentDocument !== targetDocument) {
if (uriConverter) {
targetUri = uriConverter(targetDocument.uri, refValue);
}
else {
targetUri = targetDocument.uri.toString();
}
}
const targetPath = this.astNodeLocator.getAstNodePath(refValue);
return {
$ref: `${targetUri}#${targetPath}`,
$refText
};
}
else {
return {
$error: value.error?.message ?? 'Could not resolve reference',
$refText
};
}
}
else if (isMultiReference(value)) {
const $refText = refText ? value.$refText : undefined;
const $refs = [];
for (const item of value.items) {
const refValue = item.ref;
const targetDocument = getDocument(item.ref);
let targetUri = '';
if (this.currentDocument && this.currentDocument !== targetDocument) {
if (uriConverter) {
targetUri = uriConverter(targetDocument.uri, refValue);
}
else {
targetUri = targetDocument.uri.toString();
}
}
const targetPath = this.astNodeLocator.getAstNodePath(refValue);
$refs.push(`${targetUri}#${targetPath}`);
}
return {
$refs,
$refText
};
}
else if (isAstNode(value)) {
let astNode = undefined;
if (textRegions) {
astNode = this.addAstNodeRegionWithAssignmentsTo({ ...value });
if ((!key || value.$document) && astNode?.$textRegion) {
// The document URI is added to the root node of the resulting JSON tree
astNode.$textRegion.documentURI = this.currentDocument?.uri.toString();
}
}
if (sourceText && !key) {
astNode ?? (astNode = { ...value });
astNode.$sourceText = value.$cstNode?.text;
}
if (comments) {
astNode ?? (astNode = { ...value });
const comment = this.commentProvider.getComment(value);
if (comment) {
astNode.$comment = comment.replace(/\r/g, '');
}
}
return astNode ?? value;
}
else {
return value;
}
}
addAstNodeRegionWithAssignmentsTo(node) {
const createDocumentSegment = cstNode => ({
offset: cstNode.offset,
end: cstNode.end,
length: cstNode.length,
range: cstNode.range,
});
if (node.$cstNode) {
const textRegion = node.$textRegion = createDocumentSegment(node.$cstNode);
const assignments = textRegion.assignments = {};
Object.keys(node).filter(key => !key.startsWith('$')).forEach(key => {
const propertyAssignments = findNodesForProperty(node.$cstNode, key).map(createDocumentSegment);
if (propertyAssignments.length !== 0) {
assignments[key] = propertyAssignments;
}
});
return node;
}
return undefined;
}
linkNode(node, root, options, container, containerProperty, containerIndex) {
for (const [propertyName, item] of Object.entries(node)) {
if (Array.isArray(item)) {
for (let index = 0; index < item.length; index++) {
const element = item[index];
if (isIntermediateReference(element)) {
item[index] = this.reviveReference(node, propertyName, root, element, options);
}
else if (isAstNode(element)) {
this.linkNode(element, root, options, node, propertyName, index);
}
}
}
else if (isIntermediateReference(item)) {
node[propertyName] = this.reviveReference(node, propertyName, root, item, options);
}
else if (isAstNode(item)) {
this.linkNode(item, root, options, node, propertyName);
}
}
const mutable = node;
mutable.$container = container;
mutable.$containerProperty = containerProperty;
mutable.$containerIndex = containerIndex;
}
reviveReference(container, property, root, reference, options) {
let refText = reference.$refText;
let error = reference.$error;
let ref;
if (reference.$ref) {
const refNode = this.getRefNode(root, reference.$ref, options.uriConverter);
if (isAstNode(refNode)) {
if (!refText) {
refText = this.nameProvider.getName(refNode);
}
return {
$refText: refText ?? '',
ref: refNode
};
}
else {
error = refNode;
}
}
else if (reference.$refs) {
const refs = [];
for (const refUri of reference.$refs) {
const refNode = this.getRefNode(root, refUri, options.uriConverter);
if (isAstNode(refNode)) {
refs.push({ ref: refNode });
}
}
if (refs.length === 0) {
ref = {
$refText: refText ?? '',
items: refs
};
error ?? (error = 'Could not resolve multi-reference');
}
else {
return {
$refText: refText ?? '',
items: refs
};
}
}
if (error) {
ref ?? (ref = {
$refText: refText ?? '',
ref: undefined
});
ref.error = {
info: {
container,
property,
reference: ref
},
message: error
};
return ref;
}
else {
return undefined;
}
}
getRefNode(root, uri, uriConverter) {
try {
const fragmentIndex = uri.indexOf('#');
if (fragmentIndex === 0) {
const node = this.astNodeLocator.getAstNode(root, uri.substring(1));
if (!node) {
return 'Could not resolve path: ' + uri;
}
return node;
}
if (fragmentIndex < 0) {
const documentUri = uriConverter ? uriConverter(uri) : URI.parse(uri);
const document = this.langiumDocuments.getDocument(documentUri);
if (!document) {
return 'Could not find document for URI: ' + uri;
}
return document.parseResult.value;
}
const documentUri = uriConverter ? uriConverter(uri.substring(0, fragmentIndex)) : URI.parse(uri.substring(0, fragmentIndex));
const document = this.langiumDocuments.getDocument(documentUri);
if (!document) {
return 'Could not find document for URI: ' + uri;
}
if (fragmentIndex === uri.length - 1) {
return document.parseResult.value;
}
const node = this.astNodeLocator.getAstNode(document.parseResult.value, uri.substring(fragmentIndex + 1));
if (!node) {
return 'Could not resolve URI: ' + uri;
}
return node;
}
catch (err) {
return String(err);
}
}
}
//# sourceMappingURL=json-serializer.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"service-registry.d.ts","sourceRoot":"","sources":["../src/service-registry.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,eAAe,CAAC;AACpF,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AACrE,OAAO,EAAY,KAAK,GAAG,EAAE,MAAM,sBAAsB,CAAC;AAE1D;;;GAGG;AACH,MAAM,WAAW,eAAe;IAE5B;;OAEG;IACH,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,CAAC;IAE9C;;;OAGG;IACH,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,mBAAmB,CAAC;IAE3C;;OAEG;IACH,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC;IAE/B;;OAEG;IACH,QAAQ,CAAC,GAAG,EAAE,SAAS,mBAAmB,EAAE,CAAC;CAChD;AAED;;GAEG;AACH,qBAAa,sBAAuB,YAAW,eAAe;IAE1D,SAAS,CAAC,QAAQ,CAAC,aAAa,mCAA0C;IAC1E,SAAS,CAAC,QAAQ,CAAC,gBAAgB,mCAA0C;IAC7E,SAAS,CAAC,QAAQ,CAAC,WAAW,mCAA0C;IAExE;;OAEG;IACH,SAAS,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,EAAE,mBAAmB,CAAC,GAAG,SAAS,CAEhE;IAED,SAAS,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,oBAAoB,CAAC;gBAE5C,QAAQ,CAAC,EAAE,yBAAyB;IAIhD,QAAQ,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI;IAmB7C,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,mBAAmB;IAyB1C,WAAW,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO;IAS9B,IAAI,GAAG,IAAI,SAAS,mBAAmB,EAAE,CAExC;CACJ"}

143
frontend/node_modules/langium/lib/services.d.ts generated vendored Normal file
View File

@@ -0,0 +1,143 @@
/******************************************************************************
* 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 { IParserErrorMessageProvider, ILexerErrorMessageProvider } from 'chevrotain';
import type { CommentProvider } from './documentation/comment-provider.js';
import type { DocumentationProvider } from './documentation/documentation-provider.js';
import type { Grammar } from './languages/generated/ast.js';
import type { GrammarConfig } from './languages/grammar-config.js';
import type { LanguageMetaData } from './languages/language-meta-data.js';
import type { AsyncParser } from './parser/async-parser.js';
import type { LangiumCompletionParser, LangiumParser } from './parser/langium-parser.js';
import type { Lexer } from './parser/lexer.js';
import type { IParserConfig } from './parser/parser-config.js';
import type { TokenBuilder } from './parser/token-builder.js';
import type { ValueConverter } from './parser/value-converter.js';
import type { Linker } from './references/linker.js';
import type { NameProvider } from './references/name-provider.js';
import type { References } from './references/references.js';
import type { ScopeComputation } from './references/scope-computation.js';
import type { ScopeProvider } from './references/scope-provider.js';
import type { JsonSerializer } from './serializer/json-serializer.js';
import type { ServiceRegistry } from './service-registry.js';
import type { AstReflection } from './syntax-tree.js';
import type { DocumentValidator } from './validation/document-validator.js';
import type { ValidationRegistry } from './validation/validation-registry.js';
import type { AstNodeDescriptionProvider, ReferenceDescriptionProvider } from './workspace/ast-descriptions.js';
import type { AstNodeLocator } from './workspace/ast-node-locator.js';
import type { ConfigurationProvider } from './workspace/configuration.js';
import type { DocumentBuilder } from './workspace/document-builder.js';
import type { LangiumDocumentFactory, LangiumDocuments, TextDocumentProvider } from './workspace/documents.js';
import type { FileSystemProvider } from './workspace/file-system-provider.js';
import type { IndexManager } from './workspace/index-manager.js';
import type { WorkspaceLock } from './workspace/workspace-lock.js';
import type { Hydrator } from './serializer/hydrator.js';
import type { WorkspaceManager } from './workspace/workspace-manager.js';
import type { LangiumProfiler } from './workspace/profiler.js';
/**
* The services generated by `langium-cli` for a specific language. These are derived from the
* grammar definition and the language configuration.
*/
export type LangiumGeneratedCoreServices = {
readonly Grammar: Grammar;
readonly LanguageMetaData: LanguageMetaData;
readonly parser: {
readonly ParserConfig?: IParserConfig;
};
};
/**
* Core services for a specific language of which Langium provides default implementations.
*/
export type LangiumDefaultCoreServices = {
readonly parser: {
readonly AsyncParser: AsyncParser;
readonly GrammarConfig: GrammarConfig;
readonly ValueConverter: ValueConverter;
readonly LangiumParser: LangiumParser;
readonly ParserErrorMessageProvider: IParserErrorMessageProvider;
readonly LexerErrorMessageProvider: ILexerErrorMessageProvider;
readonly CompletionParser: LangiumCompletionParser;
readonly TokenBuilder: TokenBuilder;
readonly Lexer: Lexer;
};
readonly documentation: {
readonly CommentProvider: CommentProvider;
readonly DocumentationProvider: DocumentationProvider;
};
readonly references: {
readonly Linker: Linker;
readonly NameProvider: NameProvider;
readonly References: References;
readonly ScopeProvider: ScopeProvider;
readonly ScopeComputation: ScopeComputation;
};
readonly serializer: {
readonly Hydrator: Hydrator;
readonly JsonSerializer: JsonSerializer;
};
readonly validation: {
readonly DocumentValidator: DocumentValidator;
readonly ValidationRegistry: ValidationRegistry;
};
readonly workspace: {
readonly AstNodeLocator: AstNodeLocator;
readonly AstNodeDescriptionProvider: AstNodeDescriptionProvider;
readonly ReferenceDescriptionProvider: ReferenceDescriptionProvider;
};
readonly shared: LangiumSharedCoreServices;
};
/**
* The core set of services available for a language. These are either generated by `langium-cli`
* or provided as default implementations.
*/
export type LangiumCoreServices = LangiumGeneratedCoreServices & LangiumDefaultCoreServices;
/**
* The services generated by `langium-cli` that are shared between multiple languages. These are
* derived from the grammar definition.
*/
export type LangiumGeneratedSharedCoreServices = {
readonly AstReflection: AstReflection;
};
/**
* Core services shared between multiple languages where Langium provides default implementations.
*/
export type LangiumDefaultSharedCoreServices = {
readonly ServiceRegistry: ServiceRegistry;
readonly workspace: {
readonly ConfigurationProvider: ConfigurationProvider;
readonly DocumentBuilder: DocumentBuilder;
readonly FileSystemProvider: FileSystemProvider;
readonly IndexManager: IndexManager;
readonly LangiumDocuments: LangiumDocuments;
readonly LangiumDocumentFactory: LangiumDocumentFactory;
readonly TextDocuments?: TextDocumentProvider;
readonly WorkspaceLock: WorkspaceLock;
readonly WorkspaceManager: WorkspaceManager;
};
readonly profilers: {
readonly LangiumProfiler?: LangiumProfiler;
};
};
/**
* The shared core services are a set of services that are used by every language within a Langium project (excluding LSP services)
* This is necessary to enable features like cross references across different languages.
*/
export type LangiumSharedCoreServices = LangiumDefaultSharedCoreServices & LangiumGeneratedSharedCoreServices;
/**
* A deep partial type definition for services. We look into T to see whether its type definition contains
* any methods. If it does, it's one of our services and therefore should not be partialized.
*/
export type DeepPartial<T> = T[keyof T] extends Function ? T : {
[P in keyof T]?: DeepPartial<T[P]>;
};
/**
* Language-specific core services to be partially overridden via dependency injection.
*/
export type PartialLangiumCoreServices = DeepPartial<LangiumCoreServices>;
/**
* Shared core services to be partially overridden via dependency injection.
*/
export type PartialLangiumSharedCoreServices = DeepPartial<LangiumSharedCoreServices>;
//# sourceMappingURL=services.d.ts.map

1
frontend/node_modules/langium/lib/services.js.map generated vendored Normal file
View File

@@ -0,0 +1 @@
{"version":3,"file":"services.js","sourceRoot":"","sources":["../src/services.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF"}

269
frontend/node_modules/langium/lib/syntax-tree.d.ts generated vendored Normal file
View File

@@ -0,0 +1,269 @@
/******************************************************************************
* 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 { TokenType } from 'chevrotain';
import type { URI } from './utils/uri-utils.js';
import type { AbstractElement } from './languages/generated/ast.js';
import type { DocumentSegment, LangiumDocument } from './workspace/documents.js';
/**
* A node in the Abstract Syntax Tree (AST).
*/
export interface AstNode {
/** Every AST node has a type corresponding to what was specified in the grammar declaration. */
readonly $type: string;
/** The container node in the AST; every node except the root node has a container. */
readonly $container?: AstNode;
/** The property of the `$container` node that contains this node. This is either a direct reference or an array. */
readonly $containerProperty?: string;
/** In case `$containerProperty` is an array, the array index is stored here. */
readonly $containerIndex?: number;
/** The Concrete Syntax Tree (CST) node of the text range from which this node was parsed. */
readonly $cstNode?: CstNode;
/** The document containing the AST; only the root node has a direct reference to the document. */
readonly $document?: LangiumDocument;
}
export declare function isAstNode(obj: unknown): obj is AstNode;
export interface GenericAstNode extends AstNode {
[key: string]: unknown;
}
type SpecificNodeProperties<N extends AstNode> = keyof Omit<N, keyof AstNode | number | symbol>;
/**
* The property names of a given AST node type.
*/
export type Properties<N extends AstNode> = SpecificNodeProperties<N> extends never ? string : SpecificNodeProperties<N>;
/**
* A cross-reference in the AST. Cross-references may or may not be successfully resolved.
*/
export interface Reference<T extends AstNode = AstNode> {
/**
* The target AST node of this reference. Accessing this property may trigger cross-reference
* resolution by the `Linker` in case it has not been done yet. If the reference cannot be resolved,
* the value is `undefined`.
*/
readonly ref: T | undefined;
/** If any problem occurred while resolving the reference, it is described by this property. */
readonly error?: LinkingError;
/** The CST node from which the reference was parsed */
readonly $refNode?: CstNode;
/** The actual text used to look up in the surrounding scope */
readonly $refText: string;
/** The node description for the AstNode returned by `ref` */
readonly $nodeDescription?: AstNodeDescription;
}
export interface MultiReference<T extends AstNode = AstNode> {
/** The CST node from which the reference was parsed */
readonly $refNode?: CstNode;
/** The actual text used to look up in the surrounding scope */
readonly $refText: string;
/**
* The resolved references. Accessing this property may trigger cross-reference
* resolution by the `Linker` in case it has not been done yet.
* If no references can be found, the array is empty (but not `undefined`)
* and the `error` property is set.
*/
readonly items: Array<MultiReferenceItem<T>>;
/** If any problem occurred while resolving the reference, it is described by this property. */
readonly error?: LinkingError;
}
/**
* Represents a single resolved reference of a {@link MultiReference} instance.
*/
export interface MultiReferenceItem<T extends AstNode = AstNode> {
/** The node description for the AstNode returned by `ref` */
readonly $nodeDescription?: AstNodeDescription;
/**
* The target AST node of this reference.
*/
readonly ref: T;
}
export declare function isReference(obj: unknown): obj is Reference;
export declare function isMultiReference(obj: unknown): obj is MultiReference;
export type ResolvedReference<T extends AstNode = AstNode> = Reference<T> & {
readonly ref: T;
};
/**
* A description of an AST node is used when constructing scopes and looking up cross-reference targets.
*/
export interface AstNodeDescription {
/** The target node; should be present only for local references (linking to the same document). */
node?: AstNode;
/**
* The document segment that represents the range of the name of the AST node.
*/
nameSegment?: DocumentSegment;
/**
* The document segment that represents the full range of the AST node.
*/
selectionSegment?: DocumentSegment;
/** `$type` property value of the AST node */
type: string;
/** Name of the AST node; this is usually determined by the `NameProvider` service. */
name: string;
/** URI to the document containing the AST node */
documentUri: URI;
/** Navigation path inside the document */
path: string;
}
export declare function isAstNodeDescription(obj: unknown): obj is AstNodeDescription;
/**
* Information about a cross-reference. This is used when traversing references in an AST or to describe
* unresolved references.
*/
export interface ReferenceInfo {
reference: Reference | MultiReference;
container: AstNode;
property: string;
index?: number;
}
/**
* Used to collect information when the `Linker` service fails to resolve a cross-reference.
*/
export interface LinkingError {
message: string;
info: ReferenceInfo;
targetDescription?: AstNodeDescription;
}
export declare function isLinkingError(obj: unknown): obj is LinkingError;
/**
* Service used for generic access to the structure of the AST. This service is shared between
* all involved languages, so it operates on the superset of types of these languages.
*/
export interface AstReflection {
readonly types: AstMetaData;
getAllTypes(): string[];
getReferenceType(refInfo: ReferenceInfo): string;
getTypeMetaData(type: string): TypeMetaData;
isInstance(node: unknown, type: string): boolean;
isSubtype(subtype: string, supertype: string): boolean;
getAllSubTypes(type: string): string[];
}
/**
* An abstract implementation of the {@link AstReflection} interface.
* Serves to cache subtype computation results to improve performance throughout different parts of Langium.
*/
export declare abstract class AbstractAstReflection implements AstReflection {
readonly types: AstMetaData;
protected subtypes: Record<string, Record<string, boolean | undefined>>;
protected allSubtypes: Record<string, string[] | undefined>;
getAllTypes(): string[];
getReferenceType(refInfo: ReferenceInfo): string;
getTypeMetaData(type: string): TypeMetaData;
isInstance(node: unknown, type: string): boolean;
isSubtype(subtype: string, supertype: string): boolean;
getAllSubTypes(type: string): string[];
}
/**
* A map of all AST node types and their meta data.
*/
export interface AstMetaData {
[type: string]: TypeMetaData;
}
/**
* Represents runtime meta data about an AST node type.
*/
export interface TypeMetaData {
/** The name of this AST node type. Corresponds to the `AstNode.$type` value. */
name: string;
/** A list of properties with their relevant meta data. */
properties: {
[name: string]: PropertyMetaData;
};
/** The super types of this AST node type. */
superTypes: string[];
}
/**
* Describes the meta data of a property of an AST node.
*/
export interface PropertyMetaData {
/** The name of this property. */
name: string;
/**
* Indicates that the property is mandatory in the AST node.
* For example, if an AST node contains an array, but no elements of this array have been parsed,
* we still expect an empty array instead of `undefined`.
*/
defaultValue?: PropertyType;
/**
* If the property is a reference, this is the type of the reference target.
*/
referenceType?: string;
}
/**
* Represents a default value for an AST property.
*/
export type PropertyType = number | string | boolean | PropertyType[];
/**
* A node in the Concrete Syntax Tree (CST).
*/
export interface CstNode extends DocumentSegment {
/** The container node in the CST */
readonly container?: CompositeCstNode;
/** The actual text */
readonly text: string;
/** The root CST node */
readonly root: RootCstNode;
/** The grammar element from which this node was parsed */
readonly grammarSource?: AbstractElement;
/** The AST node created from this CST node */
readonly astNode: AstNode;
/** Whether the token is hidden, i.e. not explicitly part of the containing grammar rule */
readonly hidden: boolean;
}
/**
* A composite CST node contains other nodes, but no directly associated token.
*/
export interface CompositeCstNode extends CstNode {
readonly content: CstNode[];
}
export declare function isCompositeCstNode(node: unknown): node is CompositeCstNode;
/**
* A leaf CST node corresponds to a token in the input token stream.
*/
export interface LeafCstNode extends CstNode {
readonly tokenType: TokenType;
}
export declare function isLeafCstNode(node: unknown): node is LeafCstNode;
export interface RootCstNode extends CompositeCstNode {
readonly fullText: string;
}
export declare function isRootCstNode(node: unknown): node is RootCstNode;
/**
* Describes a union type including only names(!) of properties of type T whose property value is of a certain type K,
* or 'never' in case of no such properties.
* It evaluates the value type regardless of the property being optional or not by converting T to Required<T>.
* Note the '-?' in '[I in keyof T]-?:' that is required to map all optional but un-intended properties to 'never'.
* Without that, optional props like those inherited from 'AstNode' would be mapped to 'never|undefined',
* and the subsequent value mapping ('...[keyof T]') would yield 'undefined' instead of 'never' for AstNode types
* not having any property matching type K, which in turn yields follow-up errors.
*/
type ExtractKeysOfValueType<T, K> = {
[I in keyof T]-?: Required<T>[I] extends K ? I : never;
}[keyof T];
export type SingleCrossReferencesOfAstNodeType<N extends AstNode> = ExtractKeysOfValueType<N, Reference | Reference[]>;
export type MultiCrossReferencesOfAstNodeType<N extends AstNode> = ExtractKeysOfValueType<N, MultiReference | MultiReference[]>;
/**
* Describes a union type including only names(!) of the cross-reference properties of the given AstNode type.
* Enhances compile-time validation of cross-reference distinctions, e.g. in scope providers
* in combination with `assertUnreachable(context.property)`.
*/
export type CrossReferencesOfAstNodeType<N extends AstNode> = SingleCrossReferencesOfAstNodeType<N> | MultiCrossReferencesOfAstNodeType<N>;
/**
* Represents the enumeration-like type, that lists all AstNode types of your grammar.
*/
export type AstTypeList<T> = Record<keyof T, AstNode>;
/**
* Describes a union type including of all AstNode types containing cross-references.
* A is meant to be the interface `XXXAstType` fromm your generated `ast.ts` file.
* Enhances compile-time validation of cross-reference distinctions, e.g. in scope providers
* in combination with `assertUnreachable(context.container)`.
*/
export type AstNodeTypesWithCrossReferences<A extends AstTypeList<A>> = {
[T in keyof A]-?: CrossReferencesOfAstNodeType<A[T]> extends never ? never : A[T];
}[keyof A];
export type Mutable<T> = {
-readonly [P in keyof T]: T[P];
};
export {};
//# sourceMappingURL=syntax-tree.d.ts.map

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