This commit is contained in:
nik
2025-10-03 22:27:28 +03:00
parent 829fad0e17
commit 871cf7e792
16520 changed files with 2967597 additions and 3 deletions

View File

@@ -0,0 +1,15 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { CallHierarchyIncomingCall, CallHierarchyOutgoingCall } from 'vscode-languageserver';
import type { AstNode } from '../../syntax-tree.js';
import type { Stream } from '../../utils/stream.js';
import type { ReferenceDescription } from '../../workspace/ast-descriptions.js';
import { AbstractCallHierarchyProvider } from '../../lsp/call-hierarchy-provider.js';
export declare class LangiumGrammarCallHierarchyProvider extends AbstractCallHierarchyProvider {
protected getIncomingCalls(node: AstNode, references: Stream<ReferenceDescription>): CallHierarchyIncomingCall[] | undefined;
protected getOutgoingCalls(node: AstNode): CallHierarchyOutgoingCall[] | undefined;
}
//# sourceMappingURL=grammar-call-hierarchy.d.ts.map

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

View File

@@ -0,0 +1,101 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { SymbolKind } from 'vscode-languageserver';
import { AbstractCallHierarchyProvider } from '../../lsp/call-hierarchy-provider.js';
import { getContainerOfType, getDocument, streamAllContents } from '../../utils/ast-utils.js';
import { findLeafNodeAtOffset } from '../../utils/cst-utils.js';
import { isParserRule, isRuleCall } from '../../languages/generated/ast.js';
export class LangiumGrammarCallHierarchyProvider extends AbstractCallHierarchyProvider {
getIncomingCalls(node, references) {
if (!isParserRule(node)) {
return undefined;
}
// This map is used to group incoming calls to avoid duplicates.
const uniqueRules = new Map();
references.forEach(ref => {
const doc = this.documents.getDocument(ref.sourceUri);
if (!doc) {
return;
}
const rootNode = doc.parseResult.value;
if (!rootNode.$cstNode) {
return;
}
const targetNode = findLeafNodeAtOffset(rootNode.$cstNode, ref.segment.offset);
if (!targetNode) {
return;
}
const parserRule = getContainerOfType(targetNode.astNode, isParserRule);
if (!parserRule || !parserRule.$cstNode) {
return;
}
const nameNode = this.nameProvider.getNameNode(parserRule);
if (!nameNode) {
return;
}
const refDocUri = ref.sourceUri.toString();
const ruleId = refDocUri + '@' + nameNode.text;
uniqueRules.has(ruleId) ?
uniqueRules.set(ruleId, { parserRule: parserRule.$cstNode, nameNode, targetNodes: [...uniqueRules.get(ruleId).targetNodes, targetNode], docUri: refDocUri })
: uniqueRules.set(ruleId, { parserRule: parserRule.$cstNode, nameNode, targetNodes: [targetNode], docUri: refDocUri });
});
if (uniqueRules.size === 0) {
return undefined;
}
return Array.from(uniqueRules.values()).map(rule => ({
from: {
kind: SymbolKind.Method,
name: rule.nameNode.text,
range: rule.parserRule.range,
selectionRange: rule.nameNode.range,
uri: rule.docUri
},
fromRanges: rule.targetNodes.map(node => node.range)
}));
}
getOutgoingCalls(node) {
if (!isParserRule(node)) {
return undefined;
}
const ruleCalls = streamAllContents(node).filter(isRuleCall).toArray();
// This map is used to group outgoing calls to avoid duplicates.
const uniqueRules = new Map();
ruleCalls.forEach(ruleCall => {
var _a;
const cstNode = ruleCall.$cstNode;
if (!cstNode) {
return;
}
const refCstNode = (_a = ruleCall.rule.ref) === null || _a === void 0 ? void 0 : _a.$cstNode;
if (!refCstNode) {
return;
}
const refNameNode = this.nameProvider.getNameNode(refCstNode.astNode);
if (!refNameNode) {
return;
}
const refDocUri = getDocument(refCstNode.astNode).uri.toString();
const ruleId = refDocUri + '@' + refNameNode.text;
uniqueRules.has(ruleId) ?
uniqueRules.set(ruleId, { refCstNode: refCstNode, to: refNameNode, from: [...uniqueRules.get(ruleId).from, cstNode.range], docUri: refDocUri })
: uniqueRules.set(ruleId, { refCstNode: refCstNode, to: refNameNode, from: [cstNode.range], docUri: refDocUri });
});
if (uniqueRules.size === 0) {
return undefined;
}
return Array.from(uniqueRules.values()).map(rule => ({
to: {
kind: SymbolKind.Method,
name: rule.to.text,
range: rule.refCstNode.range,
selectionRange: rule.to.range,
uri: rule.docUri
},
fromRanges: rule.from
}));
}
}
//# sourceMappingURL=grammar-call-hierarchy.js.map

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,36 @@
/******************************************************************************
* 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 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, params: CodeActionParams): MaybePromise<Array<Command | CodeAction>>;
private createCodeActions;
/**
* Adds missing returns for parser rule
*/
private fixMissingReturns;
private fixInvalidReturnsInfers;
private fixMissingInfer;
private fixSuperfluousInfer;
private fixUnnecessaryFileExtension;
private makeUpperCase;
private addEntryKeyword;
private fixRegexTokens;
private fixCrossRefSyntax;
private fixHiddenTerminals;
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;AAGhF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAsB,MAAM,6BAA6B,CAAC;AAE3F,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;AACpF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAGjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAWrE,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,EAAE,MAAM,EAAE,gBAAgB,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC,CAAC;IAS9G,OAAO,CAAC,iBAAiB;IAgDzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAoBzB,OAAO,CAAC,uBAAuB;IAqB/B,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,mBAAmB;IAoB3B,OAAO,CAAC,2BAA2B;IAwBnC,OAAO,CAAC,aAAa;IAwBrB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,cAAc;IA4BtB,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,kBAAkB;IA2C1B,OAAO,CAAC,UAAU;IA6BlB,OAAO,CAAC,iBAAiB;CA0E5B"}

