Skip to content

Commit

Permalink
Merge pull request #575 from jvalue/import-alias
Browse files Browse the repository at this point in the history
Allow aliasing imports
  • Loading branch information
georg-schwarz authored May 29, 2024
2 parents 68985df + ae53085 commit fc5502d
Show file tree
Hide file tree
Showing 5 changed files with 40 additions and 32 deletions.
5 changes: 4 additions & 1 deletion libs/language-server/src/grammar/main.langium
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,8 @@ ExportDefinition:
ImportDefinition:
'use' (
useAll?='*'
| '{' (usedElements+=ID) (',' usedElements+=ID)* '}'
| '{' usedElements+=NamedImportElement (',' usedElements+=NamedImportElement)* '}'
) 'from' path=STRING ';';

NamedImportElement:
element=ID ('as' alias=ID)?;
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ export class JayveeCompletionProvider extends DefaultCompletionProvider {
}

const isImportElementCompletion =
isImportDefinition(astNode) && next.property === 'usedElements';
isImportDefinition(astNode) && next.property === 'element';
if (isImportElementCompletion) {
return this.completionForImportElement(astNode, context, acceptor);
}
Expand Down
34 changes: 14 additions & 20 deletions libs/language-server/src/lib/lsp/jayvee-definition-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,12 @@ import {
Range,
} from 'vscode-languageserver-protocol';

import { getExportedElements, isImportDefinition, isJayveeModel } from '../ast';
import {
getExportedElements,
isImportDefinition,
isJayveeModel,
isNamedImportElement,
} from '../ast';
import { type JayveeServices } from '../jayvee-module';
import { type JayveeImportResolver } from '../services/import-resolver';

Expand Down Expand Up @@ -54,27 +59,16 @@ export class JayveeDefinitionProvider extends DefaultDefinitionProvider {
}

if (
isImportDefinition(sourceAstNode) &&
GrammarUtils.findAssignment(sourceCstNode)?.feature === 'usedElements'
isNamedImportElement(sourceAstNode) &&
GrammarUtils.findAssignment(sourceCstNode)?.feature === 'element'
) {
const clickedIndex =
GrammarUtils.findAssignment(sourceCstNode)?.$container?.$containerIndex;
assert(
clickedIndex !== undefined,
'Could not read index of selected element',
);
const indexOfElement = clickedIndex - 1;
const importDefinition = sourceAstNode.$container;
assert(
indexOfElement < sourceAstNode.usedElements.length,
'Index of selected element is not correctly computed',
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
importDefinition !== undefined,
'Could not traverse to ImportDefinition',
);
const refString = sourceAstNode.usedElements[indexOfElement];
assert(
refString !== undefined,
'Could not read reference text to imported element',
);

const importedModel = this.importResolver.resolveImport(sourceAstNode);
const importedModel = this.importResolver.resolveImport(importDefinition);

if (importedModel?.$document === undefined) {
return undefined;
Expand All @@ -83,7 +77,7 @@ export class JayveeDefinitionProvider extends DefaultDefinitionProvider {
const allExportDefinitions = getExportedElements(importedModel);

const referencedExport = allExportDefinitions.find((x) => {
return x.alias === refString;
return x.alias === sourceAstNode.element;
});
if (referencedExport === undefined) {
return;
Expand Down
19 changes: 14 additions & 5 deletions libs/language-server/src/lib/lsp/jayvee-scope-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,18 +94,27 @@ export class JayveeScopeProvider extends DefaultScopeProvider {
}

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

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

importedElements.push(matchingExportedElement);
const importedElementName = namedImport.alias ?? namedImport.element;
importedElements.push(
this.descriptions.createDescription(
matchingExportedElement.node,
importedElementName,
),
);
}
return importedElements;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,15 @@ function checkElementImportedOnlyOnce(

for (const [i, importedElement] of importedElements.entries()) {
const occurrencesInSameImportDefinition = importedElements.filter(
(x) => x === importedElement,
(x) => x.element === importedElement.element,
).length;

if (occurrencesInSameImportDefinition > 1) {
props.validationContext.accept(
'error',
`Element ${importedElement} is imported ${occurrencesInSameImportDefinition} times from file "${
`Element ${
importedElement.element
} is imported ${occurrencesInSameImportDefinition} times from file "${
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
importDefinition.path ?? ''
}". Remove the duplicate import.`,
Expand Down Expand Up @@ -142,12 +144,12 @@ function checkImportedElementsExist(
];

// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
for (const [i, importedElement] of importDefinition.usedElements?.entries() ??
for (const [i, namedImport] of importDefinition.usedElements?.entries() ??
[]) {
if (!allExports.includes(importedElement)) {
if (!allExports.includes(namedImport.element)) {
props.validationContext.accept(
'error',
`Could not find published element ${importedElement} in file "${importDefinition.path}". Check if the element exists and has been correctly published.`,
`Could not find published element ${namedImport.element} in file "${importDefinition.path}". Check if the element exists and has been correctly published.`,
{
node: importDefinition,
property: 'usedElements',
Expand Down

0 comments on commit fc5502d

Please sign in to comment.