Skip to content

Commit

Permalink
Wrapped utility functions in namespaces
Browse files Browse the repository at this point in the history
  • Loading branch information
spoenemann committed Dec 13, 2023
1 parent 79e4301 commit f0ed380
Show file tree
Hide file tree
Showing 105 changed files with 379 additions and 368 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import type { Range, WorkspaceEdit } from 'vscode-languageserver';
import type { RenameParams } from 'vscode-languageserver-protocol';
import type { DomainModelServices } from './domain-model-module.js';
import type { QualifiedNameProvider } from './domain-model-naming.js';
import { DefaultRenameProvider, findDeclarationNodeAtOffset, getDocument, isNamed, streamAst, toDocumentSegment } from 'langium';
import { AstUtils, CstUtils, DefaultRenameProvider, isNamed } from 'langium';
import { Location } from 'vscode-languageserver';
import { TextEdit } from 'vscode-languageserver-types';
import { isPackageDeclaration } from './generated/ast.js';
Expand All @@ -30,7 +30,7 @@ export class DomainModelRenameProvider extends DefaultRenameProvider {
const rootNode = document.parseResult.value.$cstNode;
if (!rootNode) return undefined;
const offset = document.textDocument.offsetAt(params.position);
const leafNode = findDeclarationNodeAtOffset(rootNode, offset, this.grammarConfig.nameRegexp);
const leafNode = CstUtils.findDeclarationNodeAtOffset(rootNode, offset, this.grammarConfig.nameRegexp);
if (!leafNode) return undefined;
const targetNode = this.references.findDeclaration(leafNode);
if (!targetNode) return undefined;
Expand All @@ -48,7 +48,7 @@ export class DomainModelRenameProvider extends DefaultRenameProvider {
}
}