View File

@@ -0,0 +1,419 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { CodeActionKind } from 'vscode-languageserver';
import { getContainerOfType } from '../../utils/ast-utils.js';
import { findLeafNodeAtOffset } from '../../utils/cst-utils.js';
import { findNodeForProperty } from '../../utils/grammar-utils.js';
import { escapeRegExp } from '../../utils/regexp-utils.js';
import { UriUtils } from '../../utils/uri-utils.js';
import { DocumentValidator } from '../../validation/document-validator.js';
import * as ast from '../../languages/generated/ast.js';
import { IssueCodes } from '../validation/validator.js';
export class LangiumGrammarCodeActionProvider {
constructor(services) {
this.reflection = services.shared.AstReflection;
this.indexManager = services.shared.workspace.IndexManager;
}
getCodeActions(document, params) {
const result = [];
const acceptor = (ca) => ca && result.push(ca);
for (const diagnostic of params.context.diagnostics) {
this.createCodeActions(diagnostic, document, acceptor);
}
return result;
}
createCodeActions(diagnostic, document, accept) {
var _a;
switch ((_a = diagnostic.data) === null || _a === void 0 ? void 0 : _a.code) {
case IssueCodes.GrammarNameUppercase:
case IssueCodes.RuleNameUppercase:
accept(this.makeUpperCase(diagnostic, document));
break;
case IssueCodes.HiddenGrammarTokens:
accept(this.fixHiddenTerminals(diagnostic, document));
break;
case IssueCodes.UseRegexTokens:
accept(this.fixRegexTokens(diagnostic, document));
break;
case IssueCodes.EntryRuleTokenSyntax:
accept(this.addEntryKeyword(diagnostic, document));
break;
case IssueCodes.CrossRefTokenSyntax:
accept(this.fixCrossRefSyntax(diagnostic, document));
break;
case IssueCodes.UnnecessaryFileExtension:
accept(this.fixUnnecessaryFileExtension(diagnostic, document));
break;
case IssueCodes.MissingReturns:
accept(this.fixMissingReturns(diagnostic, document));
break;
case IssueCodes.InvalidInfers:
case IssueCodes.InvalidReturns:
accept(this.fixInvalidReturnsInfers(diagnostic, document));
break;
case IssueCodes.MissingInfer:
accept(this.fixMissingInfer(diagnostic, document));
break;
case IssueCodes.SuperfluousInfer:
accept(this.fixSuperfluousInfer(diagnostic, document));
break;
case DocumentValidator.LinkingError: {
const data = diagnostic.data;
if (data && data.containerType === 'RuleCall' && data.property === 'rule') {
accept(this.addNewRule(diagnostic, data, document));
}
if (data) {
this.lookInGlobalScope(diagnostic, data, document).forEach(accept);
}
break;
}
}
return undefined;
}
/**
* Adds missing returns for parser rule
*/
fixMissingReturns(diagnostic, document) {
const text = document.textDocument.getText(diagnostic.range);
if (text) {
return {
title: `Add explicit return type for parser rule ${text}`,
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
edit: {
changes: {
[document.textDocument.uri]: [{
range: diagnostic.range,
newText: `${text} returns ${text}` // suggestion adds missing 'return'
}]
}
}
};
}
return undefined;
}
fixInvalidReturnsInfers(diagnostic, document) {
const data = diagnostic.data;
if (data && data.actionSegment) {
const text = document.textDocument.getText(data.actionSegment.range);
return {
title: `Correct ${text} usage`,
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
edit: {
changes: {
[document.textDocument.uri]: [{
range: data.actionSegment.range,
newText: text === 'infers' ? 'returns' : 'infers'
}]
}
}
};
}
return undefined;
}
fixMissingInfer(diagnostic, document) {
const data = diagnostic.data;
if (data && data.actionSegment) {
return {
title: "Correct 'infer' usage",
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
edit: {
changes: {
[document.textDocument.uri]: [{
range: {
start: data.actionSegment.range.end,
end: data.actionSegment.range.end
},
newText: 'infer '
}]
}
}
};
}
return undefined;
}
fixSuperfluousInfer(diagnostic, document) {
const data = diagnostic.data;
if (data && data.actionRange) {
return {
title: "Remove the 'infer' keyword",
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
edit: {
changes: {
[document.textDocument.uri]: [{
range: data.actionRange,
newText: ''
}]
}
}
};
}
return undefined;
}
fixUnnecessaryFileExtension(diagnostic, document) {
const end = Object.assign({}, diagnostic.range.end);
end.character -= 1;
const start = Object.assign({}, end);
start.character -= '.langium'.length;
return {
title: 'Remove file extension',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range: {
start,
end
},
newText: ''
}]
}
}
};
}
makeUpperCase(diagnostic, document) {
const range = {
start: diagnostic.range.start,
end: {
line: diagnostic.range.start.line,
character: diagnostic.range.start.character + 1
}
};
return {
title: 'First letter to upper case',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range,
newText: document.textDocument.getText(range).toUpperCase()
}]
}
}
};
}
addEntryKeyword(diagnostic, document) {
return {
title: 'Add entry keyword',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range: { start: diagnostic.range.start, end: diagnostic.range.start },
newText: 'entry '
}]
}
}
};
}
fixRegexTokens(diagnostic, document) {
const offset = document.textDocument.offsetAt(diagnostic.range.start);
const rootCst = document.parseResult.value.$cstNode;
if (rootCst) {
const cstNode = findLeafNodeAtOffset(rootCst, offset);
const container = getContainerOfType(cstNode === null || cstNode === void 0 ? void 0 : cstNode.astNode, ast.isCharacterRange);
if (container && container.right && container.$cstNode) {
const left = container.left.value;
const right = container.right.value;
return {
title: 'Refactor into regular expression',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range: container.$cstNode.range,
newText: `/[${escapeRegExp(left)}-${escapeRegExp(right)}]/`
}]
}
}
};
}
}
return undefined;
}
fixCrossRefSyntax(diagnostic, document) {
return {
title: "Replace '|' with ':'",
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range: diagnostic.range,
newText: ':'
}]
}
}
};
}
fixHiddenTerminals(diagnostic, document) {
const grammar = document.parseResult.value;
const hiddenTokens = grammar.hiddenTokens;
const changes = [];
const hiddenNode = findNodeForProperty(grammar.$cstNode, 'definesHiddenTokens');
if (hiddenNode) {
const start = hiddenNode.range.start;
const offset = hiddenNode.offset;
const end = grammar.$cstNode.text.indexOf(')', offset) + 1;
changes.push({
newText: '',
range: {
start,
end: document.textDocument.positionAt(end)
}
});
}
for (const terminal of hiddenTokens) {
const ref = terminal.ref;
if (ref && ast.isTerminalRule(ref) && !ref.hidden && ref.$cstNode) {
const start = ref.$cstNode.range.start;
changes.push({
newText: 'hidden ',
range: {
start,
end: start
}
});
}
}
return {
title: 'Fix hidden terminals',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: changes
}
}
};
}
addNewRule(diagnostic, data, document) {
const offset = document.textDocument.offsetAt(diagnostic.range.start);
const rootCst = document.parseResult.value.$cstNode;
if (rootCst) {
const cstNode = findLeafNodeAtOffset(rootCst, offset);
const container = getContainerOfType(cstNode === null || cstNode === void 0 ? void 0 : cstNode.astNode, ast.isParserRule);
if (container && container.$cstNode) {
return {
title: `Add new rule '${data.refText}'`,
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: false,
edit: {
changes: {
[document.textDocument.uri]: [{
range: {
start: container.$cstNode.range.end,
end: container.$cstNode.range.end
},
newText: '\n\n' + data.refText + ':\n /* TODO implement rule */ {infer ' + data.refText + '};'
}]
}
}
};
}
}
return undefined;
}
lookInGlobalScope(diagnostic, data, document) {
var _a, _b;
const refInfo = {
container: {
$type: data.containerType
},
property: data.property,
reference: {
$refText: data.refText
}
};
const referenceType = this.reflection.getReferenceType(refInfo);
const candidates = this.indexManager.allElements(referenceType).filter(e => e.name === data.refText);
const result = [];
let shortestPathIndex = -1;
let shortestPathLength = -1;
for (const candidate of candidates) {
if (UriUtils.equals(candidate.documentUri, document.uri)) {
continue;
}
// Find an import path and a position to insert the import
const importPath = getRelativeImport(document.uri, candidate.documentUri);
let position;
let suffix = '';
const grammar = document.parseResult.value;
const nextImport = grammar.imports.find(imp => imp.path && importPath < imp.path);
if (nextImport) {
// Insert the new import alphabetically
position = (_a = nextImport.$cstNode) === null || _a === void 0 ? void 0 : _a.range.start;
}
else if (grammar.imports.length > 0) {
// Put the new import after the last import
const rangeEnd = grammar.imports[grammar.imports.length - 1].$cstNode.range.end;
if (rangeEnd) {
position = { line: rangeEnd.line + 1, character: 0 };
}
}
else if (grammar.rules.length > 0) {
// Put the new import before the first rule
position = (_b = grammar.rules[0].$cstNode) === null || _b === void 0 ? void 0 : _b.range.start;
suffix = '\n';
}
if (position) {
if (shortestPathIndex < 0 || importPath.length < shortestPathLength) {
shortestPathIndex = result.length;
shortestPathLength = importPath.length;
}
// Add an import declaration for the candidate in the global scope
result.push({
title: `Add import to '${importPath}'`,
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: false,
edit: {
changes: {
[document.textDocument.uri]: [{
range: {
start: position,
end: position
},
newText: `import '${importPath}'\n${suffix}`
}]
}
}
});
}
}
// Mark the code action with the shortest import path as preferred
if (shortestPathIndex >= 0) {
result[shortestPathIndex].isPreferred = true;
}
return result;
}
}
function getRelativeImport(source, target) {
const sourceDir = UriUtils.dirname(source);
let relativePath = UriUtils.relative(sourceDir, target);
if (!relativePath.startsWith('./') && !relativePath.startsWith('../')) {
relativePath = './' + relativePath;
}
if (relativePath.endsWith('.langium')) {
relativePath = relativePath.substring(0, relativePath.length - '.langium'.length);
}
return relativePath;
}
//# sourceMappingURL=grammar-code-actions.js.map

