Skip to content

Commit

Permalink
Merge pull request #576 from jvalue/refactor-unique-name-validation
Browse files Browse the repository at this point in the history
Refactor unique name validation
  • Loading branch information
georg-schwarz authored May 29, 2024
2 parents fc5502d + e55bf4a commit daa04b5
Show file tree
Hide file tree
Showing 27 changed files with 510 additions and 277 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -61,8 +61,10 @@ describe('Validation of validateRuntimeParameterLiteral', () => {
}
}

const operatorEvaluatorRegistry = new DefaultOperatorEvaluatorRegistry();
const valueTypeProvider = new ValueTypeProvider();
const operatorEvaluatorRegistry = new DefaultOperatorEvaluatorRegistry(
valueTypeProvider,
);
const wrapperFactories = new WrapperFactoryProvider(
operatorEvaluatorRegistry,
valueTypeProvider,
Expand All @@ -73,9 +75,7 @@ describe('Validation of validateRuntimeParameterLiteral', () => {
wrapperFactories,
);

const importResolver = new JayveeImportResolver(
services.shared.workspace.LangiumDocuments,
);
const importResolver = new JayveeImportResolver(services);

validateRuntimeParameterLiteral(runtimeParameter, {
validationContext: new ValidationContext(
Expand Down
6 changes: 3 additions & 3 deletions libs/language-server/src/lib/ast/model-util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ export interface ExportDetails {
/**
* The name which the exported element is available under.
*/
alias: string;
exportName: string;
}

/**
Expand All @@ -159,7 +159,7 @@ export function getExportedElements(model: JayveeModel): ExportDetails[] {
);
exportedElements.push({
element: node,
alias: node.name,
exportName: node.name,
});
}

Expand All @@ -169,7 +169,7 @@ export function getExportedElements(model: JayveeModel): ExportDetails[] {
const exportName = node.alias ?? originalDefinition.name;
exportedElements.push({
element: originalDefinition,
alias: exportName,
exportName: exportName,
});
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { strict as assert } from 'assert';

import { type Reference, isReference } from 'langium';

import { RuntimeParameterProvider } from '../../../services';
import { RuntimeParameterProvider } from '../../../services/runtime-parameter-provider';
import {
EvaluationContext,
type OperatorEvaluatorRegistry,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { strict as assert } from 'assert';

import { type Reference, isReference } from 'langium';

import { RuntimeParameterProvider } from '../../../services';
import { RuntimeParameterProvider } from '../../../services/runtime-parameter-provider';
import { evaluateExpression } from '../../expressions/evaluate-expression';
import { EvaluationContext } from '../../expressions/evaluation-context';
import { type OperatorEvaluatorRegistry } from '../../expressions/operator-registry';
Expand Down
3 changes: 1 addition & 2 deletions libs/language-server/src/lib/jayvee-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,7 @@ export const JayveeModule: Module<
services.operators.EvaluatorRegistry,
services.ValueTypeProvider,
),
ImportResolver: (services) =>
new JayveeImportResolver(services.shared.workspace.LangiumDocuments),
ImportResolver: (services) => new JayveeImportResolver(services),
};

export const JayveeSharedModule: Module<
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ export class JayveeCompletionProvider extends DefaultCompletionProvider {
);

const exportedElementNames = getExportedElements(resolvedModel).map(
(x) => x.alias,
(x) => x.exportName,
);

const suggestedElementNames = exportedElementNames.filter((x) =>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export class JayveeDefinitionProvider extends DefaultDefinitionProvider {
const allExportDefinitions = getExportedElements(importedModel);

const referencedExport = allExportDefinitions.find((x) => {
return x.alias === sourceAstNode.element;
return x.exportName === sourceAstNode.element;
});
if (referencedExport === undefined) {
return;
Expand Down
146 changes: 11 additions & 135 deletions libs/language-server/src/lib/lsp/jayvee-scope-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,18 @@
// SPDX-License-Identifier: AGPL-3.0-only

import {
type AstNode,
type AstNodeDescription,
AstUtils,
DefaultScopeProvider,
DocumentCache,
EMPTY_SCOPE,
type LangiumDocument,
type LangiumDocuments,
MapScope,
type ReferenceInfo,
type Scope,
URI,
} from 'langium';

import {
type ExportDetails,
type ImportDefinition,
type JayveeModel,
getExportedElements,
isJayveeModel,
} from '../ast';
import { getStdLib } from '../builtin-library';
import { type ExportDetails, isJayveeModel } from '../ast';
import { type JayveeServices } from '../jayvee-module';
import { type JayveeImportResolver } from '../services/import-resolver';

Expand Down Expand Up @@ -56,133 +46,19 @@ export class JayveeScopeProvider extends DefaultScopeProvider {
}

const importedElements: AstNodeDescription[] = [];
importedElements.push(...this.getBuiltinElements());
importedElements.push(...this.getExplicitlyImportedElements(jayveeModel));

return new MapScope(importedElements);
}

protected getExplicitlyImportedElements(
model: JayveeModel,
): AstNodeDescription[] {
const importedElements: AstNodeDescription[] = [];
for (const importDefinition of model.imports) {
const importedDocument = this.getImportedDocument(importDefinition);
if (importedDocument === undefined) {
continue;
}

importedElements.push(
...this.getImportedElementsFromDocument(
importDefinition,
importedDocument,
),
);
}
return importedElements;
}

protected getImportedElementsFromDocument(
importDefinition: ImportDefinition,
importedDocument: LangiumDocument,
): AstNodeDescription[] {
const publishedElements =
this.getPublishedElementsFromDocument(importedDocument);

if (importDefinition.useAll) {
return publishedElements;
}

// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
const namedImports = importDefinition.usedElements ?? [];

const importedElements: AstNodeDescription[] = [];
for (const namedImport of namedImports) {
const matchingExportedElement = publishedElements.find(
(x) => x.name === namedImport.element,
);
if (
matchingExportedElement === undefined ||
matchingExportedElement.node === undefined
) {
continue;
}

const importedElementName = namedImport.alias ?? namedImport.element;
importedElements.push(
this.descriptions.createDescription(
matchingExportedElement.node,
importedElementName,
),
);
}
return importedElements;
}

protected getBuiltinElements(): AstNodeDescription[] {
const builtinUris = this.getBuiltins();

const importedDocuments = [...builtinUris].map((importedUri) =>
this.langiumDocuments.getDocument(URI.parse(importedUri)),
const allBuiltinElements = this.importResolver.getBuiltinElements();
const allBuiltinElementDescriptions = allBuiltinElements.map((x) =>
this.descriptions.createDescription(x.element, x.exportName),
);
importedElements.push(...allBuiltinElementDescriptions);

const importedElements: AstNodeDescription[] = [];
for (const importedDocument of importedDocuments) {
if (importedDocument === undefined) {
continue;
}

importedElements.push(
...this.getPublishedElementsFromDocument(importedDocument),
);
}

return importedElements;
}

protected getPublishedElementsFromDocument(
document: LangiumDocument<AstNode>,
): AstNodeDescription[] {
const model = document.parseResult.value as JayveeModel;

const publishedElements = this.availableElementsPerDocumentCache.get(
document.uri,
'exports', // we only need one key here as it is on document basis
() => getExportedElements(model),
);
return publishedElements.map((e) =>
this.descriptions.createDescription(e.element, e.alias),
const allImportedElements =
this.importResolver.getImportedElements(jayveeModel);
const allImportedElementDescriptions = allImportedElements.map((x) =>
this.descriptions.createDescription(x.element, x.importName),
);
}

/**
* Add all builtins' URIs to @param importedUris
*/
protected getBuiltins(): Set<string> {
const importedUris: Set<string> = new Set();
importedElements.push(...allImportedElementDescriptions);

const builtins = getStdLib();
const uris = Object.keys(builtins);

for (const uri of uris) {
// without formatting, the document might not be found
const formattedUri = URI.parse(uri).toString();
importedUris.add(formattedUri);
}

return importedUris;
}

protected getImportedDocument(
importDefinition: ImportDefinition,
): LangiumDocument | undefined {
const uri = this.importResolver.resolveImportUri(importDefinition);
if (uri === undefined) {
return undefined;
}

const importedDocument = this.langiumDocuments.getDocument(uri);

return importedDocument;
return new MapScope(importedElements);
}
}
Loading

0 comments on commit daa04b5

Please sign in to comment.