for (const node of streamAst(targetNode)) {
for (const node of AstUtils.streamAst(targetNode)) {
const qn = this.buildQualifiedName(node);
if (qn) {
const options = { onlyLocal: false, includeDeclaration: false };
Expand Down Expand Up @@ -85,10 +85,10 @@ export class DomainModelRenameProvider extends DefaultRenameProvider {
getNodeLocation(targetNode: AstNode): Location | undefined {
const nameNode = this.nameProvider.getNameNode(targetNode);
if (nameNode) {
const doc = getDocument(targetNode);
const doc = AstUtils.getDocument(targetNode);
return Location.create(
doc.uri.toString(),
toDocumentSegment(nameNode).range
CstUtils.toDocumentSegment(nameNode).range
);
}
return undefined;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { AstNode, AstNodeDescription, LangiumDocument, PrecomputedScopes }
import type { DomainModelServices } from './domain-model-module.js';
import type { QualifiedNameProvider } from './domain-model-naming.js';
import type { Domainmodel, PackageDeclaration } from './generated/ast.js';
import { DefaultScopeComputation, interruptAndCheck, MultiMap, streamAllContents } from 'langium';
import { AstUtils, DefaultScopeComputation, interruptAndCheck, MultiMap } from 'langium';
import { CancellationToken } from 'vscode-jsonrpc';
import { isType, isPackageDeclaration } from './generated/ast.js';

Expand All @@ -26,7 +26,7 @@ export class DomainModelScopeComputation extends DefaultScopeComputation {
*/
override async computeExports(document: LangiumDocument, cancelToken = CancellationToken.None): Promise<AstNodeDescription[]> {
const descr: AstNodeDescription[] = [];
for (const modelNode of streamAllContents(document.parseResult.value)) {
for (const modelNode of AstUtils.streamAllContents(document.parseResult.value)) {
await interruptAndCheck(cancelToken);
if (isType(modelNode)) {
let name = this.nameProvider.getName(modelNode);
Expand Down
4 changes: 2 additions & 2 deletions examples/domainmodel/test/refs-index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import type { AstNode, LangiumDocument, ReferenceDescription, URI } from 'langium';
import type { Domainmodel } from '../src/language-server/generated/ast.js';
import { describe, expect, test } from 'vitest';
import { EmptyFileSystem, getDocument } from 'langium';
import { AstUtils, EmptyFileSystem } from 'langium';
import { parseDocument, setTextDocument } from 'langium/test';
import { TextDocument } from 'vscode-languageserver-textdocument';
import { createDomainModelServices } from '../src/language-server/domain-model-module.js';
Expand Down Expand Up @@ -62,7 +62,7 @@ function refString(ref: ReferenceDescription): string {
}

function nodeRefString(from: AstNode, to: AstNode): string {
return asString(getDocument(from).uri, createPath(from), getDocument(to).uri, createPath(to));
return asString(AstUtils.getDocument(from).uri, createPath(from), AstUtils.getDocument(to).uri, createPath(to));
}

function createPath(node: AstNode): string {
Expand Down
12 changes: 6 additions & 6 deletions packages/langium-cli/src/generate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import type { AstNode, Grammar, LangiumDocument, Mutable } from 'langium';
import type { LangiumConfig, LangiumLanguageConfig} from './package.js';
import { URI } from 'langium';
import { loadConfig } from './package.js';
import { copyAstNode, getDocument, GrammarAST, linkContentToContainer } from 'langium';
import { AstUtils, GrammarAST } from 'langium';
import { createLangiumGrammarServices, resolveImport, resolveTransitiveImports } from 'langium/grammar';
import { NodeFileSystem } from 'langium/node';
import { generateAst } from './generator/ast-generator.js';
Expand Down Expand Up @@ -132,7 +132,7 @@ function eagerLoad(document: LangiumDocument, uris: Set<string> = new Set()): UR
for (const imp of grammar.imports) {
const importedGrammar = resolveImport(documents, imp);
if (importedGrammar) {
const importedDoc = getDocument(importedGrammar);
const importedDoc = AstUtils.getDocument(importedGrammar);
eagerLoad(importedDoc, uris);
}
}
Expand All @@ -148,7 +148,7 @@ function eagerLoad(document: LangiumDocument, uris: Set<string> = new Set()): UR
*/
function mapGrammarElements(grammars: Grammar[], visited: Set<string> = new Set(), map: Map<Grammar, GrammarElement[]> = new Map()): Map<Grammar, GrammarElement[]> {
for (const grammar of grammars) {
const doc = getDocument(grammar);
const doc = AstUtils.getDocument(grammar);
const uriString = doc.uri.toString();
if (!visited.has(uriString)) {
visited.add(uriString);
Expand All @@ -172,7 +172,7 @@ function embedReferencedGrammar(grammar: Grammar, map: Map<Grammar, GrammarEleme
for (const importedGrammar of allGrammars) {
const grammarElements = map.get(importedGrammar) ?? [];
for (const element of grammarElements) {
const copy = copyAstNode(element, buildReference);
const copy = AstUtils.copyAstNode(element, buildReference);
// Deactivate copied entry rule
if (GrammarAST.isParserRule(copy)) {
copy.entry = false;
Expand All @@ -194,7 +194,7 @@ function embedReferencedGrammar(grammar: Grammar, map: Map<Grammar, GrammarEleme
imports: []
};
// Link newly added elements to grammar
linkContentToContainer(grammarCopy);
AstUtils.linkContentToContainer(grammarCopy);
return grammarCopy;
}

Expand All @@ -211,7 +211,7 @@ async function relinkGrammars(grammars: Grammar[]): Promise<void> {
await documentBuilder.update([], documents.map(e => e.uri));
// Create and build new documents
const newDocuments = grammars.map(e => {
const uri = getDocument(e).uri;
const uri = AstUtils.getDocument(e).uri;
const newDoc = documentFactory.fromModel(e, uri);
(e as Mutable<AstNode>).$document = newDoc;
return newDoc;
Expand Down
4 changes: 2 additions & 2 deletions packages/langium-cli/src/generator/ast-generator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { Grammar, LangiumServices } from 'langium';
import { type Generated, expandToNode, joinToNode, toString } from 'langium/generate';
import type { AstTypes, Property, PropertyDefaultValue } from 'langium/grammar';
import type { LangiumConfig } from '../package.js';
import { streamAllContents, MultiMap, GrammarAST } from 'langium';
import { AstUtils, MultiMap, GrammarAST } from 'langium';
import { collectAst, collectTypeHierarchy, findReferenceTypes, isAstType, mergeTypesAndInterfaces } from 'langium/grammar';
import { collectTerminalRegexps, generatedHeader } from './util.js';

Expand Down Expand Up @@ -37,7 +37,7 @@ export function generateAst(services: LangiumServices, grammars: Grammar[], conf
}

function hasCrossReferences(grammar: Grammar): boolean {
return Boolean(streamAllContents(grammar).find(GrammarAST.isCrossReference));
return Boolean(AstUtils.streamAllContents(grammar).find(GrammarAST.isCrossReference));
}

function generateAstReflection(config: LangiumConfig, astTypes: AstTypes): Generated {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* terms of the MIT License, which is available in the project root.
******************************************************************************/

import { type Grammar, getTerminalParts, isCommentTerminal, escapeRegExp, GrammarAST, isWhitespaceRegExp, terminalRegex } from 'langium';
import { type Grammar, GrammarAST, GrammarUtils, RegExpUtils } from 'langium';
import { type Generated, expandToNode, joinToNode, toString } from 'langium/generate';
import type { LangiumLanguageConfig } from '../../package.js';
import { collectKeywords } from '../util.js';
Expand Down Expand Up @@ -225,7 +225,7 @@ function prettyPrintLangDef(languageDef: LanguageDefinition): Generated {
${genLanguageDefEntry('keywords', languageDef.keywords)}
${genLanguageDefEntry('operators', languageDef.operators)}
${/* special case, identify symbols via singular regex*/ undefined}
symbols: ${new RegExp(languageDef.symbols.map(escapeRegExp).join('|')).toString()},
symbols: ${new RegExp(languageDef.symbols.map(RegExpUtils.escapeRegExp).join('|')).toString()},
`;
}

Expand Down Expand Up @@ -315,20 +315,20 @@ function getWhitespaceRules(grammar: Grammar): Rule[] {
const rules: Rule[] = [];
for (const rule of grammar.rules) {
if (GrammarAST.isTerminalRule(rule)) {
const regex = terminalRegex(rule);
const regex = GrammarUtils.terminalRegex(rule);

if (!isCommentTerminal(rule) && !isWhitespaceRegExp(regex)) {
if (!GrammarUtils.isCommentTerminal(rule) && !RegExpUtils.isWhitespace(regex)) {
// skip rules that are not comments or whitespace
continue;
}

// token name is either comment or whitespace
const tokenName = isCommentTerminal(rule) ? 'comment' : 'white';
const tokenName = GrammarUtils.isCommentTerminal(rule) ? 'comment' : 'white';

const part = getTerminalParts(regex)[0];
const part = RegExpUtils.getTerminalParts(regex)[0];

// check if this is a comment terminal w/ a start & end sequence (multi-line)
if (part.start !== '' && part.end !== '' && isCommentTerminal(rule)) {
if (part.start !== '' && part.end !== '' && GrammarUtils.isCommentTerminal(rule)) {
// state-based comment rule, only add push to jump into it
rules.push({
regex: part.start,
Expand Down Expand Up @@ -356,9 +356,9 @@ function getWhitespaceRules(grammar: Grammar): Rule[] {
function getCommentRules(grammar: Grammar): Rule[] {
const rules: Rule[] = [];
for (const rule of grammar.rules) {
if (GrammarAST.isTerminalRule(rule) && isCommentTerminal(rule)) {
if (GrammarAST.isTerminalRule(rule) && GrammarUtils.isCommentTerminal(rule)) {
const tokenName = 'comment';
const part = getTerminalParts(terminalRegex(rule))[0];
const part = RegExpUtils.getTerminalParts(GrammarUtils.terminalRegex(rule))[0];
if (part.start !== '' && part.end !== '') {
// rules to manage comment start/end
// rule order matters
Expand Down Expand Up @@ -398,10 +398,10 @@ function getCommentRules(grammar: Grammar): Rule[] {
function getTerminalRules(grammar: Grammar): Rule[] {
const rules: Rule[] = [];
for (const rule of grammar.rules) {
if (GrammarAST.isTerminalRule(rule) && !isCommentTerminal(rule)) {
const regex = terminalRegex(rule);
if (GrammarAST.isTerminalRule(rule) && !GrammarUtils.isCommentTerminal(rule)) {
const regex = GrammarUtils.terminalRegex(rule);

if (isWhitespaceRegExp(regex)) {
if (RegExpUtils.isWhitespace(regex)) {
// disallow terminal rules that match whitespace
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { terminalRegex, GrammarAST, escapeRegExp, isCommentTerminal, type Grammar } from 'langium';
import { GrammarAST, type Grammar, GrammarUtils, RegExpUtils } from 'langium';
import { expandToNode, joinToNode, toString, type Generated } from 'langium/generate';
import _ from 'lodash';
import type { LangiumLanguageConfig } from '../../package.js';
Expand All @@ -23,26 +23,26 @@ export function generatePrismHighlighting(grammar: Grammar, config: LangiumLangu
const terminals = getTerminals(grammar);
const modifier = config.caseInsensitive ? 'i' : '';

const commentTerminals = terminals.filter(isCommentTerminal);
const commentTerminals = terminals.filter(GrammarUtils.isCommentTerminal);
if (commentTerminals.length === 1) {
highlighter.comment = {
pattern: terminalRegex(commentTerminals[0]).toString(),
pattern: GrammarUtils.terminalRegex(commentTerminals[0]).toString(),
greedy: true
};
} else if (commentTerminals.length > 0) {
highlighter.comment = commentTerminals.map(e => ({
pattern: terminalRegex(e).toString(),
pattern: GrammarUtils.terminalRegex(e).toString(),
greedy: true
}));
}
const stringTerminal = terminals.find(e => e.name.toLowerCase() === 'string');
if (stringTerminal) {
highlighter.string = {
pattern: terminalRegex(stringTerminal).toString(),
pattern: GrammarUtils.terminalRegex(stringTerminal).toString(),
greedy: true
};
}
const filteredKeywords = keywords.filter(e => idRegex.test(e)).sort((a, b) => b.length - a.length).map(escapeRegExp);
const filteredKeywords = keywords.filter(e => idRegex.test(e)).sort((a, b) => b.length - a.length).map(RegExpUtils.escapeRegExp);
highlighter.keyword = {
pattern: `/\\b(${filteredKeywords.join('|')})\\b/${modifier}`
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import type { Grammar } from 'langium';
import { escapeRegExp, getCaseInsensitivePattern, getTerminalParts, GrammarAST, isCommentTerminal, stream, terminalRegex } from 'langium';
import { GrammarAST, GrammarUtils, RegExpUtils, stream } from 'langium';
import type { LangiumLanguageConfig } from '../../package.js';
import { collectKeywords } from '../util.js';

Expand Down Expand Up @@ -74,8 +74,8 @@ function getRepository(grammar: Grammar, config: LangiumLanguageConfig): Reposit
const commentPatterns: Pattern[] = [];
let stringEscapePattern: Pattern | undefined;
for (const rule of grammar.rules) {
if (GrammarAST.isTerminalRule(rule) && isCommentTerminal(rule)) {
const parts = getTerminalParts(terminalRegex(rule));
if (GrammarAST.isTerminalRule(rule) && GrammarUtils.isCommentTerminal(rule)) {
const parts = RegExpUtils.getTerminalParts(GrammarUtils.terminalRegex(rule));
for (const part of parts) {
if (part.end) {
commentPatterns.push({
Expand Down Expand Up @@ -144,7 +144,7 @@ function groupKeywords(keywords: string[], caseInsensitive: boolean | undefined)
} = { letter: [], leftSpecial: [], rightSpecial: [], special: [] };

keywords.forEach(keyword => {
const keywordPattern = caseInsensitive ? getCaseInsensitivePattern(keyword) : escapeRegExp(keyword);
const keywordPattern = caseInsensitive ? RegExpUtils.getCaseInsensitivePattern(keyword) : RegExpUtils.escapeRegExp(keyword);
if (/\w/.test(keyword[0])) {
if (/\w/.test(keyword[keyword.length - 1])) {
groups.letter.push(keywordPattern);
Expand Down Expand Up @@ -173,7 +173,7 @@ function getStringPatterns(grammar: Grammar, pack: LangiumLanguageConfig): Patte
const stringTerminal = terminals.find(e => e.name.toLowerCase() === 'string');
const stringPatterns: Pattern[] = [];
if (stringTerminal) {
const parts = getTerminalParts(terminalRegex(stringTerminal));
const parts = RegExpUtils.getTerminalParts(GrammarUtils.terminalRegex(stringTerminal));
for (const part of parts) {
if (part.end) {
stringPatterns.push({
Expand Down
10 changes: 5 additions & 5 deletions packages/langium-cli/src/generator/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* This program and the accompanying materials are made available under the
* terms of the MIT License, which is available in the project root.
******************************************************************************/
import { type Grammar, getAllReachableRules, GrammarAST, stream, streamAllContents, terminalRegex } from 'langium';
import { AstUtils, type Grammar, GrammarAST, GrammarUtils, stream } from 'langium';
import { type Generated, expandToNode } from 'langium/generate';
import fs from 'fs-extra';
import * as path from 'node:path';
Expand Down Expand Up @@ -59,11 +59,11 @@ function getGeneratedHeader(): Generated {

export function collectKeywords(grammar: Grammar): string[] {
const keywords = new Set<string>();
const reachableRules = getAllReachableRules(grammar, false);
const reachableRules = GrammarUtils.getAllReachableRules(grammar, false);

for (const keyword of stream(reachableRules)
.filter(GrammarAST.isParserRule)
.flatMap(rule => streamAllContents(rule).filter(GrammarAST.isKeyword))) {
.flatMap(rule => AstUtils.streamAllContents(rule).filter(GrammarAST.isKeyword))) {
keywords.add(keyword.value);
}

Expand Down Expand Up @@ -97,10 +97,10 @@ export async function getUserChoice<R extends string>(text: string, values: R[],

export function collectTerminalRegexps(grammar: Grammar): Record<string, RegExp> {
const result: Record<string, RegExp> = {};
const reachableRules = getAllReachableRules(grammar, false);
const reachableRules = GrammarUtils.getAllReachableRules(grammar, false);
for (const terminalRule of stream(reachableRules).filter(GrammarAST.isTerminalRule)) {
const name = terminalRule.name;
const regexp = terminalRegex(terminalRule);
const regexp = GrammarUtils.terminalRegex(terminalRule);
result[name] = regexp;
}
return result;
Expand Down
4 changes: 2 additions & 2 deletions packages/langium-cli/src/parser-validation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
******************************************************************************/
import type { Grammar, IParserConfig, LangiumDocuments, LangiumParser, LanguageMetaData } from 'langium';
import type { LangiumConfig, LangiumLanguageConfig } from './package.js';
import { getDocument, GrammarAST, prepareLangiumParser } from 'langium';
import { AstUtils, GrammarAST, prepareLangiumParser } from 'langium';
import type { LangiumGrammarServices} from 'langium/grammar';
import { createServicesForGrammar } from 'langium/grammar';
import { getFilePath } from './package.js';
Expand Down Expand Up @@ -39,7 +39,7 @@ export async function validateParser(grammar: Grammar, config: LangiumConfig, gr
if (defError.ruleName) {
const rule = findRule(defError.ruleName, grammar, grammarServices.shared.workspace.LangiumDocuments);
if (rule && rule.$cstNode) {
const filePath = getFilePath(getDocument(rule).uri.fsPath, config);
const filePath = getFilePath(AstUtils.getDocument(rule).uri.fsPath, config);
const line = rule.$cstNode.range.start.line + 1;
message += `${filePath}:${line} - `;
}
Expand Down
Loading

0 comments on commit f0ed380

Please sign in to comment.