File diff suppressed because one or more lines are too long

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 { NextFeature } from '../../lsp/completion/follow-element-computation.js';
import { DefaultCompletionProvider, type CompletionAcceptor, type CompletionContext } from '../../lsp/completion/completion-provider.js';
import type { MaybePromise } from '../../utils/promise-utils.js';
import type { AbstractElement } from '../../languages/generated/ast.js';
import type { LangiumServices } from '../../lsp/lsp-services.js';
export declare class LangiumGrammarCompletionProvider extends DefaultCompletionProvider {
private readonly documents;
constructor(services: LangiumServices);
protected completionFor(context: CompletionContext, next: NextFeature<AbstractElement>, acceptor: CompletionAcceptor): MaybePromise<void>;
private completeImportPath;
private getAllFiles;
}
//# sourceMappingURL=grammar-completion-provider.d.ts.map

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,78 @@
/******************************************************************************
* Copyright 2023 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { CompletionItemKind } from 'vscode-languageserver-types';
import { DefaultCompletionProvider } from '../../lsp/completion/completion-provider.js';
import { getContainerOfType } from '../../utils/ast-utils.js';
import { isAssignment } from '../../languages/generated/ast.js';
import { UriUtils } from '../../utils/uri-utils.js';
export class LangiumGrammarCompletionProvider extends DefaultCompletionProvider {
constructor(services) {
super(services);
this.documents = () => services.shared.workspace.LangiumDocuments;
}
completionFor(context, next, acceptor) {
const assignment = getContainerOfType(next.feature, isAssignment);
if ((assignment === null || assignment === void 0 ? void 0 : assignment.feature) === 'path') {
this.completeImportPath(context, acceptor);
}
else {
return super.completionFor(context, next, acceptor);
}
}
completeImportPath(context, acceptor) {
const text = context.textDocument.getText();
const existingText = text.substring(context.tokenOffset, context.offset);
let allPaths = this.getAllFiles(context.document);
let range = {
start: context.position,
end: context.position
};
if (existingText.length > 0) {
const existingPath = existingText.substring(1);
allPaths = allPaths.filter(path => path.startsWith(existingPath));
// Completely replace the current token
const start = context.textDocument.positionAt(context.tokenOffset + 1);
const end = context.textDocument.positionAt(context.tokenEndOffset - 1);
range = {
start,
end
};
}
for (const path of allPaths) {
// Only insert quotes if there is no `path` token yet.
const delimiter = existingText.length > 0 ? '' : '"';
const completionValue = `${delimiter}${path}${delimiter}`;
acceptor(context, {
label: path,
textEdit: {
newText: completionValue,
range
},
kind: CompletionItemKind.File,
sortText: '0'
});
}
}
getAllFiles(document) {
const documents = this.documents().all;
const uri = document.uri.toString();
const dirname = UriUtils.dirname(document.uri).toString();
const paths = [];
for (const doc of documents) {
if (!UriUtils.equals(doc.uri, uri)) {
const docUri = doc.uri.toString();
const uriWithoutExt = docUri.substring(0, docUri.length - UriUtils.extname(doc.uri).length);
let relativePath = UriUtils.relative(dirname, uriWithoutExt);
if (!relativePath.startsWith('.')) {
relativePath = `./${relativePath}`;
}
paths.push(relativePath);
}
}
return paths;
}
}
//# sourceMappingURL=grammar-completion-provider.js.map

View File

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

View File

@@ -0,0 +1,20 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { DefinitionParams } from 'vscode-languageserver';
import type { LangiumServices } from '../../lsp/lsp-services.js';
import type { AstNode, LeafCstNode } from '../../syntax-tree.js';
import type { MaybePromise } from '../../utils/promise-utils.js';
import type { LangiumDocuments } from '../../workspace/documents.js';
import type { Grammar } from '../../languages/generated/ast.js';
import { LocationLink } from 'vscode-languageserver';
import { DefaultDefinitionProvider } from '../../lsp/index.js';
export declare class LangiumGrammarDefinitionProvider extends DefaultDefinitionProvider {
protected documents: LangiumDocuments;
constructor(services: LangiumServices);
protected collectLocationLinks(sourceCstNode: LeafCstNode, _params: DefinitionParams): MaybePromise<LocationLink[] | undefined>;
protected findTargetObject(importedGrammar: Grammar): AstNode | undefined;
}
//# sourceMappingURL=grammar-definition.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"grammar-definition.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-definition.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAc,MAAM,sBAAsB,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAS,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAM/D,qBAAa,gCAAiC,SAAQ,yBAAyB;IAE3E,SAAS,CAAC,SAAS,EAAE,gBAAgB,CAAC;gBAE1B,QAAQ,EAAE,eAAe;cAKlB,oBAAoB,CAAC,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,GAAG,YAAY,CAAC,YAAY,EAAE,GAAG,SAAS,CAAC;IAsBxI,SAAS,CAAC,gBAAgB,CAAC,eAAe,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS;CAO5E"}

View File

@@ -0,0 +1,42 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { LocationLink, Range } from 'vscode-languageserver';
import { DefaultDefinitionProvider } from '../../lsp/index.js';
import { streamContents } from '../../utils/ast-utils.js';
import { findAssignment } from '../../utils/grammar-utils.js';
import { isGrammarImport } from '../../languages/generated/ast.js';
import { resolveImport } from '../internal-grammar-util.js';
export class LangiumGrammarDefinitionProvider extends DefaultDefinitionProvider {
constructor(services) {
super(services);
this.documents = services.shared.workspace.LangiumDocuments;
}
collectLocationLinks(sourceCstNode, _params) {
var _a, _b, _c, _d, _e, _f;
const pathFeature = 'path';
if (isGrammarImport(sourceCstNode.astNode) && ((_a = findAssignment(sourceCstNode)) === null || _a === void 0 ? void 0 : _a.feature) === pathFeature) {
const importedGrammar = resolveImport(this.documents, sourceCstNode.astNode);
if (importedGrammar === null || importedGrammar === void 0 ? void 0 : importedGrammar.$document) {
const targetObject = (_b = this.findTargetObject(importedGrammar)) !== null && _b !== void 0 ? _b : importedGrammar;
const selectionRange = (_d = (_c = this.nameProvider.getNameNode(targetObject)) === null || _c === void 0 ? void 0 : _c.range) !== null && _d !== void 0 ? _d : Range.create(0, 0, 0, 0);
const previewRange = (_f = (_e = targetObject.$cstNode) === null || _e === void 0 ? void 0 : _e.range) !== null && _f !== void 0 ? _f : Range.create(0, 0, 0, 0);
return [
LocationLink.create(importedGrammar.$document.uri.toString(), previewRange, selectionRange, sourceCstNode.range)
];
}
return undefined;
}
return super.collectLocationLinks(sourceCstNode, _params);
}
findTargetObject(importedGrammar) {
// Jump to grammar name or the first element
if (importedGrammar.isDeclared) {
return importedGrammar;
}
return streamContents(importedGrammar).head();
}
}
//# sourceMappingURL=grammar-definition.js.map

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,CAAA,MAAA,cAAc,CAAC,aAAa,CAAC,0CAAE,OAAO,MAAK,WAAW,EAAE,CAAC;YACnG,MAAM,eAAe,GAAG,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;YAC7E,IAAI,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAE,SAAS,EAAE,CAAC;gBAC7B,MAAM,YAAY,GAAG,MAAA,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,mCAAI,eAAe,CAAC;gBAC/E,MAAM,cAAc,GAAG,MAAA,MAAA,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,YAAY,CAAC,0CAAE,KAAK,mCAAI,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBACtG,MAAM,YAAY,GAAG,MAAA,MAAA,YAAY,CAAC,QAAQ,0CAAE,KAAK,mCAAI,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,14 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { AstNode } from '../../syntax-tree.js';
import { DefaultFoldingRangeProvider } from '../../lsp/folding-range-provider.js';
/**
* A specialized folding range provider for the grammar language
*/
export declare class LangiumGrammarFoldingRangeProvider extends DefaultFoldingRangeProvider {
shouldProcessContent(node: AstNode): boolean;
}
//# sourceMappingURL=grammar-folding-ranges.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"grammar-folding-ranges.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-folding-ranges.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAGlF;;GAEG;AACH,qBAAa,kCAAmC,SAAQ,2BAA2B;IAEtE,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;CAIxD"}

