Skip to content

Commit

Permalink
feat: unique names withing declarations (#575)
Browse files Browse the repository at this point in the history
Closes partially #543

### Summary of Changes

Ensure that names are unique within declarations. I'll port the checks
for uniqueness on the file level in a future PR.

---------

Co-authored-by: megalinter-bot <129584137+megalinter-bot@users.noreply.github.com>
  • Loading branch information
lars-reimann and megalinter-bot committed Sep 21, 2023
1 parent 4ba7873 commit 47ce782
Show file tree
Hide file tree
Showing 19 changed files with 670 additions and 54 deletions.
6 changes: 6 additions & 0 deletions src/language/ast/checks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { SdsImport } from '../generated/ast.js';

export const isWildcardImport = function (node: SdsImport): boolean {
const importedNamespace = node.importedNamespace ?? '';
return importedNamespace.endsWith('*');
};
96 changes: 96 additions & 0 deletions src/language/ast/shortcuts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import {
isSdsAssignment,
isSdsBlockLambdaResult,
isSdsDeclaration,
isSdsPlaceholder,
SdsAnnotatedObject,
SdsAnnotationCall,
SdsAssignee,
SdsAssignment,
SdsBlock,
SdsBlockLambda,
SdsBlockLambdaResult,
SdsClass,
SdsClassMember,
SdsEnum,
SdsEnumVariant,
SdsLiteral,
SdsLiteralType,
SdsParameter,
SdsParameterList,
SdsPlaceholder,
SdsResult,
SdsResultList,
SdsStatement,
SdsTypeArgument,
SdsTypeArgumentList,
SdsTypeParameter,
SdsTypeParameterList,
} from '../generated/ast.js';
import { stream } from 'langium';

export const annotationCallsOrEmpty = function (node: SdsAnnotatedObject | undefined): SdsAnnotationCall[] {
if (!node) {
/* c8 ignore next 2 */
return [];
}

if (isSdsDeclaration(node)) {
return node?.annotationCallList?.annotationCalls ?? node?.annotationCalls ?? [];
} else {
/* c8 ignore next 2 */
return node?.annotationCalls ?? [];
}
};

export const assigneesOrEmpty = function (node: SdsAssignment | undefined): SdsAssignee[] {
return node?.assigneeList?.assignees ?? [];
};

export const blockLambdaResultsOrEmpty = function (node: SdsBlockLambda | undefined): SdsBlockLambdaResult[] {
return stream(statementsOrEmpty(node?.body))
.filter(isSdsAssignment)
.flatMap(assigneesOrEmpty)
.filter(isSdsBlockLambdaResult)
.toArray();
};

export const literalsOrEmpty = function (node: SdsLiteralType | undefined): SdsLiteral[] {
return node?.literalList?.literals ?? [];
};

export const classMembersOrEmpty = function (node: SdsClass | undefined): SdsClassMember[] {
return node?.body?.members ?? [];
};

export const parametersOrEmpty = function (node: SdsParameterList | undefined): SdsParameter[] {
return node?.parameters ?? [];
};

export const placeholdersOrEmpty = function (node: SdsBlock | undefined): SdsPlaceholder[] {
return stream(statementsOrEmpty(node))
.filter(isSdsAssignment)
.flatMap(assigneesOrEmpty)
.filter(isSdsPlaceholder)
.toArray();
};

export const resultsOrEmpty = function (node: SdsResultList | undefined): SdsResult[] {
return node?.results ?? [];
};

export const statementsOrEmpty = function (node: SdsBlock | undefined): SdsStatement[] {
return node?.statements ?? [];
};

export const typeArgumentsOrEmpty = function (node: SdsTypeArgumentList | undefined): SdsTypeArgument[] {
return node?.typeArguments ?? [];
};

export const typeParametersOrEmpty = function (node: SdsTypeParameterList | undefined): SdsTypeParameter[] {
return node?.typeParameters ?? [];
};

export const variantsOrEmpty = function (node: SdsEnum | undefined): SdsEnumVariant[] {
return node?.body?.variants ?? [];
};
14 changes: 12 additions & 2 deletions src/language/formatting/safe-ds-formatter.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,16 @@
import { AbstractFormatter, AstNode, CstNode, findCommentNode, Formatting, isAstNode, FormattingAction, FormattingActionOptions } from 'langium';
import {
AbstractFormatter,
AstNode,
CstNode,
findCommentNode,
Formatting,
isAstNode,
FormattingAction,
FormattingActionOptions,
} from 'langium';
import * as ast from '../generated/ast.js';
import { SdsImport, SdsImportAlias, SdsModule } from '../generated/ast.js';
import { annotationCallsOrEmpty, literalsOrEmpty, typeArgumentsOrEmpty } from '../helpers/astShortcuts.js';
import { annotationCallsOrEmpty, literalsOrEmpty, typeArgumentsOrEmpty } from '../ast/shortcuts.js';
import noSpace = Formatting.noSpace;
import newLine = Formatting.newLine;
import newLines = Formatting.newLines;
Expand Down Expand Up @@ -876,6 +885,7 @@ export class SafeDsFormatter extends AbstractFormatter {
} else if (ast.isSdsUnionType(node)) {
return typeArgumentsOrEmpty(node.typeArgumentList).length > 0;
} else {
/* c8 ignore next 2 */
return false;
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/language/grammar/safe-ds.langium
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ QualifiedName returns string:

interface SdsModuleMember extends SdsDeclaration {}

SdsAnnotatedModuleMember returns SdsAnnotatedObject:
SdsAnnotatedModuleMember returns SdsModuleMember:
{SdsAnnotationCallList}
annotationCalls+=SdsAnnotationCall+
(
Expand All @@ -108,7 +108,7 @@ SdsAnnotatedModuleMember returns SdsAnnotatedObject:
)
;

SdsUnannotatedModuleMember returns SdsAnnotatedObject:
SdsUnannotatedModuleMember returns SdsModuleMember:
{SdsAnnotation}
SdsAnnotationFragment

Expand Down Expand Up @@ -170,7 +170,7 @@ SdsParentTypeList returns SdsParentTypeList:
;

interface SdsClassBody extends SdsObject {
members: SdsAnnotatedObject[]
members: SdsClassMember[]
}

SdsClassBody returns SdsClassBody:
Expand All @@ -179,12 +179,12 @@ SdsClassBody returns SdsClassBody:

interface SdsClassMember extends SdsDeclaration {}

SdsClassMember returns SdsAnnotatedObject:
SdsClassMember returns SdsClassMember:
SdsAnnotatedClassMember
| SdsUnannotatedClassMember
;

SdsAnnotatedClassMember returns SdsAnnotatedObject:
SdsAnnotatedClassMember returns SdsClassMember:
{SdsAnnotationCallList}
annotationCalls+=SdsAnnotationCall+
(
Expand All @@ -203,7 +203,7 @@ SdsAnnotatedClassMember returns SdsAnnotatedObject:
)
;

SdsUnannotatedClassMember returns SdsAnnotatedObject:
SdsUnannotatedClassMember returns SdsClassMember:
{SdsAttribute}
SdsAttributeFragment

Expand Down
38 changes: 0 additions & 38 deletions src/language/helpers/astShortcuts.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/language/scoping/safe-ds-scope-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
SdsType,
SdsYield,
} from '../generated/ast.js';
import { resultsOrEmpty } from '../helpers/astShortcuts.js';
import { resultsOrEmpty } from '../ast/shortcuts.js';

export class SafeDsScopeProvider extends DefaultScopeProvider {
override getScope(context: ReferenceInfo): Scope {
Expand Down
2 changes: 1 addition & 1 deletion src/language/validation/imports.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { ValidationAcceptor } from 'langium';
import { SdsImportAlias } from '../generated/ast.js';
import { isWildcardImport } from '../helpers/astShortcuts.js';
import { isWildcardImport } from '../ast/checks.js';

export const CODE_IMPORT_WILDCARD_IMPORT_WITH_ALIAS = 'import/wildcard-import-with-alias';

Expand Down
Loading

0 comments on commit 47ce782

Please sign in to comment.