First commit.

Signed-off-by: Chen Xiao <abigwc@gmail.com>
This commit is contained in:
Chen Xiao
2026-05-08 14:43:16 +08:00
commit 0b64e2de94
10989 changed files with 2253791 additions and 0 deletions
@@ -0,0 +1,15 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { CallHierarchyIncomingCall, CallHierarchyOutgoingCall } from 'vscode-languageserver';
import type { AstNode } from '../../syntax-tree.js';
import type { Stream } from '../../utils/stream.js';
import type { ReferenceDescription } from '../../workspace/ast-descriptions.js';
import { AbstractCallHierarchyProvider } from '../../lsp/call-hierarchy-provider.js';
export declare class LangiumGrammarCallHierarchyProvider extends AbstractCallHierarchyProvider {
protected getIncomingCalls(node: AstNode, references: Stream<ReferenceDescription>): CallHierarchyIncomingCall[] | undefined;
protected getOutgoingCalls(node: AstNode): CallHierarchyOutgoingCall[] | undefined;
}
//# sourceMappingURL=grammar-call-hierarchy.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-call-hierarchy.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-call-hierarchy.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,yBAAyB,EAAE,yBAAyB,EAAS,MAAM,uBAAuB,CAAC;AACzG,OAAO,KAAK,EAAE,OAAO,EAAW,MAAM,sBAAsB,CAAC;AAC7D,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,qCAAqC,CAAC;AAEhF,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AAKrF,qBAAa,mCAAoC,SAAQ,6BAA6B;IAElF,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,CAAC,oBAAoB,CAAC,GAAG,yBAAyB,EAAE,GAAG,SAAS;IAiD5H,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,GAAG,yBAAyB,EAAE,GAAG,SAAS;CAmErF"}
+128
View File
@@ -0,0 +1,128 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { SymbolKind } from 'vscode-languageserver';
import { AbstractCallHierarchyProvider } from '../../lsp/call-hierarchy-provider.js';
import { getContainerOfType, getDocument, streamAllContents } from '../../utils/ast-utils.js';
import { findLeafNodeAtOffset } from '../../utils/cst-utils.js';
import { isAbstractParserRule, isInfixRule, isParserRule, isRuleCall } from '../../languages/generated/ast.js';
export class LangiumGrammarCallHierarchyProvider extends AbstractCallHierarchyProvider {
getIncomingCalls(node, references) {
if (!isAbstractParserRule(node)) {
return undefined;
}
// This map is used to group incoming calls to avoid duplicates.
const uniqueRules = new Map();
references.forEach(ref => {
const doc = this.documents.getDocument(ref.sourceUri);
if (!doc) {
return;
}
const rootNode = doc.parseResult.value;
if (!rootNode.$cstNode) {
return;
}
const targetNode = findLeafNodeAtOffset(rootNode.$cstNode, ref.segment.offset);
if (!targetNode) {
return;
}
const parserRule = getContainerOfType(targetNode.astNode, isAbstractParserRule);
if (!parserRule || !parserRule.$cstNode) {
return;
}
const nameNode = this.nameProvider.getNameNode(parserRule);
if (!nameNode) {
return;
}
const refDocUri = ref.sourceUri.toString();
const ruleId = refDocUri + '@' + nameNode.text;
uniqueRules.has(ruleId) ?
uniqueRules.set(ruleId, { parserRule: parserRule.$cstNode, nameNode, targetNodes: [...uniqueRules.get(ruleId).targetNodes, targetNode], docUri: refDocUri })
: uniqueRules.set(ruleId, { parserRule: parserRule.$cstNode, nameNode, targetNodes: [targetNode], docUri: refDocUri });
});
if (uniqueRules.size === 0) {
return undefined;
}
return Array.from(uniqueRules.values()).map(rule => ({
from: {
kind: SymbolKind.Method,
name: rule.nameNode.text,
range: rule.parserRule.range,
selectionRange: rule.nameNode.range,
uri: rule.docUri
},
fromRanges: rule.targetNodes.map(node => node.range)
}));
}
getOutgoingCalls(node) {
if (isParserRule(node)) {
const ruleCalls = streamAllContents(node).filter(isRuleCall).toArray();
// This map is used to group outgoing calls to avoid duplicates.
const uniqueRules = new Map();
ruleCalls.forEach(ruleCall => {
const cstNode = ruleCall.$cstNode;
if (!cstNode) {
return;
}
const refCstNode = ruleCall.rule.ref?.$cstNode;
if (!refCstNode) {
return;
}
const refNameNode = this.nameProvider.getNameNode(refCstNode.astNode);
if (!refNameNode) {
return;
}
const refDocUri = getDocument(refCstNode.astNode).uri.toString();
const ruleId = refDocUri + '@' + refNameNode.text;
uniqueRules.has(ruleId) ?
uniqueRules.set(ruleId, { refCstNode: refCstNode, to: refNameNode, from: [...uniqueRules.get(ruleId).from, cstNode.range], docUri: refDocUri })
: uniqueRules.set(ruleId, { refCstNode: refCstNode, to: refNameNode, from: [cstNode.range], docUri: refDocUri });
});
if (uniqueRules.size === 0) {
return undefined;
}
return Array.from(uniqueRules.values()).map(rule => ({
to: {
kind: SymbolKind.Method,
name: rule.to.text,
range: rule.refCstNode.range,
selectionRange: rule.to.range,
uri: rule.docUri
},
fromRanges: rule.from
}));
}
else if (isInfixRule(node)) {
const ruleCall = node.call;
const cstNode = ruleCall.$cstNode;
if (!cstNode) {
return undefined;
}
const refCstNode = ruleCall.rule.ref?.$cstNode;
if (!refCstNode) {
return undefined;
}
const refNameNode = this.nameProvider.getNameNode(refCstNode.astNode);
if (!refNameNode) {
return undefined;
}
const refDocUri = getDocument(refCstNode.astNode).uri.toString();
return [{
to: {
kind: SymbolKind.Method,
name: refNameNode.text,
range: refCstNode.range,
selectionRange: refNameNode.range,
uri: refDocUri
},
fromRanges: [cstNode.range]
}];
}
else {
return undefined;
}
}
}
//# sourceMappingURL=grammar-call-hierarchy.js.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-call-hierarchy.js","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-call-hierarchy.ts"],"names":[],"mappings":"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"}
+42
View File
@@ -0,0 +1,42 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { CodeActionParams } from 'vscode-languageserver-protocol';
import type { CodeAction, Command } from 'vscode-languageserver-types';
import * as ast from '../../languages/generated/ast.js';
import type { CodeActionProvider } from '../../lsp/code-action.js';
import type { LangiumServices } from '../../lsp/lsp-services.js';
import type { AstReflection } from '../../syntax-tree.js';
import type { MaybePromise } from '../../utils/promise-utils.js';
import type { LangiumDocument } from '../../workspace/documents.js';
import type { IndexManager } from '../../workspace/index-manager.js';
export declare class LangiumGrammarCodeActionProvider implements CodeActionProvider {
protected readonly reflection: AstReflection;
protected readonly indexManager: IndexManager;
constructor(services: LangiumServices);
getCodeActions(document: LangiumDocument<ast.Grammar>, params: CodeActionParams): MaybePromise<Array<Command | CodeAction>>;
private createCodeActions;
/**
* Adds missing returns for parser rule
*/
private fixMissingReturns;
private fixInvalidReturnsInfers;
private fixMissingInfer;
private fixMissingCrossRefTerminal;
private fixSuperfluousInfer;
private isRuleReplaceable;
private replaceRule;
private isDefinitionReplaceable;
private replaceDefinition;
private replaceParserRuleByTypeDeclaration;
private fixUnnecessaryFileExtension;
private makeUpperCase;
private addEntryKeyword;
private fixRegexTokens;
private fixCrossRefSyntax;
private addNewRule;
private lookInGlobalScope;
}
//# sourceMappingURL=grammar-code-actions.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-code-actions.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-code-actions.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAIhF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAC;AACvE,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAY,MAAM,6BAA6B,CAAC;AACjF,OAAO,KAAK,GAAG,MAAM,kCAAkC,CAAC;AACxD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AACnE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,aAAa,EAA4B,MAAM,sBAAsB,CAAC;AAGpF,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAOjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AACpE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAGrE,qBAAa,gCAAiC,YAAW,kBAAkB;IAEvE,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC;IAC7C,SAAS,CAAC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;gBAElC,QAAQ,EAAE,eAAe;IAKrC,cAAc,CAAC,QAAQ,EAAE,eAAe,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,MAAM,EAAE,gBAAgB,GAAG,YAAY,CAAC,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC,CAAC;IAS3H,OAAO,CAAC,iBAAiB;IAmDzB;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAoBzB,OAAO,CAAC,uBAAuB;IAqB/B,OAAO,CAAC,eAAe;IAuBvB,OAAO,CAAC,0BAA0B;IAwBlC,OAAO,CAAC,mBAAmB;IAoB3B,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,uBAAuB;IAS/B,OAAO,CAAC,iBAAiB;IAUzB,OAAO,CAAC,kCAAkC;IA8B1C,OAAO,CAAC,2BAA2B;IAwBnC,OAAO,CAAC,aAAa;IAwBrB,OAAO,CAAC,eAAe;IAiBvB,OAAO,CAAC,cAAc;IA4BtB,OAAO,CAAC,iBAAiB;IAiBzB,OAAO,CAAC,UAAU;IA6BlB,OAAO,CAAC,iBAAiB;CA0E5B"}
+458
View File
@@ -0,0 +1,458 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { CodeActionKind } from 'vscode-languageserver';
import * as ast from '../../languages/generated/ast.js';
import { getContainerOfType } from '../../utils/ast-utils.js';
import { findLeafNodeAtOffset } from '../../utils/cst-utils.js';
import { escapeRegExp } from '../../utils/regexp-utils.js';
import { UriUtils } from '../../utils/uri-utils.js';
import { DocumentValidator } from '../../validation/document-validator.js';
import { IssueCodes } from '../validation/validator.js';
export class LangiumGrammarCodeActionProvider {
constructor(services) {
this.reflection = services.shared.AstReflection;
this.indexManager = services.shared.workspace.IndexManager;
}
getCodeActions(document, params) {
const result = [];
const acceptor = (ca) => ca && result.push(ca);
for (const diagnostic of params.context.diagnostics) {
this.createCodeActions(diagnostic, document, acceptor);
}
return result;
}
createCodeActions(diagnostic, document, accept) {
switch (diagnostic.data?.code) {
case IssueCodes.GrammarNameUppercase:
case IssueCodes.RuleNameUppercase:
accept(this.makeUpperCase(diagnostic, document));
break;
case IssueCodes.UseRegexTokens:
accept(this.fixRegexTokens(diagnostic, document));
break;
case IssueCodes.EntryRuleTokenSyntax:
accept(this.addEntryKeyword(diagnostic, document));
break;
case IssueCodes.CrossRefTokenSyntax:
accept(this.fixCrossRefSyntax(diagnostic, document));
break;
case IssueCodes.ParserRuleToTypeDecl:
accept(this.replaceParserRuleByTypeDeclaration(diagnostic, document));
break;
case IssueCodes.UnnecessaryFileExtension:
accept(this.fixUnnecessaryFileExtension(diagnostic, document));
break;
case IssueCodes.MissingReturns:
accept(this.fixMissingReturns(diagnostic, document));
break;
case IssueCodes.InvalidInfers:
case IssueCodes.InvalidReturns:
accept(this.fixInvalidReturnsInfers(diagnostic, document));
break;
case IssueCodes.MissingInfer:
accept(this.fixMissingInfer(diagnostic, document));
break;
case IssueCodes.MissingCrossRefTerminal:
accept(this.fixMissingCrossRefTerminal(diagnostic, document));
break;
case IssueCodes.SuperfluousInfer:
accept(this.fixSuperfluousInfer(diagnostic, document));
break;
case DocumentValidator.LinkingError: {
const data = diagnostic.data;
if (data && data.containerType === 'RuleCall' && data.property === 'rule') {
accept(this.addNewRule(diagnostic, data, document));
}
if (data) {
this.lookInGlobalScope(diagnostic, data, document).forEach(accept);
}
break;
}
}
return undefined;
}
/**
* Adds missing returns for parser rule
*/
fixMissingReturns(diagnostic, document) {
const text = document.textDocument.getText(diagnostic.range);
if (text) {
return {
title: `Add explicit return type for parser rule ${text}`,
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
edit: {
changes: {
[document.textDocument.uri]: [{
range: diagnostic.range,
newText: `${text} returns ${text}` // suggestion adds missing 'return'
}]
}
}
};
}
return undefined;
}
fixInvalidReturnsInfers(diagnostic, document) {
const data = diagnostic.data;
if (data && data.actionSegment) {
const text = document.textDocument.getText(data.actionSegment.range);
return {
title: `Correct ${text} usage`,
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
edit: {
changes: {
[document.textDocument.uri]: [{
range: data.actionSegment.range,
newText: text === 'infers' ? 'returns' : 'infers'
}]
}
}
};
}
return undefined;
}
fixMissingInfer(diagnostic, document) {
const data = diagnostic.data;
if (data && data.actionSegment) {
return {
title: "Correct 'infer' usage",
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
edit: {
changes: {
[document.textDocument.uri]: [{
range: {
start: data.actionSegment.range.end,
end: data.actionSegment.range.end
},
newText: 'infer '
}]
}
}
};
}
return undefined;
}
fixMissingCrossRefTerminal(diagnostic, document) {
const grammar = document.parseResult.value;
const idTerminal = grammar.rules.find(rule => ast.isTerminalRule(rule) && rule.name === 'ID');
if (idTerminal) {
return {
title: 'Use ID token to resolve cross-reference',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
edit: {
changes: {
[document.textDocument.uri]: [{
range: {
start: diagnostic.range.end,
end: diagnostic.range.end
},
newText: ':ID'
}]
}
}
};
}
return undefined;
}
fixSuperfluousInfer(diagnostic, document) {
const data = diagnostic.data;
if (data && data.actionRange) {
return {
title: "Remove the 'infer' keyword",
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
edit: {
changes: {
[document.textDocument.uri]: [{
range: data.actionRange,
newText: ''
}]
}
}
};
}
return undefined;
}
isRuleReplaceable(rule) {
/** at the moment, only "pure" parser rules are supported:
* - supported are only Alternatives (recursively) and "infers"
* - "returns" is not relevant, since cross-references would not refer to the parser rule, but to its "return type" instead
*/
return !rule.fragment && !rule.entry && rule.parameters.length === 0 && !rule.returnType && !rule.dataType;
}
replaceRule(rule) {
const type = rule.inferredType ?? rule;
return type.name;
}
isDefinitionReplaceable(node) {
if (ast.isRuleCall(node)) {
return node.arguments.length === 0 && ast.isParserRule(node.rule.ref) && this.isRuleReplaceable(node.rule.ref);
}
if (ast.isAlternatives(node)) {
return node.elements.every(child => this.isDefinitionReplaceable(child));
}
return false;
}
replaceDefinition(node) {
if (ast.isRuleCall(node) && node.rule.ref) {
return node.rule.ref.name;
}
if (ast.isAlternatives(node)) {
return node.elements.map(child => this.replaceDefinition(child)).join(' | ');
}
throw new Error('missing code for ' + node);
}
replaceParserRuleByTypeDeclaration(diagnostic, document) {
const rootCst = document.parseResult.value.$cstNode;
if (rootCst) {
const offset = document.textDocument.offsetAt(diagnostic.range.start);
const cstNode = findLeafNodeAtOffset(rootCst, offset);
const rule = getContainerOfType(cstNode?.astNode, ast.isParserRule);
if (rule && rule.$cstNode) {
const isReplaceable = this.isRuleReplaceable(rule) && this.isDefinitionReplaceable(rule.definition);
if (isReplaceable) {
const newText = `type ${this.replaceRule(rule)} = ${this.replaceDefinition(rule.definition)};`;
return {
title: 'Replace with type declaration',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range: diagnostic.range,
newText
}]
}
}
};
}
}
}
return undefined;
}
fixUnnecessaryFileExtension(diagnostic, document) {
const end = { ...diagnostic.range.end };
end.character -= 1;
const start = { ...end };
start.character -= '.langium'.length;
return {
title: 'Remove file extension',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range: {
start,
end
},
newText: ''
}]
}
}
};
}
makeUpperCase(diagnostic, document) {
const range = {
start: diagnostic.range.start,
end: {
line: diagnostic.range.start.line,
character: diagnostic.range.start.character + 1
}
};
return {
title: 'First letter to upper case',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range,
newText: document.textDocument.getText(range).toUpperCase()
}]
}
}
};
}
addEntryKeyword(diagnostic, document) {
return {
title: 'Add entry keyword',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range: { start: diagnostic.range.start, end: diagnostic.range.start },
newText: 'entry '
}]
}
}
};
}
fixRegexTokens(diagnostic, document) {
const offset = document.textDocument.offsetAt(diagnostic.range.start);
const rootCst = document.parseResult.value.$cstNode;
if (rootCst) {
const cstNode = findLeafNodeAtOffset(rootCst, offset);
const container = getContainerOfType(cstNode?.astNode, ast.isCharacterRange);
if (container && container.right && container.$cstNode) {
const left = container.left.value;
const right = container.right.value;
return {
title: 'Refactor into regular expression',
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range: container.$cstNode.range,
newText: `/[${escapeRegExp(left)}-${escapeRegExp(right)}]/`
}]
}
}
};
}
}
return undefined;
}
fixCrossRefSyntax(diagnostic, document) {
return {
title: "Replace '|' with ':'",
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: true,
edit: {
changes: {
[document.textDocument.uri]: [{
range: diagnostic.range,
newText: ':'
}]
}
}
};
}
addNewRule(diagnostic, data, document) {
const offset = document.textDocument.offsetAt(diagnostic.range.start);
const rootCst = document.parseResult.value.$cstNode;
if (rootCst) {
const cstNode = findLeafNodeAtOffset(rootCst, offset);
const container = getContainerOfType(cstNode?.astNode, ast.isParserRule);
if (container && container.$cstNode) {
return {
title: `Add new rule '${data.refText}'`,
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: false,
edit: {
changes: {
[document.textDocument.uri]: [{
range: {
start: container.$cstNode.range.end,
end: container.$cstNode.range.end
},
newText: '\n\n' + data.refText + ':\n /* TODO implement rule */ {infer ' + data.refText + '};'
}]
}
}
};
}
}
return undefined;
}
lookInGlobalScope(diagnostic, data, document) {
const refInfo = {
container: {
$type: data.containerType
},
property: data.property,
reference: {
$refText: data.refText
}
};
const referenceType = this.reflection.getReferenceType(refInfo);
const candidates = this.indexManager.allElements(referenceType).filter(e => e.name === data.refText);
const result = [];
let shortestPathIndex = -1;
let shortestPathLength = -1;
for (const candidate of candidates) {
if (UriUtils.equals(candidate.documentUri, document.uri)) {
continue;
}
// Find an import path and a position to insert the import
const importPath = getRelativeImport(document.uri, candidate.documentUri);
let position;
let suffix = '';
const grammar = document.parseResult.value;
const nextImport = grammar.imports.find(imp => imp.path && importPath < imp.path);
if (nextImport) {
// Insert the new import alphabetically
position = nextImport.$cstNode?.range.start;
}
else if (grammar.imports.length > 0) {
// Put the new import after the last import
const rangeEnd = grammar.imports[grammar.imports.length - 1].$cstNode.range.end;
if (rangeEnd) {
position = { line: rangeEnd.line + 1, character: 0 };
}
}
else if (grammar.rules.length > 0) {
// Put the new import before the first rule
position = grammar.rules[0].$cstNode?.range.start;
suffix = '\n';
}
if (position) {
if (shortestPathIndex < 0 || importPath.length < shortestPathLength) {
shortestPathIndex = result.length;
shortestPathLength = importPath.length;
}
// Add an import declaration for the candidate in the global scope
result.push({
title: `Add import to '${importPath}'`,
kind: CodeActionKind.QuickFix,
diagnostics: [diagnostic],
isPreferred: false,
edit: {
changes: {
[document.textDocument.uri]: [{
range: {
start: position,
end: position
},
newText: `import '${importPath}'\n${suffix}`
}]
}
}
});
}
}
// Mark the code action with the shortest import path as preferred
if (shortestPathIndex >= 0) {
result[shortestPathIndex].isPreferred = true;
}
return result;
}
}
function getRelativeImport(source, target) {
const sourceDir = UriUtils.dirname(source);
let relativePath = UriUtils.relative(sourceDir, target);
if (!relativePath.startsWith('./') && !relativePath.startsWith('../')) {
relativePath = './' + relativePath;
}
if (relativePath.endsWith('.langium')) {
relativePath = relativePath.substring(0, relativePath.length - '.langium'.length);
}
return relativePath;
}
//# sourceMappingURL=grammar-code-actions.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,18 @@
/******************************************************************************
* Copyright 2023 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { NextFeature } from '../../lsp/completion/follow-element-computation.js';
import { DefaultCompletionProvider, type CompletionAcceptor, type CompletionContext } from '../../lsp/completion/completion-provider.js';
import type { MaybePromise } from '../../utils/promise-utils.js';
import type { AbstractElement } from '../../languages/generated/ast.js';
import type { LangiumServices } from '../../lsp/lsp-services.js';
export declare class LangiumGrammarCompletionProvider extends DefaultCompletionProvider {
private readonly documents;
constructor(services: LangiumServices);
protected completionFor(context: CompletionContext, next: NextFeature<AbstractElement>, acceptor: CompletionAcceptor): MaybePromise<void>;
private completeImportPath;
private getAllFiles;
}
//# sourceMappingURL=grammar-completion-provider.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-completion-provider.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-completion-provider.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAIhF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oDAAoD,CAAC;AACtF,OAAO,EAAE,yBAAyB,EAAE,KAAK,kBAAkB,EAAE,KAAK,iBAAiB,EAAE,MAAM,6CAA6C,CAAC;AACzI,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AAGjE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAGxE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAEjE,qBAAa,gCAAiC,SAAQ,yBAAyB;IAE3E,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAyB;gBAEvC,QAAQ,EAAE,eAAe;cAKlB,aAAa,CAAC,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,WAAW,CAAC,eAAe,CAAC,EAAE,QAAQ,EAAE,kBAAkB,GAAG,YAAY,CAAC,IAAI,CAAC;IASlJ,OAAO,CAAC,kBAAkB;IAmC1B,OAAO,CAAC,WAAW;CAmBtB"}
@@ -0,0 +1,78 @@
/******************************************************************************
* Copyright 2023 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { CompletionItemKind } from 'vscode-languageserver-types';
import { DefaultCompletionProvider } from '../../lsp/completion/completion-provider.js';
import { getContainerOfType } from '../../utils/ast-utils.js';
import { isAssignment } from '../../languages/generated/ast.js';
import { UriUtils } from '../../utils/uri-utils.js';
export class LangiumGrammarCompletionProvider extends DefaultCompletionProvider {
constructor(services) {
super(services);
this.documents = () => services.shared.workspace.LangiumDocuments;
}
completionFor(context, next, acceptor) {
const assignment = getContainerOfType(next.feature, isAssignment);
if (assignment?.feature === 'path') {
this.completeImportPath(context, acceptor);
}
else {
return super.completionFor(context, next, acceptor);
}
}
completeImportPath(context, acceptor) {
const text = context.textDocument.getText();
const existingText = text.substring(context.tokenOffset, context.offset);
let allPaths = this.getAllFiles(context.document);
let range = {
start: context.position,
end: context.position
};
if (existingText.length > 0) {
const existingPath = existingText.substring(1);
allPaths = allPaths.filter(path => path.startsWith(existingPath));
// Completely replace the current token
const start = context.textDocument.positionAt(context.tokenOffset + 1);
const end = context.textDocument.positionAt(context.tokenEndOffset - 1);
range = {
start,
end
};
}
for (const path of allPaths) {
// Only insert quotes if there is no `path` token yet.
const delimiter = existingText.length > 0 ? '' : '"';
const completionValue = `${delimiter}${path}${delimiter}`;
acceptor(context, {
label: path,
textEdit: {
newText: completionValue,
range
},
kind: CompletionItemKind.File,
sortText: '0'
});
}
}
getAllFiles(document) {
const documents = this.documents().all;
const uri = document.uri.toString();
const dirname = UriUtils.dirname(document.uri).toString();
const paths = [];
for (const doc of documents) {
if (!UriUtils.equals(doc.uri, uri)) {
const docUri = doc.uri.toString();
const uriWithoutExt = docUri.substring(0, docUri.length - UriUtils.extname(doc.uri).length);
let relativePath = UriUtils.relative(dirname, uriWithoutExt);
if (!relativePath.startsWith('.')) {
relativePath = `./${relativePath}`;
}
paths.push(relativePath);
}
}
return paths;
}
}
//# sourceMappingURL=grammar-completion-provider.js.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-completion-provider.js","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-completion-provider.ts"],"names":[],"mappings":"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"}
+20
View File
@@ -0,0 +1,20 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { DefinitionParams } from 'vscode-languageserver';
import type { LangiumServices } from '../../lsp/lsp-services.js';
import type { AstNode, LeafCstNode } from '../../syntax-tree.js';
import type { MaybePromise } from '../../utils/promise-utils.js';
import type { LangiumDocuments } from '../../workspace/documents.js';
import type { Grammar } from '../../languages/generated/ast.js';
import { LocationLink } from 'vscode-languageserver';
import { DefaultDefinitionProvider } from '../../lsp/index.js';
export declare class LangiumGrammarDefinitionProvider extends DefaultDefinitionProvider {
protected documents: LangiumDocuments;
constructor(services: LangiumServices);
protected collectLocationLinks(sourceCstNode: LeafCstNode, _params: DefinitionParams): MaybePromise<LocationLink[] | undefined>;
protected findTargetObject(importedGrammar: Grammar): AstNode | undefined;
}
//# sourceMappingURL=grammar-definition.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-definition.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-definition.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AACjE,OAAO,KAAK,EAAE,OAAO,EAAE,WAAW,EAAc,MAAM,sBAAsB,CAAC;AAC7E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,8BAA8B,CAAC;AACjE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,8BAA8B,CAAC;AACrE,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,kCAAkC,CAAC;AAC/E,OAAO,EAAE,YAAY,EAAS,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAM/D,qBAAa,gCAAiC,SAAQ,yBAAyB;IAE3E,SAAS,CAAC,SAAS,EAAE,gBAAgB,CAAC;gBAE1B,QAAQ,EAAE,eAAe;cAKlB,oBAAoB,CAAC,aAAa,EAAE,WAAW,EAAE,OAAO,EAAE,gBAAgB,GAAG,YAAY,CAAC,YAAY,EAAE,GAAG,SAAS,CAAC;IAsBxI,SAAS,CAAC,gBAAgB,CAAC,eAAe,EAAE,OAAO,GAAG,OAAO,GAAG,SAAS;CAO5E"}
+41
View File
@@ -0,0 +1,41 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { LocationLink, Range } from 'vscode-languageserver';
import { DefaultDefinitionProvider } from '../../lsp/index.js';
import { streamContents } from '../../utils/ast-utils.js';
import { findAssignment } from '../../utils/grammar-utils.js';
import { isGrammarImport } from '../../languages/generated/ast.js';
import { resolveImport } from '../internal-grammar-util.js';
export class LangiumGrammarDefinitionProvider extends DefaultDefinitionProvider {
constructor(services) {
super(services);
this.documents = services.shared.workspace.LangiumDocuments;
}
collectLocationLinks(sourceCstNode, _params) {
const pathFeature = 'path';
if (isGrammarImport(sourceCstNode.astNode) && findAssignment(sourceCstNode)?.feature === pathFeature) {
const importedGrammar = resolveImport(this.documents, sourceCstNode.astNode);
if (importedGrammar?.$document) {
const targetObject = this.findTargetObject(importedGrammar) ?? importedGrammar;
const selectionRange = this.nameProvider.getNameNode(targetObject)?.range ?? Range.create(0, 0, 0, 0);
const previewRange = targetObject.$cstNode?.range ?? Range.create(0, 0, 0, 0);
return [
LocationLink.create(importedGrammar.$document.uri.toString(), previewRange, selectionRange, sourceCstNode.range)
];
}
return undefined;
}
return super.collectLocationLinks(sourceCstNode, _params);
}
findTargetObject(importedGrammar) {
// Jump to grammar name or the first element
if (importedGrammar.isDeclared) {
return importedGrammar;
}
return streamContents(importedGrammar).head();
}
}
//# sourceMappingURL=grammar-definition.js.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-definition.js","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-definition.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAQhF,OAAO,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC5D,OAAO,EAAE,yBAAyB,EAAE,MAAM,oBAAoB,CAAC;AAC/D,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AACnE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAE5D,MAAM,OAAO,gCAAiC,SAAQ,yBAAyB;IAI3E,YAAY,QAAyB;QACjC,KAAK,CAAC,QAAQ,CAAC,CAAC;QAChB,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC;IAChE,CAAC;IAEkB,oBAAoB,CAAC,aAA0B,EAAE,OAAyB;QACzF,MAAM,WAAW,GAA8B,MAAM,CAAC;QACtD,IAAI,eAAe,CAAC,aAAa,CAAC,OAAO,CAAC,IAAI,cAAc,CAAC,aAAa,CAAC,EAAE,OAAO,KAAK,WAAW,EAAE,CAAC;YACnG,MAAM,eAAe,GAAG,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;YAC7E,IAAI,eAAe,EAAE,SAAS,EAAE,CAAC;gBAC7B,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,eAAe,CAAC,IAAI,eAAe,CAAC;gBAC/E,MAAM,cAAc,GAAG,IAAI,CAAC,YAAY,CAAC,WAAW,CAAC,YAAY,CAAC,EAAE,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBACtG,MAAM,YAAY,GAAG,YAAY,CAAC,QAAQ,EAAE,KAAK,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC9E,OAAO;oBACH,YAAY,CAAC,MAAM,CACf,eAAe,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,EAAE,EACxC,YAAY,EACZ,cAAc,EACd,aAAa,CAAC,KAAK,CACtB;iBACJ,CAAC;YACN,CAAC;YACD,OAAO,SAAS,CAAC;QACrB,CAAC;QACD,OAAO,KAAK,CAAC,oBAAoB,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;IAC9D,CAAC;IAES,gBAAgB,CAAC,eAAwB;QAC/C,4CAA4C;QAC5C,IAAI,eAAe,CAAC,UAAU,EAAE,CAAC;YAC7B,OAAO,eAAe,CAAC;QAC3B,CAAC;QACD,OAAO,cAAc,CAAC,eAAe,CAAC,CAAC,IAAI,EAAE,CAAC;IAClD,CAAC;CACJ"}
@@ -0,0 +1,14 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { AstNode } from '../../syntax-tree.js';
import { DefaultFoldingRangeProvider } from '../../lsp/folding-range-provider.js';
/**
* A specialized folding range provider for the grammar language
*/
export declare class LangiumGrammarFoldingRangeProvider extends DefaultFoldingRangeProvider {
shouldProcessContent(node: AstNode): boolean;
}
//# sourceMappingURL=grammar-folding-ranges.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-folding-ranges.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-folding-ranges.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAGlF;;GAEG;AACH,qBAAa,kCAAmC,SAAQ,2BAA2B;IAEtE,oBAAoB,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO;CAIxD"}
+17
View File
@@ -0,0 +1,17 @@
/******************************************************************************
* Copyright 2021 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { DefaultFoldingRangeProvider } from '../../lsp/folding-range-provider.js';
import { isParserRule } from '../../languages/generated/ast.js';
/**
* A specialized folding range provider for the grammar language
*/
export class LangiumGrammarFoldingRangeProvider extends DefaultFoldingRangeProvider {
shouldProcessContent(node) {
// Exclude parser rules from folding
return !isParserRule(node);
}
}
//# sourceMappingURL=grammar-folding-ranges.js.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-folding-ranges.js","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-folding-ranges.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAGhF,OAAO,EAAE,2BAA2B,EAAE,MAAM,qCAAqC,CAAC;AAClF,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAEhE;;GAEG;AACH,MAAM,OAAO,kCAAmC,SAAQ,2BAA2B;IAEtE,oBAAoB,CAAC,IAAa;QACvC,oCAAoC;QACpC,OAAO,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;CACJ"}
+11
View File
@@ -0,0 +1,11 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { AstNode } from '../../syntax-tree.js';
import { AbstractFormatter } from '../../lsp/formatter.js';
export declare class LangiumGrammarFormatter extends AbstractFormatter {
protected format(node: AstNode): void;
}
//# sourceMappingURL=grammar-formatter.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-formatter.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-formatter.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAc,MAAM,wBAAwB,CAAC;AAKvE,qBAAa,uBAAwB,SAAQ,iBAAiB;IAE1D,SAAS,CAAC,MAAM,CAAC,IAAI,EAAE,OAAO,GAAG,IAAI;CA0FxC"}
+112
View File
@@ -0,0 +1,112 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { AbstractFormatter, Formatting } from '../../lsp/formatter.js';
import * as ast from '../../languages/generated/ast.js';
const indentOrSpace = Formatting.fit(Formatting.oneSpace(), Formatting.indent());
export class LangiumGrammarFormatter extends AbstractFormatter {
format(node) {
if (ast.isCrossReference(node)) {
const formatter = this.getNodeFormatter(node);
formatter.properties('type', 'terminal').surround(Formatting.noSpace());
}
else if (ast.isParserRule(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keywords('entry', 'fragment', 'returns').append(Formatting.oneSpace());
if ((node.inferredType || node.returnType || node.dataType) && node.parameters.length === 0) {
formatter.property('name').append(Formatting.oneSpace());
}
else {
formatter.property('name').append(Formatting.noSpace());
}
formatter.properties('parameters').append(Formatting.noSpace());
formatter.keywords(',').append(Formatting.oneSpace());
formatter.keywords('<').append(Formatting.noSpace());
const semicolon = formatter.keyword(';');
const colon = formatter.keyword(':');
colon.prepend(Formatting.noSpace());
formatter.interior(colon, semicolon).prepend(Formatting.indent());
semicolon.prepend(Formatting.fit(Formatting.noSpace(), Formatting.newLine()));
formatter.node(node).prepend(Formatting.noIndent());
}
else if (ast.isTerminalRule(node)) {
const formatter = this.getNodeFormatter(node);
if (node.type) {
formatter.property('name').append(Formatting.oneSpace());
formatter.keyword('returns').append(Formatting.oneSpace());
}
formatter.keywords('hidden', 'terminal', 'fragment').append(Formatting.oneSpace());
formatter.keyword(':').prepend(Formatting.noSpace());
formatter.keyword(';').prepend(Formatting.fit(Formatting.noSpace(), Formatting.newLine()));
formatter.node(node).prepend(Formatting.noIndent());
}
else if (ast.isAction(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keyword('{').append(Formatting.noSpace());
formatter.keywords('.', '+=', '=').surround(Formatting.noSpace());
formatter.keyword('}').prepend(Formatting.noSpace());
}
else if (ast.isInferredType(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keywords('infer', 'infers').append(Formatting.oneSpace());
}
else if (ast.isAssignment(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keywords('=', '+=', '?=').surround(Formatting.noSpace());
}
else if (ast.isRuleCall(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keyword('<').surround(Formatting.noSpace());
formatter.keyword(',').append(Formatting.oneSpace());
formatter.properties('arguments').append(Formatting.noSpace());
}
else if (ast.isInterface(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keyword('interface').append(Formatting.oneSpace());
formatter.keyword('extends').prepend(Formatting.oneSpace()).append(indentOrSpace);
formatter.keywords(',').prepend(Formatting.noSpace()).append(indentOrSpace);
const bracesOpen = formatter.keyword('{');
bracesOpen.prepend(Formatting.fit(Formatting.oneSpace(), Formatting.newLine()));
const bracesClose = formatter.keyword('}');
bracesClose.prepend(Formatting.newLine());
formatter.interior(bracesOpen, bracesClose).prepend(Formatting.indent());
}
else if (ast.isType(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keyword('type').append(Formatting.oneSpace());
formatter.keyword('=').prepend(Formatting.oneSpace()).append(indentOrSpace);
formatter.keyword(';').prepend(Formatting.noSpace()).append(Formatting.newLine());
}
else if (ast.isGrammar(node)) {
const formatter = this.getNodeFormatter(node);
const nodes = formatter.nodes(...node.rules, ...node.interfaces, ...node.types, ...node.imports);
nodes.prepend(Formatting.noIndent());
formatter.keyword('grammar').prepend(Formatting.noSpace()).append(Formatting.oneSpace());
}
else if (ast.isInfixRuleOperatorList(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keywords('left', 'right').append(Formatting.oneSpace());
formatter.keywords('|').surround(Formatting.oneSpace());
}
else if (ast.isInfixRuleOperators(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keywords('>').prepend(Formatting.newLine());
}
else if (ast.isInfixRule(node)) {
const formatter = this.getNodeFormatter(node);
formatter.keyword('infix').append(Formatting.oneSpace());
formatter.keyword('on').append(Formatting.oneSpace());
const semicolon = formatter.keyword(';');
const colon = formatter.keyword(':');
colon.prepend(Formatting.noSpace());
formatter.interior(colon, semicolon).prepend(Formatting.indent());
}
if (ast.isAbstractElement(node)) {
const formatter = this.getNodeFormatter(node);
formatter.property('cardinality').prepend(Formatting.noSpace());
}
}
}
//# sourceMappingURL=grammar-formatter.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,12 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { AstNode } from '../../syntax-tree.js';
import type { SemanticTokenAcceptor } from '../../lsp/semantic-token-provider.js';
import { AbstractSemanticTokenProvider } from '../../lsp/semantic-token-provider.js';
export declare class LangiumGrammarSemanticTokenProvider extends AbstractSemanticTokenProvider {
protected highlightElement(node: AstNode, acceptor: SemanticTokenAcceptor): void;
}
//# sourceMappingURL=grammar-semantic-tokens.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-semantic-tokens.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-semantic-tokens.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,sCAAsC,CAAC;AAElF,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AAGrF,qBAAa,mCAAoC,SAAQ,6BAA6B;IAElF,SAAS,CAAC,gBAAgB,CAAC,IAAI,EAAE,OAAO,EAAE,QAAQ,EAAE,qBAAqB,GAAG,IAAI;CA0DnF"}
+75
View File
@@ -0,0 +1,75 @@
/******************************************************************************
* Copyright 2022 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { SemanticTokenTypes } from 'vscode-languageserver';
import { AbstractSemanticTokenProvider } from '../../lsp/semantic-token-provider.js';
import { isAction, isAssignment, isInfixRule, isParameter, isParameterReference, isReturnType, isRuleCall, isSimpleType, isTypeAttribute } from '../../languages/generated/ast.js';
export class LangiumGrammarSemanticTokenProvider extends AbstractSemanticTokenProvider {
highlightElement(node, acceptor) {
if (isAssignment(node)) {
acceptor({
node,
property: 'feature',
type: SemanticTokenTypes.property
});
}
else if (isAction(node)) {
if (node.feature) {
acceptor({
node,
property: 'feature',
type: SemanticTokenTypes.property
});
}
}
else if (isReturnType(node)) {
acceptor({
node,
property: 'name',
type: SemanticTokenTypes.type
});
}
else if (isSimpleType(node)) {
if (node.primitiveType || node.typeRef) {
acceptor({
node,
property: node.primitiveType ? 'primitiveType' : 'typeRef',
type: SemanticTokenTypes.type
});
}
}
else if (isParameter(node)) {
acceptor({
node,
property: 'name',
type: SemanticTokenTypes.parameter
});
}
else if (isParameterReference(node)) {
acceptor({
node,
property: 'parameter',
type: SemanticTokenTypes.parameter
});
}
else if (isRuleCall(node)) {
if (!isInfixRule(node.rule.ref) && node.rule.ref?.fragment) {
acceptor({
node,
property: 'rule',
type: SemanticTokenTypes.type
});
}
}
else if (isTypeAttribute(node)) {
acceptor({
node,
property: 'name',
type: SemanticTokenTypes.property
});
}
}
}
//# sourceMappingURL=grammar-semantic-tokens.js.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-semantic-tokens.js","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-semantic-tokens.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAIhF,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,oBAAoB,EAAE,YAAY,EAAE,UAAU,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,kCAAkC,CAAC;AAEnL,MAAM,OAAO,mCAAoC,SAAQ,6BAA6B;IAExE,gBAAgB,CAAC,IAAa,EAAE,QAA+B;QACrE,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,QAAQ,CAAC;gBACL,IAAI;gBACJ,QAAQ,EAAE,SAAS;gBACnB,IAAI,EAAE,kBAAkB,CAAC,QAAQ;aACpC,CAAC,CAAC;QACP,CAAC;aAAM,IAAI,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;YACxB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACf,QAAQ,CAAC;oBACL,IAAI;oBACJ,QAAQ,EAAE,SAAS;oBACnB,IAAI,EAAE,kBAAkB,CAAC,QAAQ;iBACpC,CAAC,CAAC;YACP,CAAC;QACL,CAAC;aAAM,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,QAAQ,CAAC;gBACL,IAAI;gBACJ,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,kBAAkB,CAAC,IAAI;aAChC,CAAC,CAAC;QACP,CAAC;aAAM,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,aAAa,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;gBACrC,QAAQ,CAAC;oBACL,IAAI;oBACJ,QAAQ,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS;oBAC1D,IAAI,EAAE,kBAAkB,CAAC,IAAI;iBAChC,CAAC,CAAC;YACP,CAAC;QACL,CAAC;aAAM,IAAI,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YAC3B,QAAQ,CAAC;gBACL,IAAI;gBACJ,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,kBAAkB,CAAC,SAAS;aACrC,CAAC,CAAC;QACP,CAAC;aAAM,IAAI,oBAAoB,CAAC,IAAI,CAAC,EAAE,CAAC;YACpC,QAAQ,CAAC;gBACL,IAAI;gBACJ,QAAQ,EAAE,WAAW;gBACrB,IAAI,EAAE,kBAAkB,CAAC,SAAS;aACrC,CAAC,CAAC;QACP,CAAC;aAAM,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;YAC1B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,CAAC;gBACzD,QAAQ,CAAC;oBACL,IAAI;oBACJ,QAAQ,EAAE,MAAM;oBAChB,IAAI,EAAE,kBAAkB,CAAC,IAAI;iBAChC,CAAC,CAAC;YACP,CAAC;QACL,CAAC;aAAM,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;YAC/B,QAAQ,CAAC;gBACL,IAAI;gBACJ,QAAQ,EAAE,MAAM;gBAChB,IAAI,EAAE,kBAAkB,CAAC,QAAQ;aACpC,CAAC,CAAC;QACP,CAAC;IACL,CAAC;CAEJ"}
@@ -0,0 +1,13 @@
/******************************************************************************
* Copyright 2023 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { AstNode } from '../../syntax-tree.js';
import type { TypeHierarchyItem } from 'vscode-languageserver';
import { AbstractTypeHierarchyProvider } from '../../lsp/type-hierarchy-provider.js';
export declare class LangiumGrammarTypeHierarchyProvider extends AbstractTypeHierarchyProvider {
protected getSupertypes(node: AstNode): TypeHierarchyItem[] | undefined;
protected getSubtypes(node: AstNode): TypeHierarchyItem[] | undefined;
}
//# sourceMappingURL=grammar-type-hierarchy.d.ts.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-type-hierarchy.d.ts","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-type-hierarchy.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAEhF,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AAKrF,qBAAa,mCAAoC,SAAQ,6BAA6B;IAClF,SAAS,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,GAAG,iBAAiB,EAAE,GAAG,SAAS;IAiBvE,SAAS,CAAC,WAAW,CAAC,IAAI,EAAE,OAAO,GAAG,iBAAiB,EAAE,GAAG,SAAS;CAmCxE"}
+54
View File
@@ -0,0 +1,54 @@
/******************************************************************************
* Copyright 2023 TypeFox GmbH
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { AbstractTypeHierarchyProvider } from '../../lsp/type-hierarchy-provider.js';
import { getDocument } from '../../utils/ast-utils.js';
import { findLeafNodeAtOffset } from '../../utils/cst-utils.js';
import { isInterface } from '../../languages/generated/ast.js';
export class LangiumGrammarTypeHierarchyProvider extends AbstractTypeHierarchyProvider {
getSupertypes(node) {
if (!isInterface(node)) {
return undefined;
}
const items = node.superTypes.flatMap(superType => {
const ref = superType.ref;
if (!ref) {
return [];
}
return this.getTypeHierarchyItems(ref, getDocument(ref)) ?? [];
});
return items.length === 0 ? undefined : items;
}
getSubtypes(node) {
if (!isInterface(node)) {
return undefined;
}
const items = this.references
.findReferences(node, { includeDeclaration: false })
.flatMap(ref => {
const document = this.documents.getDocument(ref.sourceUri);
if (!document) {
return [];
}
const rootNode = document.parseResult.value;
if (!rootNode.$cstNode) {
return [];
}
const refCstNode = findLeafNodeAtOffset(rootNode.$cstNode, ref.segment.offset);
if (!refCstNode) {
return [];
}
// Only consider references that occur as a superType of an interface
const refNode = refCstNode.astNode;
if (!isInterface(refNode) || refNode.superTypes.every(superType => superType.$refNode !== refCstNode)) {
return [];
}
return this.getTypeHierarchyItems(refNode, document) ?? [];
})
.toArray();
return items.length === 0 ? undefined : items;
}
}
//# sourceMappingURL=grammar-type-hierarchy.js.map
@@ -0,0 +1 @@
{"version":3,"file":"grammar-type-hierarchy.js","sourceRoot":"","sources":["../../../src/grammar/lsp/grammar-type-hierarchy.ts"],"names":[],"mappings":"AAAA;;;;gFAIgF;AAIhF,OAAO,EAAE,6BAA6B,EAAE,MAAM,sCAAsC,CAAC;AACrF,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,kCAAkC,CAAC;AAE/D,MAAM,OAAO,mCAAoC,SAAQ,6BAA6B;IACxE,aAAa,CAAC,IAAa;QACjC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE;YAC9C,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,CAAC;YAC1B,IAAI,CAAC,GAAG,EAAE,CAAC;gBACP,OAAO,EAAE,CAAC;YACd,CAAC;YAED,OAAO,IAAI,CAAC,qBAAqB,CAAC,GAAG,EAAE,WAAW,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QACnE,CAAC,CAAC,CAAC;QAEH,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;IAClD,CAAC;IAES,WAAW,CAAC,IAAa;QAC/B,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;YACrB,OAAO,SAAS,CAAC;QACrB,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU;aACxB,cAAc,CAAC,IAAI,EAAE,EAAC,kBAAkB,EAAE,KAAK,EAAC,CAAC;aACjD,OAAO,CAAC,GAAG,CAAC,EAAE;YACX,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,WAAW,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YAC3D,IAAI,CAAC,QAAQ,EAAE,CAAC;gBACZ,OAAO,EAAE,CAAC;YACd,CAAC;YAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,KAAK,CAAC;YAC5C,IAAI,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;gBACrB,OAAO,EAAE,CAAC;YACd,CAAC;YAED,MAAM,UAAU,GAAG,oBAAoB,CAAC,QAAQ,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;YAC/E,IAAI,CAAC,UAAU,EAAE,CAAC;gBACd,OAAO,EAAE,CAAC;YACd,CAAC;YAED,qEAAqE;YACrE,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;YACnC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,UAAU,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,SAAS,CAAC,QAAQ,KAAK,UAAU,CAAC,EAAE,CAAC;gBACpG,OAAO,EAAE,CAAC;YACd,CAAC;YAED,OAAO,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC/D,CAAC,CAAC;aACD,OAAO,EAAE,CAAC;QAEf,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC;IAClD,CAAC;CACJ"}