View File

@@ -0,0 +1,17 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { DefaultFoldingRangeProvider } from '../../lsp/folding-range-provider.js';
import { isParserRule } from '../../languages/generated/ast.js';
/**
* A specialized folding range provider for the grammar language
*/
export class LangiumGrammarFoldingRangeProvider extends DefaultFoldingRangeProvider {
shouldProcessContent(node) {
// Exclude parser rules from folding
return !isParserRule(node);
}
}
//# sourceMappingURL=grammar-folding-ranges.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"grammar-folding-ranges.js","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-folding-ranges.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAGhF,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAEhE;;GAEG;AACH,MAAM,OAAO,kCAAmC,SAAQ,2BAA2B;IAEtE,oBAAoB,CAAC,IAAa;QACvC,oCAAoC;QACpC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;CACJ"}

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 @@
{"version":3,"file":"grammar-formatter.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-formatter.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAc,MAAM,wBAAwB,CAAC;AAKvE,qBAAa,uBAAwB,SAAQ,iBAAiB;IAE1D,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;CA2ExC"}

View File

@@ -0,0 +1,94 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { AbstractFormatter, Formatting } from '../../lsp/formatter.js';
import * as ast from '../../languages/generated/ast.js';
const indentOrSpace = Formatting.fit(Formatting.oneSpace(), Formatting.indent());
export class LangiumGrammarFormatter extends AbstractFormatter {
format(node) {
if (ast.isCrossReference(node)) {
const formatter = this.getNodeFormatter(node);
formatter.properties('type', 'terminal').surround(Formatting.noSpace());
}
else if (ast.isParserRule(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keywords('entry', 'fragment', 'returns').append(Formatting.oneSpace());
if ((node.inferredType || node.returnType || node.dataType) && node.parameters.length === 0) {
formatter.property('name').append(Formatting.oneSpace());
}
else {
formatter.property('name').append(Formatting.noSpace());
}
formatter.properties('parameters').append(Formatting.noSpace());
formatter.keywords(',').append(Formatting.oneSpace());
formatter.keywords('<').append(Formatting.noSpace());
const semicolon = formatter.keyword(';');
const colon = formatter.keyword(':');
colon.prepend(Formatting.noSpace());
formatter.interior(colon, semicolon).prepend(Formatting.indent());
semicolon.prepend(Formatting.fit(Formatting.noSpace(), Formatting.newLine()));
formatter.node(node).prepend(Formatting.noIndent());
}
else if (ast.isTerminalRule(node)) {
const formatter = this.getNodeFormatter(node);
if (node.type) {
formatter.property('name').append(Formatting.oneSpace());
formatter.keyword('returns').append(Formatting.oneSpace());
}
formatter.keywords('hidden', 'terminal', 'fragment').append(Formatting.oneSpace());
formatter.keyword(':').prepend(Formatting.noSpace());
formatter.keyword(';').prepend(Formatting.fit(Formatting.noSpace(), Formatting.newLine()));
formatter.node(node).prepend(Formatting.noIndent());
}
else if (ast.isAction(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keyword('{').append(Formatting.noSpace());
formatter.keywords('.', '+=', '=').surround(Formatting.noSpace());
formatter.keyword('}').prepend(Formatting.noSpace());
}
else if (ast.isInferredType(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keywords('infer', 'infers').append(Formatting.oneSpace());
}
else if (ast.isAssignment(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keywords('=', '+=', '?=').surround(Formatting.noSpace());
}
else if (ast.isRuleCall(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keyword('<').surround(Formatting.noSpace());
formatter.keyword(',').append(Formatting.oneSpace());
formatter.properties('arguments').append(Formatting.noSpace());
}
else if (ast.isInterface(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keyword('interface').append(Formatting.oneSpace());
formatter.keyword('extends').prepend(Formatting.oneSpace()).append(indentOrSpace);
formatter.keywords(',').prepend(Formatting.noSpace()).append(indentOrSpace);
const bracesOpen = formatter.keyword('{');
bracesOpen.prepend(Formatting.fit(Formatting.oneSpace(), Formatting.newLine()));
const bracesClose = formatter.keyword('}');
bracesClose.prepend(Formatting.newLine());
formatter.interior(bracesOpen, bracesClose).prepend(Formatting.indent());
}
else if (ast.isType(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keyword('type').append(Formatting.oneSpace());
formatter.keyword('=').prepend(Formatting.oneSpace()).append(indentOrSpace);
formatter.keyword(';').prepend(Formatting.noSpace()).append(Formatting.newLine());
}
else if (ast.isGrammar(node)) {
const formatter = this.getNodeFormatter(node);
const nodes = formatter.nodes(...node.rules, ...node.interfaces, ...node.types, ...node.imports);
nodes.prepend(Formatting.noIndent());
formatter.keyword('grammar').prepend(Formatting.noSpace()).append(Formatting.oneSpace());
}
if (ast.isAbstractElement(node)) {
const formatter = this.getNodeFormatter(node);
formatter.property('cardinality').prepend(Formatting.noSpace());
}
}
}
//# sourceMappingURL=grammar-formatter.js.map

File diff suppressed because one or more lines are too long

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.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-semantic-tokens.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAElF,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AAGrF,qBAAa,mCAAoC,SAAQ,6BAA6B;IAElF,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,qBAAqB,GAAG,IAAI;CA0DnF"}

View File

@@ -0,0 +1,76 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { SemanticTokenTypes } from 'vscode-languageserver';
import { AbstractSemanticTokenProvider } from '../../lsp/semantic-token-provider.js';
import { isAction, isAssignment, isParameter, isParameterReference, isReturnType, isRuleCall, isSimpleType, isTypeAttribute } from '../../languages/generated/ast.js';
export class LangiumGrammarSemanticTokenProvider extends AbstractSemanticTokenProvider {
highlightElement(node, acceptor) {
var _a;
if (isAssignment(node)) {
acceptor({
node,
property: 'feature',
type: SemanticTokenTypes.property
});
}
else if (isAction(node)) {
if (node.feature) {
acceptor({
node,
property: 'feature',
type: SemanticTokenTypes.property
});
}
}
else if (isReturnType(node)) {
acceptor({
node,
property: 'name',
type: SemanticTokenTypes.type
});
}
else if (isSimpleType(node)) {
if (node.primitiveType || node.typeRef) {
acceptor({
node,
property: node.primitiveType ? 'primitiveType' : 'typeRef',
type: SemanticTokenTypes.type
});
}
}
else if (isParameter(node)) {
acceptor({
node,
property: 'name',
type: SemanticTokenTypes.parameter
});
}
else if (isParameterReference(node)) {
acceptor({
node,
property: 'parameter',
type: SemanticTokenTypes.parameter
});
}
else if (isRuleCall(node)) {
if ((_a = node.rule.ref) === null || _a === void 0 ? void 0 : _a.fragment) {
acceptor({
node,
property: 'rule',
type: SemanticTokenTypes.type
});
}
}
else if (isTypeAttribute(node)) {
acceptor({
node,
property: 'name',
type: SemanticTokenTypes.property
});
}
}
}
//# sourceMappingURL=grammar-semantic-tokens.js.map

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,oBAAoB,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAEtK,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,MAAA,IAAI,CAAC,IAAI,CAAC,GAAG,0CAAE,QAAQ,EAAE,CAAC;gBAC1B,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,13 @@
/******************************************************************************
* Copyright 2023 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { AstNode } from '../../syntax-tree.js';
import type { TypeHierarchyItem } from 'vscode-languageserver';
import { AbstractTypeHierarchyProvider } from '../../lsp/type-hierarchy-provider.js';
export declare class LangiumGrammarTypeHierarchyProvider extends AbstractTypeHierarchyProvider {
protected getSupertypes(node: AstNode): TypeHierarchyItem[] | undefined;
protected getSubtypes(node: AstNode): TypeHierarchyItem[] | undefined;
}
//# sourceMappingURL=grammar-type-hierarchy.d.ts.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"grammar-type-hierarchy.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-type-hierarchy.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AAKrF,qBAAa,mCAAoC,SAAQ,6BAA6B;IAClF,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,iBAAiB,EAAE,GAAG,SAAS;IAiBvE,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,iBAAiB,EAAE,GAAG,SAAS;CAmCxE"}

View File

@@ -0,0 +1,56 @@
/******************************************************************************
* Copyright 2023 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { AbstractTypeHierarchyProvider } from '../../lsp/type-hierarchy-provider.js';
import { getDocument } from '../../utils/ast-utils.js';
import { findLeafNodeAtOffset } from '../../utils/cst-utils.js';
import { isInterface } from '../../languages/generated/ast.js';
export class LangiumGrammarTypeHierarchyProvider extends AbstractTypeHierarchyProvider {
getSupertypes(node) {
if (!isInterface(node)) {
return undefined;
}
const items = node.superTypes.flatMap(superType => {
var _a;
const ref = superType.ref;
if (!ref) {
return [];
}
return (_a = this.getTypeHierarchyItems(ref, getDocument(ref))) !== null && _a !== void 0 ? _a : [];
});
return items.length === 0 ? undefined : items;
}
getSubtypes(node) {
if (!isInterface(node)) {
return undefined;
}
const items = this.references
.findReferences(node, { includeDeclaration: false })
.flatMap(ref => {
var _a;
const document = this.documents.getDocument(ref.sourceUri);
if (!document) {
return [];
}
const rootNode = document.parseResult.value;
if (!rootNode.$cstNode) {
return [];
}
const refCstNode = findLeafNodeAtOffset(rootNode.$cstNode, ref.segment.offset);
if (!refCstNode) {
return [];
}
// Only consider references that occur as a superType of an interface
const refNode = refCstNode.astNode;
if (!isInterface(refNode) || refNode.superTypes.every(superType => superType.$refNode !== refCstNode)) {
return [];
}
return (_a = this.getTypeHierarchyItems(refNode, document)) !== null && _a !== void 0 ? _a : [];
})
.toArray();
return items.length === 0 ? undefined : items;
}
}
//# sourceMappingURL=grammar-type-hierarchy.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"grammar-type-hierarchy.js","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-type-hierarchy.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAIhF,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAE/D,MAAM,OAAO,mCAAoC,SAAQ,6BAA6B;IACxE,aAAa,CAAC,IAAa;QACjC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;;YAC9C,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC;YAC1B,IAAI,CAAC,GAAG,EAAE,CAAC;gBACP,OAAO,EAAE,CAAC;YACd,CAAC;YAED,OAAO,MAAA,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,mCAAI,EAAE,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;IAClD,CAAC;IAES,WAAW,CAAC,IAAa;QAC/B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU;aACxB,cAAc,CAAC,IAAI,EAAE,EAAC,kBAAkB,EAAE,KAAK,EAAC,CAAC;aACjD,OAAO,CAAC,GAAG,CAAC,EAAE;;YACX,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC3D,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACZ,OAAO,EAAE,CAAC;YACd,CAAC;YAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC;YAC5C,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACrB,OAAO,EAAE,CAAC;YACd,CAAC;YAED,MAAM,UAAU,GAAG,oBAAoB,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC/E,IAAI,CAAC,UAAU,EAAE,CAAC;gBACd,OAAO,EAAE,CAAC;YACd,CAAC;YAED,qEAAqE;YACrE,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;YACnC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,KAAK,UAAU,CAAC,EAAE,CAAC;gBACpG,OAAO,EAAE,CAAC;YACd,CAAC;YAED,OAAO,MAAA,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,QAAQ,CAAC,mCAAI,EAAE,CAAC;QAC/D,CAAC,CAAC;aACD,OAAO,EAAE,CAAC;QAEf,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;IAClD,CAAC;CACJ"}