Skip to content

Commit

Permalink
feat: remove type parameters from enum variants (#767)
Browse files Browse the repository at this point in the history
Closes #766

### Summary of Changes

Enum variants can no longer have type parameters.
  • Loading branch information
lars-reimann authored Nov 12, 2023
1 parent 11c58ee commit cb6556a
Show file tree
Hide file tree
Showing 45 changed files with 95 additions and 486 deletions.
2 changes: 0 additions & 2 deletions packages/safe-ds-lang/src/language/grammar/safe-ds.langium
Original file line number Diff line number Diff line change
Expand Up @@ -281,14 +281,12 @@ SdsEnumBody returns SdsEnumBody:
;

interface SdsEnumVariant extends SdsCallable, SdsNamedTypeDeclaration {
typeParameterList?: SdsTypeParameterList
constraintList?: SdsConstraintList
}

SdsEnumVariant returns SdsEnumVariant:
annotationCalls+=SdsAnnotationCall*
name=ID
typeParameterList=SdsTypeParameterList?
parameterList=SdsParameterList?
constraintList=SdsConstraintList?
;
Expand Down
3 changes: 0 additions & 3 deletions packages/safe-ds-lang/src/language/helpers/nodeProperties.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
isSdsClass,
isSdsDeclaration,
isSdsEnum,
isSdsEnumVariant,
isSdsFunction,
isSdsLambda,
isSdsModule,
Expand Down Expand Up @@ -278,8 +277,6 @@ export const getTypeParameters = (
return node.typeParameters;
} else if (isSdsClass(node)) {
return getTypeParameters(node.typeParameterList);
} else if (isSdsEnumVariant(node)) {
return getTypeParameters(node.typeParameterList);
} /* c8 ignore start */ else {
return [];
} /* c8 ignore stop */
Expand Down
7 changes: 3 additions & 4 deletions packages/safe-ds-lang/src/language/lsp/safe-ds-formatter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ import {
FormattingActionOptions,
isAstNode,
} from 'langium';
import { last } from '../../helpers/collectionUtils.js';
import * as ast from '../generated/ast.js';
import { getAnnotationCalls, getLiterals, getTypeArguments } from '../helpers/nodeProperties.js';
import { last } from '../../helpers/collectionUtils.js';
import noSpace = Formatting.noSpace;
import indent = Formatting.indent;
import newLine = Formatting.newLine;
import newLines = Formatting.newLines;
import noSpace = Formatting.noSpace;
import oneSpace = Formatting.oneSpace;
import indent = Formatting.indent;

const newLinesWithIndent = function (count: number, options?: FormattingActionOptions): FormattingAction {
return {
Expand Down Expand Up @@ -427,7 +427,6 @@ export class SafeDsFormatter extends AbstractFormatter {
formatter.property('name').prepend(newLine());
}

formatter.property('typeParameterList').prepend(noSpace());
formatter.property('parameterList').prepend(noSpace());
formatter.property('constraintList').prepend(oneSpace());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -124,9 +124,6 @@ export class SafeDsScopeComputation extends DefaultScopeComputation {
this.addToScopesIfKeyIsDefined(scopes, containingDeclaration.parameterList, description);
this.addToScopesIfKeyIsDefined(scopes, containingDeclaration.constraintList, description);
this.addToScopesIfKeyIsDefined(scopes, containingDeclaration.body, description);
} else if (isSdsEnumVariant(containingDeclaration)) {
this.addToScopesIfKeyIsDefined(scopes, containingDeclaration.parameterList, description);
this.addToScopesIfKeyIsDefined(scopes, containingDeclaration.constraintList, description);
} else if (isSdsFunction(containingDeclaration)) {
this.addToScopesIfKeyIsDefined(scopes, containingDeclaration.parameterList, description);
this.addToScopesIfKeyIsDefined(scopes, containingDeclaration.resultList, description);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
isSdsCallable,
isSdsClass,
isSdsEnum,
isSdsEnumVariant,
isSdsImportedDeclaration,
isSdsLambda,
isSdsMemberAccess,
Expand Down Expand Up @@ -398,9 +397,6 @@ export class SafeDsScopeProvider extends DefaultScopeProvider {
if (isSdsClass(namedTypeDeclaration)) {
const typeParameters = getTypeParameters(namedTypeDeclaration.typeParameterList);
return this.createScopeForNodes(typeParameters);
} else if (isSdsEnumVariant(namedTypeDeclaration)) {
const typeParameters = getTypeParameters(namedTypeDeclaration.typeParameterList);
return this.createScopeForNodes(typeParameters);
} else {
return EMPTY_SCOPE;
}
Expand Down
8 changes: 2 additions & 6 deletions packages/safe-ds-lang/src/language/validation/names.ts
Original file line number Diff line number Diff line change
Expand Up @@ -227,12 +227,8 @@ export const enumMustContainUniqueNames = (node: SdsEnum, accept: ValidationAcce
};

export const enumVariantMustContainUniqueNames = (node: SdsEnumVariant, accept: ValidationAcceptor): void => {
const typeParametersAndParameters = [...getTypeParameters(node.typeParameterList), ...getParameters(node)];
namesMustBeUnique(
typeParametersAndParameters,
(name) => `A type parameter or parameter with name '${name}' exists already.`,
accept,
);
const parameters = [...getParameters(node)];
namesMustBeUnique(parameters, (name) => `A parameter with name '${name}' exists already.`, accept);
};

export const expressionLambdaMustContainUniqueNames = (node: SdsExpressionLambda, accept: ValidationAcceptor): void => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -120,41 +120,35 @@ describe('SafeDsDocumentationProvider', () => {
{
testName: 'documented type parameter',
code: `
enum MyEnum {
/**
* @typeParam T
* ${testDocumentation}
*/
MyEnumVariant<T>
}
/**
* @typeParam T
* ${testDocumentation}
*/
class MyClass<T>
`,
predicate: isSdsTypeParameter,
expectedDocumentation: testDocumentation,
},
{
testName: 'documented type parameter (duplicate)',
code: `
enum MyEnum {
/**
* @typeParam T ${testDocumentation}
* @typeParam T bla
*/
MyEnumVariant<T>
}
/**
* @typeParam T ${testDocumentation}
* @typeParam T bla
*/
class MyClass<T>
`,
predicate: isSdsTypeParameter,
expectedDocumentation: testDocumentation,
},
{
testName: 'undocumented type parameter',
code: `
enum MyEnum {
/**
* @typeParam T
* ${testDocumentation}
*/
MyEnumVariant<T2>
}
/**
* @typeParam T
* ${testDocumentation}
*/
class MyClass<T2>
`,
predicate: isSdsTypeParameter,
expectedDocumentation: undefined,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { afterEach, describe, expect, it } from 'vitest';
import { createSafeDsServices } from '../../../../src/language/safe-ds-module.js';
import { clearDocuments } from 'langium/test';
import { EmptyFileSystem } from 'langium';
import { getNodeOfType } from '../../../helpers/nodeFinder.js';
import { clearDocuments } from 'langium/test';
import { afterEach, describe, expect, it } from 'vitest';
import { isSdsAbstractCall, SdsArgument } from '../../../../src/language/generated/ast.js';
import { getArguments } from '../../../../src/language/helpers/nodeProperties.js';
import { createSafeDsServices } from '../../../../src/language/index.js';
import { getNodeOfType } from '../../../helpers/nodeFinder.js';

const services = createSafeDsServices(EmptyFileSystem).SafeDs;
const nodeMapper = services.helpers.NodeMapper;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import { createSafeDsServices } from '../../../../src/language/safe-ds-module.js';
import { NodeFileSystem } from 'langium/node';
import { clearDocuments } from 'langium/test';
import { getNodeOfType } from '../../../helpers/nodeFinder.js';
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
import {
isSdsAbstractResult,
isSdsAssignment,
isSdsPlaceholder,
SdsAssignee,
} from '../../../../src/language/generated/ast.js';
import { getAssignees } from '../../../../src/language/helpers/nodeProperties.js';
import { NodeFileSystem } from 'langium/node';
import { createSafeDsServices } from '../../../../src/language/index.js';
import { getNodeOfType } from '../../../helpers/nodeFinder.js';

const services = createSafeDsServices(NodeFileSystem).SafeDs;
const nodeMapper = services.helpers.NodeMapper;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { afterEach, describe, expect, it } from 'vitest';
import { createSafeDsServices } from '../../../../src/language/safe-ds-module.js';
import { clearDocuments } from 'langium/test';
import { EmptyFileSystem } from 'langium';
import { getNodeOfType } from '../../../helpers/nodeFinder.js';
import { clearDocuments } from 'langium/test';
import { afterEach, describe, expect, it } from 'vitest';
import { isSdsAbstractCall } from '../../../../src/language/generated/ast.js';
import { createSafeDsServices } from '../../../../src/language/index.js';
import { getNodeOfType } from '../../../helpers/nodeFinder.js';

const services = createSafeDsServices(EmptyFileSystem).SafeDs;
const nodeMapper = services.helpers.NodeMapper;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { afterEach, describe, expect, it } from 'vitest';
import { createSafeDsServices } from '../../../../src/language/safe-ds-module.js';
import { clearDocuments } from 'langium/test';
import { EmptyFileSystem } from 'langium';
import { getNodeOfType } from '../../../helpers/nodeFinder.js';
import { clearDocuments } from 'langium/test';
import { afterEach, describe, expect, it } from 'vitest';
import { isSdsParameter } from '../../../../src/language/generated/ast.js';
import { createSafeDsServices } from '../../../../src/language/index.js';
import { getNodeOfType } from '../../../helpers/nodeFinder.js';

const services = createSafeDsServices(EmptyFileSystem).SafeDs;
const nodeMapper = services.helpers.NodeMapper;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { afterEach, describe, expect, it } from 'vitest';
import { createSafeDsServices } from '../../../../src/language/safe-ds-module.js';
import { clearDocuments } from 'langium/test';
import { EmptyFileSystem } from 'langium';
import { getNodeOfType } from '../../../helpers/nodeFinder.js';
import { clearDocuments } from 'langium/test';
import { afterEach, describe, expect, it } from 'vitest';
import { isSdsPlaceholder } from '../../../../src/language/generated/ast.js';
import { createSafeDsServices } from '../../../../src/language/index.js';
import { getNodeOfType } from '../../../helpers/nodeFinder.js';

const services = createSafeDsServices(EmptyFileSystem).SafeDs;
const nodeMapper = services.helpers.NodeMapper;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { afterEach, describe, expect, it } from 'vitest';
import { createSafeDsServices } from '../../../../src/language/safe-ds-module.js';
import { clearDocuments } from 'langium/test';
import { EmptyFileSystem } from 'langium';
import { getNodeOfType } from '../../../helpers/nodeFinder.js';
import { clearDocuments } from 'langium/test';
import { afterEach, describe, expect, it } from 'vitest';
import { isSdsResult } from '../../../../src/language/generated/ast.js';
import { createSafeDsServices } from '../../../../src/language/index.js';
import { getNodeOfType } from '../../../helpers/nodeFinder.js';

const services = createSafeDsServices(EmptyFileSystem).SafeDs;
const nodeMapper = services.helpers.NodeMapper;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { afterEach, describe, expect, it } from 'vitest';
import { createSafeDsServices } from '../../../../src/language/safe-ds-module.js';
import { clearDocuments } from 'langium/test';
import { EmptyFileSystem } from 'langium';
import { getNodeOfType } from '../../../helpers/nodeFinder.js';
import { clearDocuments } from 'langium/test';
import { afterEach, describe, expect, it } from 'vitest';
import { isSdsNamedType, isSdsUnionType, SdsTypeArgument } from '../../../../src/language/generated/ast.js';
import { getTypeArguments } from '../../../../src/language/helpers/nodeProperties.js';
import { createSafeDsServices } from '../../../../src/language/index.js';
import { getNodeOfType } from '../../../helpers/nodeFinder.js';

const services = createSafeDsServices(EmptyFileSystem).SafeDs;
const nodeMapper = services.helpers.NodeMapper;
Expand Down Expand Up @@ -72,14 +72,12 @@ describe('SafeDsNodeMapper', () => {

it('should return the type parameter at the same index if all prior type arguments are positional', async () => {
const code = `
enum E {
V<T1, T2, T3>
}
class C<T1, T2, T3>
segment mySegment(p: E.V<C, C, C>) {}
segment mySegment(p: C<C, C, C>) {}
`;

const namedType = await getNodeOfType(services, code, isSdsNamedType, 1);
const namedType = await getNodeOfType(services, code, isSdsNamedType, 0);
const parameterNames = getTypeArguments(namedType.typeArgumentList).map(typeParameterNameOrNull);
expect(parameterNames).toStrictEqual(['T1', 'T2', 'T3']);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ describe('SafeDsSemanticTokenProvider', async () => {
testName: 'enum variant declaration',
code: `
enum E {
V<T>(p: Int)
V(p: Int)
}
`,
expectedSymbols: [
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
enum E {
A<T> where {
A where {
T sub Any ,
T super Int ,
}
Expand All @@ -8,7 +8,7 @@ enum E {
// -----------------------------------------------------------------------------

enum E {
A<T> where {
A where {
T sub Any,
T super Int,
}
Expand Down

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// $TEST$ no_syntax_error

enum E {
A<T> where {
A where {
T sub Any,
T super Int,
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ class »MyClass«<T>(
// $TEST$ target enum
enum »MyEnum« {
// $TEST$ target variant
»MyEnumVariant«<T>(
»MyEnumVariant«(
// $TEST$ references outerClass
p1: »MyClass«,

Expand Down
Loading

0 comments on commit cb6556a

Please sign in to comment.