diff --git a/docs/lexer/safe_ds_lexer/_safe_ds_lexer.py b/docs/lexer/safe_ds_lexer/_safe_ds_lexer.py index b6860ea96..70178294d 100644 --- a/docs/lexer/safe_ds_lexer/_safe_ds_lexer.py +++ b/docs/lexer/safe_ds_lexer/_safe_ds_lexer.py @@ -51,7 +51,6 @@ "not", "or", "sub", - "super", ) builtins = ( diff --git a/packages/safe-ds-lang/src/language/grammar/safe-ds.langium b/packages/safe-ds-lang/src/language/grammar/safe-ds.langium index 64ac752e6..a692319f8 100644 --- a/packages/safe-ds-lang/src/language/grammar/safe-ds.langium +++ b/packages/safe-ds-lang/src/language/grammar/safe-ds.langium @@ -378,23 +378,19 @@ SdsConstraintList returns SdsConstraintList: interface SdsConstraint extends SdsObject {} SdsConstraint returns SdsConstraint: - SdsTypeParameterBound + SdsParameterBound ; -interface SdsTypeParameterBound extends SdsConstraint { - leftOperand?: @SdsTypeParameter +interface SdsParameterBound extends SdsConstraint { + leftOperand?: @SdsParameter operator: string - rightOperand: SdsType + rightOperand: SdsExpression } -SdsTypeParameterBound returns SdsTypeParameterBound: - leftOperand=[SdsTypeParameter:ID] - operator=SdsTypeParameterBoundOperator - rightOperand=SdsType -; - -SdsTypeParameterBoundOperator returns string: - 'sub' | 'super' +SdsParameterBound returns SdsParameterBound: + leftOperand=[SdsParameter:ID] + operator=SdsComparisonOperator + rightOperand=SdsExpression ; @@ -967,11 +963,7 @@ SdsUnionTypeArgumentList returns SdsTypeArgumentList: ; SdsUnionTypeArgument returns SdsTypeArgument: - value=SdsUnionTypeArgumentValue -; - -SdsUnionTypeArgumentValue returns SdsTypeArgumentValue: - {SdsTypeProjection} ^type=SdsType + value=SdsType ; SdsParentType returns SdsType: @@ -995,6 +987,7 @@ SdsTypeParameterList returns SdsTypeParameterList: interface SdsTypeParameter extends SdsNamedTypeDeclaration { variance?: string + upperBound?: SdsType defaultValue?: SdsType } @@ -1002,6 +995,7 @@ SdsTypeParameter returns SdsTypeParameter: annotationCalls+=SdsAnnotationCall* variance=SdsTypeParameterVariance? name=ID + ('sub' upperBound=SdsType)? ('=' defaultValue=SdsType)? ; @@ -1022,22 +1016,12 @@ SdsTypeArgumentList returns SdsTypeArgumentList: interface SdsTypeArgument extends SdsObject { typeParameter?: @SdsTypeParameter - value: SdsTypeArgumentValue + value: SdsType } SdsTypeArgument returns SdsTypeArgument: (typeParameter=[SdsTypeParameter:ID] '=' )? - value=SdsTypeArgumentValue -; - -interface SdsTypeArgumentValue extends SdsObject {} - -interface SdsTypeProjection extends SdsTypeArgumentValue { - ^type: SdsType -} - -SdsTypeArgumentValue returns SdsTypeArgumentValue: - {SdsTypeProjection} ^type=SdsType + value=SdsType ; diff --git a/packages/safe-ds-lang/src/language/helpers/nodeProperties.ts b/packages/safe-ds-lang/src/language/helpers/nodeProperties.ts index cbbc00965..1c6347379 100644 --- a/packages/safe-ds-lang/src/language/helpers/nodeProperties.ts +++ b/packages/safe-ds-lang/src/language/helpers/nodeProperties.ts @@ -12,7 +12,6 @@ import { isSdsClass, isSdsDeclaration, isSdsEnum, - isSdsEnumVariant, isSdsFunction, isSdsLambda, isSdsModule, @@ -24,7 +23,6 @@ import { isSdsSegment, isSdsTypeArgumentList, isSdsTypeParameter, - isSdsTypeParameterBound, isSdsTypeParameterList, SdsAbstractCall, SdsAbstractResult, @@ -42,7 +40,6 @@ import { SdsClass, SdsClassMember, SdsColumn, - SdsConstraint, SdsDeclaration, SdsEnum, SdsEnumVariant, @@ -65,7 +62,6 @@ import { SdsTypeArgument, SdsTypeArgumentList, SdsTypeParameter, - SdsTypeParameterBound, SdsTypeParameterList, } from '../generated/ast.js'; @@ -173,51 +169,6 @@ export namespace TypeParameter { export const isInvariant = (node: SdsTypeParameter | undefined): boolean => { return isSdsTypeParameter(node) && !node.variance; }; - - export const getLowerBounds = (node: SdsTypeParameter | undefined): SdsTypeParameterBound[] => { - return getBounds(node).filter((it) => { - if (it.operator === 'super') { - // Type parameter is the left operand - return it.leftOperand?.ref === node; - } else if (it.operator === 'sub') { - // Type parameter is the right operand - return isSdsNamedType(it.rightOperand) && it.rightOperand.declaration?.ref === node; - } else { - /* c8 ignore next 2 */ - return false; - } - }); - }; - - export const getUpperBounds = (node: SdsTypeParameter | undefined): SdsTypeParameterBound[] => { - return getBounds(node).filter((it) => { - if (it.operator === 'sub') { - // Type parameter is the left operand - return it.leftOperand?.ref === node; - } else if (it.operator === 'super') { - // Type parameter is the right operand - return isSdsNamedType(it.rightOperand) && it.rightOperand.declaration?.ref === node; - } else { - /* c8 ignore next 2 */ - return false; - } - }); - }; - - const getBounds = (node: SdsTypeParameter | undefined): SdsTypeParameterBound[] => { - const declarationContainingTypeParameter = getContainerOfType(node?.$container, isSdsDeclaration); - return getConstraints(declarationContainingTypeParameter).filter((it) => { - if (!isSdsTypeParameterBound(it)) { - /* c8 ignore next 2 */ - return false; - } - - return ( - it.leftOperand?.ref === node || - (isSdsNamedType(it.rightOperand) && it.rightOperand.declaration?.ref === node) - ); - }) as SdsTypeParameterBound[]; - }; } // ------------------------------------------------------------------------------------------------- @@ -301,23 +252,6 @@ export const getColumns = (node: SdsSchema | undefined): SdsColumn[] => { return node?.columnList?.columns ?? []; }; -export const getConstraints = (node: SdsDeclaration | undefined): SdsConstraint[] => { - if (isSdsAnnotation(node)) { - /* c8 ignore next 2 */ - return node.constraintList?.constraints ?? []; - } else if (isSdsClass(node)) { - return node.constraintList?.constraints ?? []; - } else if (isSdsEnumVariant(node)) { - /* c8 ignore next 2 */ - return node.constraintList?.constraints ?? []; - } else if (isSdsFunction(node)) { - return node.constraintList?.constraints ?? []; - } else { - /* c8 ignore next 2 */ - return []; - } -}; - export const getEnumVariants = (node: SdsEnum | undefined): SdsEnumVariant[] => { return node?.body?.variants ?? []; }; diff --git a/packages/safe-ds-lang/src/language/lsp/safe-ds-formatter.ts b/packages/safe-ds-lang/src/language/lsp/safe-ds-formatter.ts index ffa2381cb..11f75ba83 100644 --- a/packages/safe-ds-lang/src/language/lsp/safe-ds-formatter.ts +++ b/packages/safe-ds-lang/src/language/lsp/safe-ds-formatter.ts @@ -87,8 +87,8 @@ export class SafeDsFormatter extends AbstractFormatter { // ----------------------------------------------------------------------------- else if (ast.isSdsConstraintList(node)) { this.formatSdsConstraintList(node); - } else if (ast.isSdsTypeParameterBound(node)) { - this.formatSdsTypeParameterBound(node); + } else if (ast.isSdsParameterBound(node)) { + this.formatSdsParameterBound(node); } // ----------------------------------------------------------------------------- @@ -529,7 +529,7 @@ export class SafeDsFormatter extends AbstractFormatter { } } - private formatSdsTypeParameterBound(node: ast.SdsTypeParameterBound) { + private formatSdsParameterBound(node: ast.SdsParameterBound) { const formatter = this.getNodeFormatter(node); formatter.property('operator').surround(oneSpace()); diff --git a/packages/safe-ds-lang/src/language/lsp/safe-ds-semantic-token-provider.ts b/packages/safe-ds-lang/src/language/lsp/safe-ds-semantic-token-provider.ts index 0356f5af7..cd73b9cd3 100644 --- a/packages/safe-ds-lang/src/language/lsp/safe-ds-semantic-token-provider.ts +++ b/packages/safe-ds-lang/src/language/lsp/safe-ds-semantic-token-provider.ts @@ -16,6 +16,7 @@ import { isSdsModule, isSdsNamedType, isSdsParameter, + isSdsParameterBound, isSdsPipeline, isSdsPlaceholder, isSdsReference, @@ -24,7 +25,6 @@ import { isSdsSegment, isSdsTypeArgument, isSdsTypeParameter, - isSdsTypeParameterBound, isSdsYield, } from '../generated/ast.js'; import { SafeDsServices } from '../safe-ds-module.js'; @@ -91,6 +91,12 @@ export class SafeDsSemanticTokenProvider extends AbstractSemanticTokenProvider { ...info, }); } + } else if (isSdsParameterBound(node)) { + acceptor({ + node, + property: 'leftOperand', + type: SemanticTokenTypes.parameter, + }); } else if (isSdsReference(node)) { const info = this.computeSemanticTokenInfoForDeclaration(node.target.ref); if (info) { @@ -108,12 +114,6 @@ export class SafeDsSemanticTokenProvider extends AbstractSemanticTokenProvider { type: SemanticTokenTypes.typeParameter, }); } - } else if (isSdsTypeParameterBound(node)) { - acceptor({ - node, - property: 'leftOperand', - type: SemanticTokenTypes.typeParameter, - }); } else if (isSdsYield(node)) { // For lack of a better option, we use the token type for parameters here acceptor({ diff --git a/packages/safe-ds-lang/src/language/scoping/safe-ds-scope-computation.ts b/packages/safe-ds-lang/src/language/scoping/safe-ds-scope-computation.ts index 3dd486a11..d55ce9dbe 100644 --- a/packages/safe-ds-lang/src/language/scoping/safe-ds-scope-computation.ts +++ b/packages/safe-ds-lang/src/language/scoping/safe-ds-scope-computation.ts @@ -7,12 +7,15 @@ import { PrecomputedScopes, } from 'langium'; import { + isSdsAnnotation, isSdsClass, isSdsDeclaration, isSdsEnum, isSdsEnumVariant, isSdsFunction, isSdsModule, + isSdsParameter, + isSdsParameterList, isSdsPipeline, isSdsSegment, isSdsTypeParameter, @@ -20,6 +23,7 @@ import { SdsClass, SdsEnum, SdsEnumVariant, + SdsParameter, SdsTypeParameter, } from '../generated/ast.js'; @@ -46,6 +50,8 @@ export class SafeDsScopeComputation extends DefaultScopeComputation { this.processSdsEnum(node, document, scopes); } else if (isSdsEnumVariant(node)) { this.processSdsEnumVariant(node, document, scopes); + } else if (isSdsParameter(node)) { + this.processSdsParameter(node, document, scopes); } else if (isSdsTypeParameter(node)) { this.processSdsTypeParameter(node, document, scopes); } else { @@ -101,6 +107,32 @@ export class SafeDsScopeComputation extends DefaultScopeComputation { this.addToScopesIfKeyIsDefined(scopes, node.constraintList, description); } + private processSdsParameter(node: SdsParameter, document: LangiumDocument, scopes: PrecomputedScopes): void { + const containingCallable = getContainerOfType(node, isSdsParameterList)?.$container; + if (!containingCallable) { + /* c8 ignore next 2 */ + return; + } + + const name = this.nameProvider.getName(node); + if (!name) { + /* c8 ignore next 2 */ + return; + } + + const description = this.descriptions.createDescription(node, name, document); + + if (isSdsAnnotation(containingCallable)) { + this.addToScopesIfKeyIsDefined(scopes, containingCallable.constraintList, description); + } else if (isSdsClass(containingCallable)) { + this.addToScopesIfKeyIsDefined(scopes, containingCallable.constraintList, description); + } else if (isSdsEnumVariant(containingCallable)) { + this.addToScopesIfKeyIsDefined(scopes, containingCallable.constraintList, description); + } else if (isSdsFunction(containingCallable)) { + this.addToScopesIfKeyIsDefined(scopes, containingCallable.constraintList, description); + } + } + private processSdsTypeParameter( node: SdsTypeParameter, document: LangiumDocument, @@ -123,12 +155,10 @@ export class SafeDsScopeComputation extends DefaultScopeComputation { if (isSdsClass(containingDeclaration)) { this.addToScopesIfKeyIsDefined(scopes, containingDeclaration.parameterList, description); this.addToScopesIfKeyIsDefined(scopes, containingDeclaration.parentTypeList, description); - this.addToScopesIfKeyIsDefined(scopes, containingDeclaration.constraintList, description); this.addToScopesIfKeyIsDefined(scopes, containingDeclaration.body, description); } else if (isSdsFunction(containingDeclaration)) { this.addToScopesIfKeyIsDefined(scopes, containingDeclaration.parameterList, description); this.addToScopesIfKeyIsDefined(scopes, containingDeclaration.resultList, description); - this.addToScopesIfKeyIsDefined(scopes, containingDeclaration.constraintList, description); } } diff --git a/packages/safe-ds-lang/src/language/scoping/safe-ds-scope-provider.ts b/packages/safe-ds-lang/src/language/scoping/safe-ds-scope-provider.ts index d9b080806..518658ee8 100644 --- a/packages/safe-ds-lang/src/language/scoping/safe-ds-scope-provider.ts +++ b/packages/safe-ds-lang/src/language/scoping/safe-ds-scope-provider.ts @@ -34,6 +34,7 @@ import { isSdsSegment, isSdsStatement, isSdsTypeArgument, + isSdsTypeParameter, isSdsWildcardImport, isSdsYield, SdsAnnotation, @@ -44,6 +45,7 @@ import { SdsImportedDeclaration, SdsMemberAccess, SdsMemberType, + SdsNamedType, SdsNamedTypeDeclaration, type SdsParameter, SdsPlaceholder, @@ -110,7 +112,7 @@ export class SafeDsScopeProvider extends DefaultScopeProvider { if (isSdsMemberType(node.$container) && node.$containerProperty === 'member') { return this.getScopeForMemberTypeMember(node.$container); } else { - return this.getScopeForNamedTypeDeclaration(context); + return this.getScopeForNamedTypeDeclaration(node, context); } } else if (isSdsReference(node) && context.property === 'target') { if (isSdsMemberAccess(node.$container) && node.$containerProperty === 'member') { @@ -192,8 +194,19 @@ export class SafeDsScopeProvider extends DefaultScopeProvider { } } - private getScopeForNamedTypeDeclaration(context: ReferenceInfo): Scope { - return this.coreDeclarations(SdsNamedTypeDeclaration, super.getScope(context)); + private getScopeForNamedTypeDeclaration(node: SdsNamedType, context: ReferenceInfo): Scope { + // Default scope + let currentScope = this.coreDeclarations(SdsNamedTypeDeclaration, super.getScope(context)); + + // Type parameters (up to the containing type parameter) + const containingTypeParameter = getContainerOfType(node, isSdsTypeParameter); + if (containingTypeParameter) { + const allTypeParameters = getTypeParameters(containingTypeParameter?.$container); + const priorTypeParameters = allTypeParameters.slice(0, containingTypeParameter.$containerIndex); + currentScope = this.createScopeForNodes(priorTypeParameters, currentScope); + } + + return currentScope; } private getScopeForMemberAccessMember(node: SdsMemberAccess): Scope { diff --git a/packages/safe-ds-lang/src/language/typing/safe-ds-type-checker.ts b/packages/safe-ds-lang/src/language/typing/safe-ds-type-checker.ts index d8e88e438..dfc271efd 100644 --- a/packages/safe-ds-lang/src/language/typing/safe-ds-type-checker.ts +++ b/packages/safe-ds-lang/src/language/typing/safe-ds-type-checker.ts @@ -64,22 +64,8 @@ export class SafeDsTypeChecker { if (type === UnknownType || other === UnknownType) { return false; } else if (other instanceof TypeParameterType) { - const otherLowerBound = this.typeComputer().computeLowerBound(other); const otherUpperBound = this.typeComputer().computeUpperBound(other); - - if (!(type instanceof TypeParameterType)) { - return ( - this.isSubtypeOf(otherLowerBound, type, options) && this.isSubtypeOf(type, otherUpperBound, options) - ); - } - - const typeLowerBound = this.typeComputer().computeLowerBound(type); - const typeUpperBound = this.typeComputer().computeUpperBound(type); - - return ( - this.isSubtypeOf(otherLowerBound, typeLowerBound, options) && - this.isSubtypeOf(typeUpperBound, otherUpperBound, options) - ); + return this.isSubtypeOf(type, otherUpperBound, options); } else if (other instanceof UnionType) { return other.types.some((it) => this.isSubtypeOf(type, it, options)); } diff --git a/packages/safe-ds-lang/src/language/typing/safe-ds-type-computer.ts b/packages/safe-ds-lang/src/language/typing/safe-ds-type-computer.ts index a7aa70fa4..70a21488a 100644 --- a/packages/safe-ds-lang/src/language/typing/safe-ds-type-computer.ts +++ b/packages/safe-ds-lang/src/language/typing/safe-ds-type-computer.ts @@ -49,7 +49,6 @@ import { isSdsTypeArgument, isSdsTypeCast, isSdsTypeParameter, - isSdsTypeProjection, isSdsUnionType, isSdsYield, SdsAbstractResult, @@ -74,7 +73,6 @@ import { SdsType, SdsTypeArgument, SdsTypeParameter, - SdsTypeParameterBound, } from '../generated/ast.js'; import { getAssignees, @@ -187,9 +185,7 @@ export class SafeDsTypeComputer { } else if (isSdsType(node)) { return this.computeTypeOfType(node); } else if (isSdsTypeArgument(node)) { - return this.computeType(node.value); - } else if (isSdsTypeProjection(node)) { - return this.computeTypeOfType(node.type); + return this.computeTypeOfType(node.value); } /* c8 ignore start */ else { return UnknownType; } /* c8 ignore stop */ @@ -691,56 +687,6 @@ export class SafeDsTypeComputer { // Type parameter bounds // ----------------------------------------------------------------------------------------------------------------- - /** - * Returns the lower bound for the given input. If no lower bound is specified explicitly, the result is `Nothing`. - * If invalid lower bounds are specified (e.g. because of an unresolved reference or a cycle), `$unknown` is - * returned. The result is simplified as much as possible. - */ - computeLowerBound(nodeOrType: SdsTypeParameter | TypeParameterType, options: ComputeBoundOptions = {}): Type { - let type: TypeParameterType; - if (nodeOrType instanceof TypeParameterType) { - type = nodeOrType; - } else { - type = this.computeType(nodeOrType) as TypeParameterType; - } - - return this.doComputeLowerBound(type, new Set(), options); - } - - private doComputeLowerBound( - type: TypeParameterType, - visited: Set, - options: ComputeBoundOptions, - ): Type { - // Check for cycles - if (visited.has(type.declaration)) { - return UnknownType; - } - visited.add(type.declaration); - - const lowerBounds = TypeParameter.getLowerBounds(type.declaration); - if (isEmpty(lowerBounds)) { - return this.coreTypes.Nothing; - } - - const boundType = this.computeLowerBoundType(lowerBounds[0]!); - if (!(boundType instanceof NamedType)) { - return UnknownType; - } else if (options.stopAtTypeParameterType || !(boundType instanceof TypeParameterType)) { - return boundType; - } else { - return this.doComputeLowerBound(boundType, visited, options); - } - } - - private computeLowerBoundType(node: SdsTypeParameterBound): Type { - if (node.operator === 'super') { - return this.computeType(node.rightOperand); - } else { - return this.computeType(node.leftOperand?.ref); - } - } - /** * Returns the upper bound for the given input. If no upper bound is specified explicitly, the result is `Any?`. If * invalid upper bounds are specified, but are invalid (e.g. because of an unresolved reference or a cycle), @@ -754,41 +700,23 @@ export class SafeDsTypeComputer { type = this.computeType(nodeOrType) as TypeParameterType; } - const result = this.doComputeUpperBound(type, new Set(), options); + const result = this.doComputeUpperBound(type, options); return result.withExplicitNullability(result.isExplicitlyNullable || type.isExplicitlyNullable); } - private doComputeUpperBound( - type: TypeParameterType, - visited: Set, - options: ComputeBoundOptions, - ): Type { - // Check for cycles - if (visited.has(type.declaration)) { - return UnknownType; - } - visited.add(type.declaration); - - const upperBounds = TypeParameter.getUpperBounds(type.declaration); - if (isEmpty(upperBounds)) { + private doComputeUpperBound(type: TypeParameterType, options: ComputeBoundOptions): Type { + const upperBound = type.declaration.upperBound; + if (!upperBound) { return this.coreTypes.AnyOrNull; } - const boundType = this.computeUpperBoundType(upperBounds[0]!); + const boundType = this.computeType(upperBound); if (!(boundType instanceof NamedType)) { return UnknownType; } else if (options.stopAtTypeParameterType || !(boundType instanceof TypeParameterType)) { return boundType; } else { - return this.doComputeUpperBound(boundType, visited, options); - } - } - - private computeUpperBoundType(node: SdsTypeParameterBound): Type { - if (node.operator === 'sub') { - return this.computeType(node.rightOperand); - } else { - return this.computeType(node.leftOperand?.ref); + return this.doComputeUpperBound(boundType, options); } } diff --git a/packages/safe-ds-lang/src/language/validation/other/declarations/typeParameterBounds.ts b/packages/safe-ds-lang/src/language/validation/other/declarations/typeParameterBounds.ts deleted file mode 100644 index 4e4800e6a..000000000 --- a/packages/safe-ds-lang/src/language/validation/other/declarations/typeParameterBounds.ts +++ /dev/null @@ -1,44 +0,0 @@ -import { isSdsDeclaration, SdsTypeParameterBound } from '../../../generated/ast.js'; -import { getContainerOfType, ValidationAcceptor } from 'langium'; -import { NamedType, UnknownType } from '../../../typing/model.js'; -import { SafeDsServices } from '../../../safe-ds-module.js'; - -export const CODE_TYPE_PARAMETER_BOUND_LEFT_OPERAND = 'type-parameter-bound/left-operand'; -export const CODE_TYPE_PARAMETER_BOUND_RIGHT_OPERAND = 'type-parameter-bound/right-operand'; - -export const typeParameterBoundLeftOperandMustBeOwnTypeParameter = ( - node: SdsTypeParameterBound, - accept: ValidationAcceptor, -) => { - const typeParameter = node.leftOperand?.ref; - if (!typeParameter) { - return; - } - - const declarationWithConstraint = getContainerOfType(node.$container, isSdsDeclaration); - const declarationWithTypeParameters = getContainerOfType(typeParameter.$container, isSdsDeclaration); - - if (declarationWithConstraint !== declarationWithTypeParameters) { - accept('error', 'The left operand must refer to a type parameter of the declaration with the bound.', { - node, - property: 'leftOperand', - code: CODE_TYPE_PARAMETER_BOUND_LEFT_OPERAND, - }); - } -}; - -export const typeParameterBoundRightOperandMustBeNamedType = (services: SafeDsServices) => { - const typeComputer = services.types.TypeComputer; - - return (node: SdsTypeParameterBound, accept: ValidationAcceptor) => { - const boundType = typeComputer.computeType(node.rightOperand); - - if (boundType !== UnknownType && !(boundType instanceof NamedType)) { - accept('error', 'Bounds of type parameters must be named types.', { - node, - property: 'rightOperand', - code: CODE_TYPE_PARAMETER_BOUND_RIGHT_OPERAND, - }); - } - }; -}; diff --git a/packages/safe-ds-lang/src/language/validation/other/declarations/typeParameters.ts b/packages/safe-ds-lang/src/language/validation/other/declarations/typeParameters.ts index 9948d6036..0f2184879 100644 --- a/packages/safe-ds-lang/src/language/validation/other/declarations/typeParameters.ts +++ b/packages/safe-ds-lang/src/language/validation/other/declarations/typeParameters.ts @@ -4,132 +4,25 @@ import { isSdsClass, isSdsClassMember, isSdsDeclaration, - isSdsNamedType, isSdsNamedTypeDeclaration, isSdsParameter, isSdsParameterList, isSdsTypeArgument, - isSdsTypeParameter, isSdsUnionType, SdsClass, SdsDeclaration, SdsTypeParameter, - SdsTypeParameterBound, } from '../../../generated/ast.js'; import { isStatic, TypeParameter } from '../../../helpers/nodeProperties.js'; import { SafeDsServices } from '../../../safe-ds-module.js'; import { SafeDsNodeMapper } from '../../../helpers/safe-ds-node-mapper.js'; -import { UnknownType } from '../../../typing/model.js'; +import { NamedType, UnknownType } from '../../../typing/model.js'; -export const CODE_TYPE_PARAMETER_CYCLIC_BOUND = 'type-parameter/cyclic-bound'; -export const CODE_TYPE_PARAMETER_INCOMPATIBLE_BOUNDS = 'type-parameter/incompatible-bounds'; export const CODE_TYPE_PARAMETER_INSUFFICIENT_CONTEXT = 'type-parameter/insufficient-context'; -export const CODE_TYPE_PARAMETER_MULTIPLE_BOUNDS = 'type-parameter/multiple-bounds'; +export const CODE_TYPE_PARAMETER_UPPER_BOUND = 'type-parameter/upper-bound'; export const CODE_TYPE_PARAMETER_USAGE = 'type-parameter/usage'; export const CODE_TYPE_PARAMETER_VARIANCE = 'type-parameter/variance'; -export const typeParameterBoundMustBeAcyclic = (node: SdsTypeParameter, accept: ValidationAcceptor) => { - const lowerBound = TypeParameter.getLowerBounds(node)[0]; - if (lowerBound && !lowerTypeParameterBoundIsAcyclic(lowerBound)) { - accept('error', 'Bounds of type parameters must be acyclic.', { - node: lowerBound, - code: CODE_TYPE_PARAMETER_CYCLIC_BOUND, - }); - } - - const upperBound = TypeParameter.getUpperBounds(node)[0]; - if (upperBound && !upperTypeParameterBoundIsAcyclic(upperBound)) { - accept('error', 'Bounds of type parameters must be acyclic.', { - node: upperBound, - code: CODE_TYPE_PARAMETER_CYCLIC_BOUND, - }); - } -}; - -const lowerTypeParameterBoundIsAcyclic = (node: SdsTypeParameterBound): boolean => { - const visited = new Set(); - let current: SdsTypeParameterBound | undefined = node; - - while (current) { - const typeParameter = getBoundingTypeParameter(current, 'sub'); - if (!typeParameter) { - return true; - } else if (visited.has(typeParameter)) { - return false; - } - - visited.add(typeParameter); - current = TypeParameter.getLowerBounds(typeParameter)[0]; - } - - return true; -}; - -const upperTypeParameterBoundIsAcyclic = (node: SdsTypeParameterBound): boolean => { - const visited = new Set(); - let current: SdsTypeParameterBound | undefined = node; - - while (current) { - const typeParameter = getBoundingTypeParameter(current, 'super'); - if (!typeParameter) { - return true; - } else if (visited.has(typeParameter)) { - return false; - } - - visited.add(typeParameter); - current = TypeParameter.getUpperBounds(typeParameter)[0]; - } - - return true; -}; - -/** - * Returns the next type parameter to be visited when checking for cycles. - * - * @param node - * The current type parameter bound. - * - * @param invertedOperator - * The operator for the inverted bound direction ('sub' for lower bounds, 'super' for upper bounds). - */ -const getBoundingTypeParameter = ( - node: SdsTypeParameterBound, - invertedOperator: string, -): SdsTypeParameter | undefined => { - if (node.operator === invertedOperator) { - return node.leftOperand?.ref; - } else if (isSdsNamedType(node.rightOperand) && isSdsTypeParameter(node.rightOperand.declaration?.ref)) { - return node.rightOperand.declaration?.ref; - } else { - return undefined; - } -}; - -export const typeParameterBoundsMustBeCompatible = (services: SafeDsServices) => { - const typeChecker = services.types.TypeChecker; - const typeComputer = services.types.TypeComputer; - - return (node: SdsTypeParameter, accept: ValidationAcceptor) => { - const lowerBound = typeComputer.computeLowerBound(node); - if (lowerBound === UnknownType) { - return; - } - - const upperBound = typeComputer.computeUpperBound(node); - if (upperBound === UnknownType) { - return; - } - - if (!typeChecker.isSubtypeOf(lowerBound, upperBound)) { - accept('error', `The lower bound '${lowerBound}' is not assignable to the upper bound '${upperBound}'.`, { - node, - code: CODE_TYPE_PARAMETER_INCOMPATIBLE_BOUNDS, - }); - } - }; -}; - export const typeParameterMustHaveSufficientContext = (node: SdsTypeParameter, accept: ValidationAcceptor) => { const containingCallable = getContainerOfType(node, isSdsCallable); /* c8 ignore start */ @@ -162,29 +55,26 @@ export const typeParameterMustHaveSufficientContext = (node: SdsTypeParameter, a if (typeParameterHasInsufficientContext) { accept('error', 'Insufficient context to infer this type parameter.', { node, + property: 'name', code: CODE_TYPE_PARAMETER_INSUFFICIENT_CONTEXT, }); } }; -export const typeParameterMustNotHaveMultipleBounds = (node: SdsTypeParameter, accept: ValidationAcceptor) => { - TypeParameter.getLowerBounds(node) - .slice(1) - .forEach((it) => { - accept('error', `The type parameter '${node.name}' can only have a single lower bound.`, { - node: it, - code: CODE_TYPE_PARAMETER_MULTIPLE_BOUNDS, - }); - }); +export const typeParameterUpperBoundMustBeNamedType = (services: SafeDsServices) => { + const typeComputer = services.types.TypeComputer; - TypeParameter.getUpperBounds(node) - .slice(1) - .forEach((it) => { - accept('error', `The type parameter '${node.name}' can only have a single upper bound.`, { - node: it, - code: CODE_TYPE_PARAMETER_MULTIPLE_BOUNDS, + return (node: SdsTypeParameter, accept: ValidationAcceptor) => { + const boundType = typeComputer.computeType(node.upperBound); + + if (boundType !== UnknownType && !(boundType instanceof NamedType)) { + accept('error', 'The upper bound of a type parameter must be a named type.', { + node, + property: 'upperBound', + code: CODE_TYPE_PARAMETER_UPPER_BOUND, }); - }); + } + }; }; export const typeParameterMustBeUsedInCorrectPosition = (services: SafeDsServices) => { diff --git a/packages/safe-ds-lang/src/language/validation/safe-ds-validator.ts b/packages/safe-ds-lang/src/language/validation/safe-ds-validator.ts index 5636b91f8..f0deb8749 100644 --- a/packages/safe-ds-lang/src/language/validation/safe-ds-validator.ts +++ b/packages/safe-ds-lang/src/language/validation/safe-ds-validator.ts @@ -79,16 +79,10 @@ import { segmentShouldBeUsed, } from './other/declarations/segments.js'; import { - typeParameterBoundLeftOperandMustBeOwnTypeParameter, - typeParameterBoundRightOperandMustBeNamedType, -} from './other/declarations/typeParameterBounds.js'; -import { - typeParameterBoundMustBeAcyclic, - typeParameterBoundsMustBeCompatible, typeParameterMustBeUsedInCorrectPosition, typeParameterMustHaveSufficientContext, - typeParameterMustNotHaveMultipleBounds, typeParameterMustOnlyBeVariantOnClass, + typeParameterUpperBoundMustBeNamedType, } from './other/declarations/typeParameters.js'; import { callArgumentMustBeConstantIfParameterIsConstant, callMustNotBeRecursive } from './other/expressions/calls.js'; import { divisionDivisorMustNotBeZero } from './other/expressions/infixOperations.js'; @@ -353,16 +347,10 @@ export const registerValidationChecks = function (services: SafeDsServices) { SdsTemplateString: [templateStringMustHaveExpressionBetweenTwoStringParts], SdsTypeCast: [typeCastExpressionMustHaveUnknownType(services)], SdsTypeParameter: [ - typeParameterBoundMustBeAcyclic, - typeParameterBoundsMustBeCompatible(services), typeParameterMustBeUsedInCorrectPosition(services), typeParameterMustHaveSufficientContext, - typeParameterMustNotHaveMultipleBounds, typeParameterMustOnlyBeVariantOnClass, - ], - SdsTypeParameterBound: [ - typeParameterBoundLeftOperandMustBeOwnTypeParameter, - typeParameterBoundRightOperandMustBeNamedType(services), + typeParameterUpperBoundMustBeNamedType(services), ], SdsTypeParameterList: [ typeParameterListMustNotHaveRequiredTypeParametersAfterOptionalTypeParameters, diff --git a/packages/safe-ds-lang/tests/language/lsp/safe-ds-semantic-token-provider.test.ts b/packages/safe-ds-lang/tests/language/lsp/safe-ds-semantic-token-provider.test.ts index 9a19227b3..3eb440192 100644 --- a/packages/safe-ds-lang/tests/language/lsp/safe-ds-semantic-token-provider.test.ts +++ b/packages/safe-ds-lang/tests/language/lsp/safe-ds-semantic-token-provider.test.ts @@ -130,6 +130,15 @@ describe('SafeDsSemanticTokenProvider', async () => { `, expectedTokenTypes: [SemanticTokenTypes.enum], }, + { + testName: 'parameter bound', + code: ` + class C(p: Int) where { + <|p|> < 0 + } + `, + expectedTokenTypes: [SemanticTokenTypes.parameter], + }, { testName: 'reference', code: ` @@ -150,15 +159,6 @@ describe('SafeDsSemanticTokenProvider', async () => { `, expectedTokenTypes: [SemanticTokenTypes.typeParameter], }, - { - testName: 'type parameter constraint', - code: ` - class C where { - <|T|> sub C - } - `, - expectedTokenTypes: [SemanticTokenTypes.typeParameter], - }, { testName: 'yield', code: ` diff --git a/packages/safe-ds-lang/tests/language/typing/type checker/isSubOrSupertypeOf.test.ts b/packages/safe-ds-lang/tests/language/typing/type checker/isSubOrSupertypeOf.test.ts index 7041aaece..6a7d511ab 100644 --- a/packages/safe-ds-lang/tests/language/typing/type checker/isSubOrSupertypeOf.test.ts +++ b/packages/safe-ds-lang/tests/language/typing/type checker/isSubOrSupertypeOf.test.ts @@ -975,26 +975,10 @@ const typeParameterTypes = async (): Promise => { const code = ` class TestClass< Unbounded, - LowerBound, - UpperBound, - BothBounds, - - IndirectLowerBound, - IndirectUpperBound, - Cyclic, - Unresolved, - > where { - LowerBound super Number, UpperBound sub Number, - BothBounds super Int, - BothBounds sub Number, - - IndirectLowerBound super LowerBound, IndirectUpperBound sub UpperBound, - Cyclic sub Cyclic, - Unresolved super Unknown, Unresolved sub Unknown, - } + > `; const module = await getNodeOfType(services, code, isSdsModule); const classes = getModuleMembers(module).filter(isSdsClass); @@ -1003,12 +987,8 @@ const typeParameterTypes = async (): Promise => { const computeTypeOfTypeParameterWithName = computeTypeOfDeclarationWithName(typeParameters); const unbounded = computeTypeOfTypeParameterWithName('Unbounded'); - const lowerBound = computeTypeOfTypeParameterWithName('LowerBound'); const upperBound = computeTypeOfTypeParameterWithName('UpperBound'); - const bothBounds = computeTypeOfTypeParameterWithName('BothBounds'); - const indirectLowerBound = computeTypeOfTypeParameterWithName('IndirectLowerBound'); const indirectUpperBound = computeTypeOfTypeParameterWithName('IndirectUpperBound'); - const cyclic = computeTypeOfTypeParameterWithName('Cyclic'); const unresolved = computeTypeOfTypeParameterWithName('Unresolved'); return [ @@ -1018,36 +998,16 @@ const typeParameterTypes = async (): Promise => { type2: unbounded, expected: true, }, - { - type1: lowerBound, - type2: unbounded, - expected: true, - }, { type1: upperBound, type2: unbounded, expected: true, }, - { - type1: bothBounds, - type2: unbounded, - expected: true, - }, - { - type1: indirectLowerBound, - type2: unbounded, - expected: true, - }, { type1: indirectUpperBound, type2: unbounded, expected: true, }, - { - type1: cyclic, - type2: unbounded, - expected: false, - }, { type1: unresolved, type2: unbounded, @@ -1069,104 +1029,22 @@ const typeParameterTypes = async (): Promise => { expected: true, }, - // Compare to LowerBound - { - type1: unbounded, - type2: lowerBound, - expected: false, - }, - { - type1: lowerBound, - type2: lowerBound, - expected: true, - }, - { - type1: upperBound, - type2: lowerBound, - expected: false, - }, - { - type1: bothBounds, - type2: lowerBound, - expected: false, - }, - { - type1: indirectLowerBound, - type2: lowerBound, - expected: true, - }, - { - type1: indirectUpperBound, - type2: lowerBound, - expected: false, - }, - { - type1: cyclic, - type2: lowerBound, - expected: false, - }, - { - type1: unresolved, - type2: lowerBound, - expected: false, - }, - { - type1: coreTypes.AnyOrNull, - type2: lowerBound, - expected: true, - }, - { - type1: coreTypes.Number, - type2: lowerBound, - expected: true, - }, - { - type1: coreTypes.Number.withExplicitNullability(true), - type2: lowerBound, - expected: true, - }, - { - type1: coreTypes.Nothing, - type2: lowerBound, - expected: false, - }, - // Compare to UpperBound { type1: unbounded, type2: upperBound, expected: false, }, - { - type1: lowerBound, - type2: upperBound, - expected: false, - }, { type1: upperBound, type2: upperBound, expected: true, }, - { - type1: bothBounds, - type2: upperBound, - expected: true, - }, - { - type1: indirectLowerBound, - type2: upperBound, - expected: false, - }, { type1: indirectUpperBound, type2: upperBound, expected: true, }, - { - type1: cyclic, - type2: upperBound, - expected: false, - }, { type1: unresolved, type2: upperBound, @@ -1198,105 +1076,6 @@ const typeParameterTypes = async (): Promise => { expected: true, }, - // Compare to BothBounds - { - type1: unbounded, - type2: bothBounds, - expected: false, - }, - { - type1: lowerBound, - type2: bothBounds, - expected: false, - }, - { - type1: upperBound, - type2: bothBounds, - expected: false, - }, - { - type1: bothBounds, - type2: bothBounds, - expected: true, - }, - { - type1: indirectLowerBound, - type2: bothBounds, - expected: false, - }, - { - type1: indirectUpperBound, - type2: bothBounds, - expected: false, - }, - { - type1: cyclic, - type2: bothBounds, - expected: false, - }, - { - type1: unresolved, - type2: bothBounds, - expected: false, - }, - { - type1: coreTypes.AnyOrNull, - type2: bothBounds, - expected: false, - }, - { - type1: coreTypes.Number, - type2: bothBounds, - expected: true, - }, - { - type1: coreTypes.Number.withExplicitNullability(true), - type2: bothBounds, - expected: false, - }, - { - type1: coreTypes.Number.withExplicitNullability(true), - type2: bothBounds.withExplicitNullability(true), - expected: true, - }, - { - type1: coreTypes.Int, - type2: bothBounds, - expected: true, - }, - { - type1: coreTypes.Int.withExplicitNullability(true), - type2: bothBounds, - expected: false, - }, - { - type1: coreTypes.Int.withExplicitNullability(true), - type2: bothBounds.withExplicitNullability(true), - expected: true, - }, - { - type1: coreTypes.Nothing, - type2: bothBounds, - expected: false, - }, - - // Compare to IndirectLowerBound - { - type1: indirectLowerBound, - type2: indirectLowerBound, - expected: true, - }, - { - type1: coreTypes.AnyOrNull, - type2: indirectLowerBound, - expected: true, - }, - { - type1: coreTypes.Nothing, - type2: indirectLowerBound, - expected: false, - }, - // Compare to IndirectUpperBound { type1: indirectUpperBound, @@ -1314,26 +1093,9 @@ const typeParameterTypes = async (): Promise => { expected: true, }, - // Compare to Cyclic - { - type1: cyclic, - type2: cyclic, - expected: false, - }, - { - type1: coreTypes.AnyOrNull, - type2: cyclic, - expected: false, - }, - { - type1: coreTypes.Nothing, - type2: cyclic, - expected: false, - }, - // Compare to Unresolved { - type1: cyclic, + type1: upperBound, type2: unresolved, expected: false, }, @@ -1369,26 +1131,6 @@ const typeParameterTypes = async (): Promise => { type2: coreTypes.AnyOrNull, expected: true, }, - { - type1: lowerBound, - type2: coreTypes.Any, - expected: false, - }, - { - type1: lowerBound, - type2: coreTypes.AnyOrNull, - expected: true, - }, - { - type1: lowerBound.withExplicitNullability(true), - type2: coreTypes.Any, - expected: false, - }, - { - type1: lowerBound.withExplicitNullability(true), - type2: coreTypes.AnyOrNull, - expected: true, - }, { type1: upperBound, type2: coreTypes.Any, @@ -1419,36 +1161,6 @@ const typeParameterTypes = async (): Promise => { type2: coreTypes.Number, expected: false, }, - { - type1: bothBounds, - type2: coreTypes.Any, - expected: true, - }, - { - type1: bothBounds.withExplicitNullability(true), - type2: coreTypes.AnyOrNull, - expected: true, - }, - { - type1: bothBounds, - type2: coreTypes.Number, - expected: true, - }, - { - type1: bothBounds.withExplicitNullability(true), - type2: coreTypes.Any, - expected: false, - }, - { - type1: bothBounds.withExplicitNullability(true), - type2: coreTypes.AnyOrNull, - expected: true, - }, - { - type1: bothBounds.withExplicitNullability(true), - type2: coreTypes.Number, - expected: false, - }, ]; }; diff --git a/packages/safe-ds-lang/tests/language/typing/type computer/computeBound.test.ts b/packages/safe-ds-lang/tests/language/typing/type computer/computeUpperBound.test.ts similarity index 55% rename from packages/safe-ds-lang/tests/language/typing/type computer/computeBound.test.ts rename to packages/safe-ds-lang/tests/language/typing/type computer/computeUpperBound.test.ts index fdd344491..2019d451f 100644 --- a/packages/safe-ds-lang/tests/language/typing/type computer/computeBound.test.ts +++ b/packages/safe-ds-lang/tests/language/typing/type computer/computeUpperBound.test.ts @@ -17,26 +17,11 @@ const typeComputer = services.types.TypeComputer; const code = ` class MyClass< Unbounded, - LegalDirectBounds, - LegalIndirectBounds, - UnnamedBounds, - UnresolvedBounds, - CyclicBounds, - > where { - LegalDirectBounds super Int, LegalDirectBounds sub Number, - - LegalIndirectBounds super LegalDirectBounds, LegalIndirectBounds sub LegalDirectBounds, - - UnnamedBounds super literal<1>, UnnamedBounds sub literal<2>, - - UnresolvedBounds super unknown, UnresolvedBounds sub unknown, - - CyclicBounds sub CyclicBounds, - } + > `; const module = await getNodeOfType(services, code, isSdsModule); @@ -46,45 +31,10 @@ const typeParameters = getTypeParameters(classes[0]); const unbounded = typeParameters[0]!; const legalDirectBounds = typeParameters[1]!; const legalIndirectBounds = typeParameters[2]!; -const UnnamedBounds = typeParameters[3]!; -const UnresolvedBounds = typeParameters[4]!; -const CyclicBounds = typeParameters[5]!; +const unnamedBounds = typeParameters[3]!; +const unresolvedBounds = typeParameters[4]!; -const computeLowerBoundTests: ComputeBoundTest[] = [ - { - typeParameter: unbounded, - expected: coreTypes.Nothing, - }, - { - typeParameter: legalDirectBounds, - expected: coreTypes.Int, - }, - { - typeParameter: legalIndirectBounds, - expected: coreTypes.Int, - }, - { - typeParameter: UnnamedBounds, - expected: UnknownType, - }, - { - typeParameter: UnresolvedBounds, - expected: UnknownType, - }, - { - typeParameter: CyclicBounds, - expected: UnknownType, - }, -]; - -describe.each(computeLowerBoundTests)('computeLowerBound', ({ typeParameter, expected }) => { - it(`should return the lower bound (${typeParameter.name})`, () => { - const actual = typeComputer.computeLowerBound(typeParameter); - expectEqualTypes(actual, expected); - }); -}); - -const computeUpperBoundTests: ComputeBoundTest[] = [ +const computeUpperBoundTests: ComputeUpperBoundTest[] = [ { typeParameter: unbounded, expected: coreTypes.AnyOrNull, @@ -98,15 +48,11 @@ const computeUpperBoundTests: ComputeBoundTest[] = [ expected: coreTypes.Number, }, { - typeParameter: UnnamedBounds, - expected: UnknownType, - }, - { - typeParameter: UnresolvedBounds, + typeParameter: unnamedBounds, expected: UnknownType, }, { - typeParameter: CyclicBounds, + typeParameter: unresolvedBounds, expected: UnknownType, }, ]; @@ -119,9 +65,9 @@ describe.each(computeUpperBoundTests)('computeUpperBound', ({ typeParameter, exp }); /** - * A test case for {@link TypeComputer.computeLowerBound} and {@link TypeComputer.computeUpperBound}. + * A test case for {@link TypeComputer.computeUpperBound}. */ -interface ComputeBoundTest { +interface ComputeUpperBoundTest { /** * The type parameter to get the bound for. */ diff --git a/packages/safe-ds-lang/tests/resources/formatting/declarations/annotations/full.sdstest b/packages/safe-ds-lang/tests/resources/formatting/declarations/annotations/full.sdstest deleted file mode 100644 index 6240bd873..000000000 --- a/packages/safe-ds-lang/tests/resources/formatting/declarations/annotations/full.sdstest +++ /dev/null @@ -1,29 +0,0 @@ -package test - -@Annotation1 - -@Annotation2 - - annotation MyAnnotation ( - @Annotation3 a : Int , - const b : Int = 3 - ) -where { - T2 super Number , - T3 sub Number - } - -// ----------------------------------------------------------------------------- - -package test - -@Annotation1 -@Annotation2 -annotation MyAnnotation( - @Annotation3 - a: Int, - const b: Int = 3 -) where { - T2 super Number, - T3 sub Number -} diff --git a/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/sub constraint.sdstest b/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/greater than constraint.sdstest similarity index 62% rename from packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/sub constraint.sdstest rename to packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/greater than constraint.sdstest index 84f465805..20f9e558a 100644 --- a/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/sub constraint.sdstest +++ b/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/greater than constraint.sdstest @@ -1,7 +1,7 @@ -annotation MyAnnotation where { T sub Number } +annotation MyAnnotation where { p > 0 } // ----------------------------------------------------------------------------- annotation MyAnnotation where { - T sub Number + p > 0 } diff --git a/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/super constraint.sdstest b/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/greater than or equal constraint.sdstest similarity index 61% rename from packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/super constraint.sdstest rename to packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/greater than or equal constraint.sdstest index 5db455325..5a51d5c8c 100644 --- a/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/super constraint.sdstest +++ b/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/greater than or equal constraint.sdstest @@ -1,7 +1,7 @@ -annotation MyAnnotation where { T super Number } +annotation MyAnnotation where { p >= 0 } // ----------------------------------------------------------------------------- annotation MyAnnotation where { - T super Number + p >= 0 } diff --git a/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/less than constraint.sdstest b/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/less than constraint.sdstest new file mode 100644 index 000000000..aa2e4735a --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/less than constraint.sdstest @@ -0,0 +1,7 @@ +annotation MyAnnotation where { p < 0 } + +// ----------------------------------------------------------------------------- + +annotation MyAnnotation where { + p < 0 +} diff --git a/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/less than or equal constraint.sdstest b/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/less than or equal constraint.sdstest new file mode 100644 index 000000000..130c0d70b --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/less than or equal constraint.sdstest @@ -0,0 +1,7 @@ +annotation MyAnnotation where { p <= 0 } + +// ----------------------------------------------------------------------------- + +annotation MyAnnotation where { + p <= 0 +} diff --git a/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/multiple constraints.sdstest b/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/multiple constraints.sdstest index cae5c0389..f5414c717 100644 --- a/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/multiple constraints.sdstest +++ b/packages/safe-ds-lang/tests/resources/formatting/declarations/constraints/multiple constraints.sdstest @@ -1,8 +1,8 @@ -annotation MyAnnotation where { T sub Number , S super Number } +annotation MyAnnotation where { p < 0 , q > 1 } // ----------------------------------------------------------------------------- annotation MyAnnotation where { - T sub Number, - S super Number + p < 0, + q > 1 } diff --git a/packages/safe-ds-lang/tests/resources/formatting/trailing commas/constraint list of annotation.sdstest b/packages/safe-ds-lang/tests/resources/formatting/trailing commas/constraint list of annotation.sdstest index 688bbadc4..c1cdddce6 100644 --- a/packages/safe-ds-lang/tests/resources/formatting/trailing commas/constraint list of annotation.sdstest +++ b/packages/safe-ds-lang/tests/resources/formatting/trailing commas/constraint list of annotation.sdstest @@ -1,11 +1,11 @@ annotation A where { - T sub Any , - T super Int , + p < 0 , + q > 1 , } // ----------------------------------------------------------------------------- annotation A where { - T sub Any, - T super Int, + p < 0, + q > 1, } diff --git a/packages/safe-ds-lang/tests/resources/formatting/trailing commas/constraint list of class.sdstest b/packages/safe-ds-lang/tests/resources/formatting/trailing commas/constraint list of class.sdstest index 049700527..985fc61fc 100644 --- a/packages/safe-ds-lang/tests/resources/formatting/trailing commas/constraint list of class.sdstest +++ b/packages/safe-ds-lang/tests/resources/formatting/trailing commas/constraint list of class.sdstest @@ -1,11 +1,11 @@ -class C where { - T sub Any , - T super Int , +class C where { + p < 0 , + q > 1 , } // ----------------------------------------------------------------------------- -class C where { - T sub Any, - T super Int, +class C where { + p < 0, + q > 1, } diff --git a/packages/safe-ds-lang/tests/resources/formatting/trailing commas/constraint list of enum variant.sdstest b/packages/safe-ds-lang/tests/resources/formatting/trailing commas/constraint list of enum variant.sdstest index df3d52ad1..b44b943c5 100644 --- a/packages/safe-ds-lang/tests/resources/formatting/trailing commas/constraint list of enum variant.sdstest +++ b/packages/safe-ds-lang/tests/resources/formatting/trailing commas/constraint list of enum variant.sdstest @@ -1,7 +1,7 @@ enum E { A where { - T sub Any , - T super Int , + p < 0 , + q > 1 , } } @@ -9,7 +9,7 @@ enum E { enum E { A where { - T sub Any, - T super Int, + p < 0, + q > 1, } } diff --git a/packages/safe-ds-lang/tests/resources/formatting/trailing commas/constraint list of function.sdstest b/packages/safe-ds-lang/tests/resources/formatting/trailing commas/constraint list of function.sdstest index 59e36e1b7..e5ec138ef 100644 --- a/packages/safe-ds-lang/tests/resources/formatting/trailing commas/constraint list of function.sdstest +++ b/packages/safe-ds-lang/tests/resources/formatting/trailing commas/constraint list of function.sdstest @@ -1,11 +1,11 @@ -fun f() where { - T sub Any , - T super Int , +fun f() where { + p < 0 , + q > 1 , } // ----------------------------------------------------------------------------- -fun f() where { - T sub Any, - T super Int, +fun f() where { + p < 0, + q > 1, } diff --git a/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/bad-missing comma.sdstest b/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/bad-missing comma.sdstest index d6645383a..9eee0a233 100644 --- a/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/bad-missing comma.sdstest +++ b/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/bad-missing comma.sdstest @@ -1,6 +1,6 @@ // $TEST$ syntax_error annotation MyAnnotation where { - T sub Number - S super Number + p < 0 + q > 0 } diff --git a/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-sub constraint.sdstest b/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-greater than constraint.sdstest similarity index 78% rename from packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-sub constraint.sdstest rename to packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-greater than constraint.sdstest index a58135efb..1c940e1da 100644 --- a/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-sub constraint.sdstest +++ b/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-greater than constraint.sdstest @@ -1,5 +1,5 @@ // $TEST$ no_syntax_error annotation MyAnnotation where { - T sub Number + p > 0 } diff --git a/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-super constraint.sdstest b/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-greater than or equals constraint.sdstest similarity index 76% rename from packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-super constraint.sdstest rename to packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-greater than or equals constraint.sdstest index cc9f5c23d..8bde0690d 100644 --- a/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-super constraint.sdstest +++ b/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-greater than or equals constraint.sdstest @@ -1,5 +1,5 @@ // $TEST$ no_syntax_error annotation MyAnnotation where { - T super Number + p >= 0 } diff --git a/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-less than constraint.sdstest b/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-less than constraint.sdstest new file mode 100644 index 000000000..7665e1f67 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-less than constraint.sdstest @@ -0,0 +1,5 @@ +// $TEST$ no_syntax_error + +annotation MyAnnotation where { + p < 0 +} diff --git a/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-less than or equals constraint.sdstest b/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-less than or equals constraint.sdstest new file mode 100644 index 000000000..9c2063050 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-less than or equals constraint.sdstest @@ -0,0 +1,5 @@ +// $TEST$ no_syntax_error + +annotation MyAnnotation where { + p <= 0 +} diff --git a/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-multiple constraints.sdstest b/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-multiple constraints.sdstest index 3ef08442f..c20fe5b6c 100644 --- a/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-multiple constraints.sdstest +++ b/packages/safe-ds-lang/tests/resources/grammar/declarations/constraints/good-multiple constraints.sdstest @@ -1,6 +1,6 @@ // $TEST$ no_syntax_error annotation MyAnnotation where { - T sub Number, - S super Number + p < 0, + q > 0 } diff --git a/packages/safe-ds-lang/tests/resources/grammar/keywords as names/bad-unescaped super.sdstest b/packages/safe-ds-lang/tests/resources/grammar/keywords as names/bad-unescaped super.sdstest deleted file mode 100644 index 4d7c4ed36..000000000 --- a/packages/safe-ds-lang/tests/resources/grammar/keywords as names/bad-unescaped super.sdstest +++ /dev/null @@ -1,3 +0,0 @@ -// $TEST$ syntax_error - -class super diff --git a/packages/safe-ds-lang/tests/resources/grammar/keywords as names/good-escapedKeywords.sdstest b/packages/safe-ds-lang/tests/resources/grammar/keywords as names/good-escapedKeywords.sdstest index 10071f65a..b44cdb5f2 100644 --- a/packages/safe-ds-lang/tests/resources/grammar/keywords as names/good-escapedKeywords.sdstest +++ b/packages/safe-ds-lang/tests/resources/grammar/keywords as names/good-escapedKeywords.sdstest @@ -24,7 +24,6 @@ class `schema` class `static` class `segment` class `sub` -class `super` class `true` class `union` class `val` diff --git a/packages/safe-ds-lang/tests/resources/grammar/trailing commas/good-constraint list of annotation.sdstest b/packages/safe-ds-lang/tests/resources/grammar/trailing commas/good-constraint list of annotation.sdstest index 33f63690d..ab23f1ef7 100644 --- a/packages/safe-ds-lang/tests/resources/grammar/trailing commas/good-constraint list of annotation.sdstest +++ b/packages/safe-ds-lang/tests/resources/grammar/trailing commas/good-constraint list of annotation.sdstest @@ -1,6 +1,6 @@ // $TEST$ no_syntax_error annotation A where { - T sub Any, - T super Int, + p < 0, + q > 0, } diff --git a/packages/safe-ds-lang/tests/resources/grammar/trailing commas/good-constraint list of class.sdstest b/packages/safe-ds-lang/tests/resources/grammar/trailing commas/good-constraint list of class.sdstest index 8a0d0fd22..c3b80dd90 100644 --- a/packages/safe-ds-lang/tests/resources/grammar/trailing commas/good-constraint list of class.sdstest +++ b/packages/safe-ds-lang/tests/resources/grammar/trailing commas/good-constraint list of class.sdstest @@ -1,6 +1,6 @@ // $TEST$ no_syntax_error class C where { - T sub Any, - T super Int, + p < 0, + q > 0, } diff --git a/packages/safe-ds-lang/tests/resources/grammar/trailing commas/good-constraint list of enum variant.sdstest b/packages/safe-ds-lang/tests/resources/grammar/trailing commas/good-constraint list of enum variant.sdstest index b6c17a240..8330bbf56 100644 --- a/packages/safe-ds-lang/tests/resources/grammar/trailing commas/good-constraint list of enum variant.sdstest +++ b/packages/safe-ds-lang/tests/resources/grammar/trailing commas/good-constraint list of enum variant.sdstest @@ -2,7 +2,7 @@ enum E { A where { - T sub Any, - T super Int, + p < 0, + q > 0, } } diff --git a/packages/safe-ds-lang/tests/resources/grammar/trailing commas/good-constraint list of function.sdstest b/packages/safe-ds-lang/tests/resources/grammar/trailing commas/good-constraint list of function.sdstest index 418bb09a8..0520d7863 100644 --- a/packages/safe-ds-lang/tests/resources/grammar/trailing commas/good-constraint list of function.sdstest +++ b/packages/safe-ds-lang/tests/resources/grammar/trailing commas/good-constraint list of function.sdstest @@ -1,6 +1,6 @@ // $TEST$ no_syntax_error fun f() where { - T sub Any, - T super Int, + p < 0, + q > 0, } diff --git a/packages/safe-ds-lang/tests/resources/scoping/member accesses/on type parameters/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/member accesses/on type parameters/main.sdstest index ee0348077..4883da99b 100644 --- a/packages/safe-ds-lang/tests/resources/scoping/member accesses/on type parameters/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/scoping/member accesses/on type parameters/main.sdstest @@ -5,7 +5,7 @@ class C { attr »a«: Int } -class MyClass( +class MyClass( unbounded: Unbounded, upperBound: UpperBound, @@ -13,9 +13,7 @@ class MyClass( p1: Any = unbounded.»a«, // $TEST$ references attribute p2: Any = upperBound.»a«, -) where { - UpperBound sub C -} { +) { attr unbounded: Unbounded attr upperBound: UpperBound } diff --git a/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to containing named type declarations/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to containing named type declarations/main.sdstest index 7fc6e4ea9..6f334dada 100644 --- a/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to containing named type declarations/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to containing named type declarations/main.sdstest @@ -1,21 +1,27 @@ package tests.scoping.namedTypes.inSameFile.toContainingNamedTypeDeclarations // $TEST$ target outerClass -class »MyClass«( +class »MyClass«< + // $TEST$ references outerClass + T sub »MyClass« +>( // $TEST$ references outerClass p: »MyClass« // $TEST$ references outerClass -) sub »MyClass« where { - // $TEST$ references outerClass - T sub »MyClass« -} { +) sub »MyClass« { // $TEST$ references outerClass attr a1: »MyClass« // $TEST$ unresolved attr a2: »MyEnum« - fun f( + fun f< + // $TEST$ references outerClass + T1 sub »MyClass«, + + // $TEST$ unresolved + T2 sub »MyEnum«, + >( // $TEST$ references outerClass p1: »MyClass«, @@ -27,13 +33,7 @@ class »MyClass«( // $TEST$ unresolved r2: »MyEnum« - ) where { - // $TEST$ references outerClass - T sub »MyClass«, - - // $TEST$ unresolved - T sub »MyEnum«, - } + ) // $TEST$ target enum enum »MyEnum« { @@ -47,16 +47,7 @@ class »MyClass«( // $TEST$ references variant p3: »MyEnumVariant«, - ) where { - // $TEST$ references outerClass - T sub »MyClass«, - - // $TEST$ references enum - T sub »MyEnum«, - - // $TEST$ references variant - T sub »MyEnumVariant«, - } + ) } // $TEST$ target innerClass @@ -76,7 +67,13 @@ class »MyClass«( // $TEST$ unresolved attr a2: »MyEnum« - fun f( + fun f< + // $TEST$ references innerClass + T1 sub »MyClass«, + + // $TEST$ unresolved + T2 sub »MyEnum«, + >( // $TEST$ references innerClass p1: »MyClass«, @@ -88,12 +85,6 @@ class »MyClass«( // $TEST$ unresolved r2: »MyEnum«, - ) where { - // $TEST$ references innerClass - T sub »MyClass«, - - // $TEST$ unresolved - T sub »MyEnum«, - } + ) } } diff --git a/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in enum variants in nested enums/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in enum variants in nested enums/main.sdstest index aca49929f..94290c0c9 100644 --- a/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in enum variants in nested enums/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in enum variants in nested enums/main.sdstest @@ -17,19 +17,7 @@ class MyClass<»Container«> { // $TEST$ unresolved d: »Unresolved«, - ) where { - // $TEST$ references container - Own sub »Container«, - - // $TEST$ unresolved - Own sub »BeforeEnum«, - - // $TEST$ unresolved - Own sub »AfterEnum«, - - // $TEST$ unresolved - Own sub »Unresolved«, - } + ) } fun myFunction2() diff --git a/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in global classes/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in global classes/main.sdstest index 2f9b99849..c4dfd05f7 100644 --- a/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in global classes/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in global classes/main.sdstest @@ -2,35 +2,41 @@ package tests.scoping.namedTypes.inSameFile.toTypeParameter.inGlobalClasses fun myFunction1() -// $TEST$ target own -class MyClass<»Own«>( +class MyClass< + // $TEST$ target own + »Own«, + // $TEST$ references own - a: »Own«, + T1 sub »Own«, // $TEST$ unresolved - b: »Before«, + T2 sub »Before«, // $TEST$ unresolved - c: »After«, + T3 sub »After«, // $TEST$ unresolved - d: »Unresolved«, -) -// $TEST$ references own -sub »Own« -where { + T4 sub »Unresolved«, + + // $TEST$ unresolved + T5 sub »Forward«, + + Forward, +>( // $TEST$ references own - Own sub »Own«, + a: »Own«, // $TEST$ unresolved - Own sub »Before«, + b: »Before«, // $TEST$ unresolved - Own sub »After«, + c: »After«, // $TEST$ unresolved - Own sub »Unresolved«, -} { + d: »Unresolved«, +) +// $TEST$ references own +sub »Own« { // $TEST$ references own attr z: »Own« diff --git a/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in global functions/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in global functions/main.sdstest index a23203377..b53c31159 100644 --- a/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in global functions/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in global functions/main.sdstest @@ -2,8 +2,27 @@ package tests.scoping.namedTypes.inSameFile.toTypeParameter.inGlobalFunctions fun myFunction1() -// $TEST$ target own -fun myFunction2<»Own«>( +fun myFunction2< + // $TEST$ target own + »Own«, + + // $TEST$ references own + T1 sub »Own«, + + // $TEST$ unresolved + T2 sub »Before«, + + // $TEST$ unresolved + T3 sub »After«, + + // $TEST$ unresolved + T4 sub »Unresolved«, + + // $TEST$ unresolved + T5 sub »Forward«, + + Forward, +>( // $TEST$ references own a: »Own«, @@ -27,18 +46,6 @@ fun myFunction2<»Own«>( // $TEST$ unresolved w: »Unresolved« -) where { - // $TEST$ references own - Own sub »Own«, - - // $TEST$ unresolved - Own sub »Before«, - - // $TEST$ unresolved - Own sub »After«, - - // $TEST$ unresolved - Own sub »Unresolved« -} +) fun myFunction3() diff --git a/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in methods/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in methods/main.sdstest index 586f64614..47d173c4d 100644 --- a/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in methods/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in methods/main.sdstest @@ -6,9 +6,42 @@ fun myFunction1() class MyClass1<»Container«, Overridden> { fun myFunction2() - // $TEST$ target own - // $TEST$ target overridden - fun myFunction3<»Own«, »Overridden«>( + fun myFunction3< + // $TEST$ target own + »Own«, + + // $TEST$ target overridden + »Overridden«, + + // $TEST$ references own + T1 sub »Own«, + + // $TEST$ references overridden + T2 sub »Overridden«, + + // $TEST$ references container + T3 sub »Container«, + + // $TEST$ unresolved + T4 sub »BeforeMember«, + + // $TEST$ unresolved + T5 sub »AfterMember«, + + // $TEST$ unresolved + T6 sub »BeforeGlobal«, + + // $TEST$ unresolved + T7 sub »AfterGlobal«, + + // $TEST$ unresolved + T8 sub »Unresolved«, + + // $TEST$ unresolved + T9 sub »Forward«, + + Forward, + >( // $TEST$ references own a: »Own«, @@ -56,31 +89,7 @@ class MyClass1<»Container«, Overridden> { // $TEST$ unresolved s: »Unresolved«, - ) where { - // $TEST$ references own - Own sub »Own«, - - // $TEST$ references overridden - Own sub »Overridden«, - - // $TEST$ references container - Own sub »Container«, - - // $TEST$ unresolved - Own sub »BeforeMember«, - - // $TEST$ unresolved - Own sub »AfterMember«, - - // $TEST$ unresolved - Own sub »BeforeGlobal«, - - // $TEST$ unresolved - Own sub »AfterGlobal«, - - // $TEST$ unresolved - Own sub »Unresolved«, - } + ) fun myFunction5() } diff --git a/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in nested classes/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in nested classes/main.sdstest index 80b0e5dda..16e725658 100644 --- a/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in nested classes/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/scoping/named types/in same file/to type parameters/in nested classes/main.sdstest @@ -6,62 +6,71 @@ fun myFunction1() class MyClass1<»Container«, Overridden> { fun myFunction2() - // $TEST$ target own - // $TEST$ target overridden - class MyClass2<»Own«, »Overridden«>( + class MyClass2< + // $TEST$ target own + »Own«, + + // $TEST$ target overridden + »Overridden«, + // $TEST$ references own - a: »Own«, + T1 sub »Own«, // $TEST$ references overridden - b: »Overridden«, + T2 sub »Overridden«, // $TEST$ references container - c: »Container«, + T3 sub »Container«, // $TEST$ unresolved - d: »BeforeMember«, + T4 sub »BeforeMember«, // $TEST$ unresolved - e: »AfterMember«, + T5 sub »AfterMember«, // $TEST$ unresolved - f: »BeforeGlobal«, + T6 sub »BeforeGlobal«, // $TEST$ unresolved - g: »AfterGlobal«, + T7 sub »AfterGlobal«, // $TEST$ unresolved - h: »Unresolved«, - ) - // $TEST$ references own - // $TEST$ references overridden - // $TEST$ references container - sub »Own«, »Overridden«, »Container« - where { + T8 sub »Unresolved«, + + // $TEST$ unresolved + T9 sub »Forward«, + + Forward, + >( // $TEST$ references own - Own sub »Own«, + a: »Own«, // $TEST$ references overridden - Own sub »Overridden«, + b: »Overridden«, // $TEST$ references container - Own sub »Container«, + c: »Container«, // $TEST$ unresolved - Own sub »BeforeMember«, + d: »BeforeMember«, // $TEST$ unresolved - Own sub »AfterMember«, + e: »AfterMember«, // $TEST$ unresolved - Own sub »BeforeGlobal«, + f: »BeforeGlobal«, // $TEST$ unresolved - Own sub »AfterGlobal«, + g: »AfterGlobal«, // $TEST$ unresolved - Own sub »Unresolved«, - } { + h: »Unresolved«, + ) + // $TEST$ references own + // $TEST$ references overridden + // $TEST$ references container + sub »Own«, »Overridden«, »Container« + { // $TEST$ references own attr z: »Own« diff --git a/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in annotation/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in annotation/main.sdstest new file mode 100644 index 000000000..314584ad0 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in annotation/main.sdstest @@ -0,0 +1,27 @@ +package tests.scoping.parameterBounds.inAnnotation + +fun myFunction1(before: Int) + +annotation MyAnnotation( + // $TEST$ target own + »own«: Int +) where { + // $TEST$ references own + »own« < 0, + + // $TEST$ unresolved + »before« < 0, + + // $TEST$ unresolved + »after« < 0, + + // $TEST$ unresolved + »notAParameter« < 0, + + // $TEST$ unresolved + »unresolved« < 0 +} + +fun myFunction2(after: Int) + +class notAParameter diff --git a/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in enum variant in nested enum/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in enum variant in nested enum/main.sdstest new file mode 100644 index 000000000..16e0811f8 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in enum variant in nested enum/main.sdstest @@ -0,0 +1,34 @@ +package tests.scoping.parameterBounds.inEnumVariantInNestedEnum + +class MyClass(container: Int) { + fun myFunction1(beforeEnum: Int) + + enum MyEnum { + MyEnumVariant( + // $TEST$ target own + »own«: Int + ) where { + // $TEST$ references own + »own« < 0, + + // $TEST$ unresolved + »container« < 0, + + // $TEST$ unresolved + »beforeEnum« < 0, + + // $TEST$ unresolved + »afterEnum« < 0, + + // $TEST$ unresolved + »notAParameter« < 0, + + // $TEST$ unresolved + »unresolved« < 0 + } + } + + fun myFunction2(afterEnum: Int) +} + +class notAParameter diff --git a/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in global class/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in global class/main.sdstest new file mode 100644 index 000000000..e3ada2150 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in global class/main.sdstest @@ -0,0 +1,27 @@ +package tests.scoping.parameterBounds.inGlobalClass + +fun myFunction1(before: Int) + +class MyClass( + // $TEST$ target own + »own«: Int +) where { + // $TEST$ references own + »own« < 0, + + // $TEST$ unresolved + »before« < 0, + + // $TEST$ unresolved + »after« < 0, + + // $TEST$ unresolved + »notAParameter« < 0, + + // $TEST$ unresolved + »unresolved« < 0 +} + +fun myFunction2(after: Int) + +class notAParameter diff --git a/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in global function/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in global function/main.sdstest new file mode 100644 index 000000000..796412173 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in global function/main.sdstest @@ -0,0 +1,27 @@ +package tests.scoping.parameterBounds.inGlobalFunction + +fun myFunction1(before: Int) + +fun myFunction2( + // $TEST$ target own + »own«: Int +) where { + // $TEST$ references own + »own« < 0, + + // $TEST$ unresolved + »before« < 0, + + // $TEST$ unresolved + »after« < 0, + + // $TEST$ unresolved + »notAParameter« < 0, + + // $TEST$ unresolved + »unresolved« < 0 +} + +fun myFunction3(after: Int) + +class notAParameter diff --git a/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in method/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in method/main.sdstest new file mode 100644 index 000000000..3ea3d3bc5 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in method/main.sdstest @@ -0,0 +1,48 @@ +package tests.scoping.parameterBounds.inMethod + +fun myFunction1(beforeGlobal: Int) + +class MyClass1(container: Int, overridden: Int) { + fun myFunction2(beforeMember: Int) + + fun myFunction3( + // $TEST$ target own + »own«: Int, + + // $TEST$ target overridden + »overridden«: Int, + ) where { + // $TEST$ references own + »own« < 0, + + // $TEST$ references overridden + »overridden« < 0, + + // $TEST$ unresolved + »container« < 0, + + // $TEST$ unresolved + »beforeMember« < 0, + + // $TEST$ unresolved + »afterMember« < 0, + + // $TEST$ unresolved + »beforeGlobal« < 0, + + // $TEST$ unresolved + »afterGlobal« < 0, + + // $TEST$ unresolved + »notAParameter« < 0, + + // $TEST$ unresolved + »unresolved« < 0 + } + + fun myFunction5(afterMember: Int) +} + +fun myFunction5(afterGlobal: Int) + +class notAParameter diff --git a/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in nested class/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in nested class/main.sdstest new file mode 100644 index 000000000..1d4ec7481 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/scoping/parameter bounds/in nested class/main.sdstest @@ -0,0 +1,48 @@ +package tests.scoping.parameterBounds.inNestedClass + +fun myFunction1(beforeGlobal: Int) + +class MyClass1(container: Int, overridden: Int){ + fun myFunction2(beforeMember: Int) + + class MyClass2( + // $TEST$ target own + »own«: Int, + + // $TEST$ target overridden + »overridden«: Int, + ) where { + // $TEST$ references own + »own« < 0, + + // $TEST$ references overridden + »overridden« < 0, + + // $TEST$ unresolved + »container« < 0, + + // $TEST$ unresolved + »beforeMember« < 0, + + // $TEST$ unresolved + »afterMember« < 0, + + // $TEST$ unresolved + »beforeGlobal« < 0, + + // $TEST$ unresolved + »afterGlobal« < 0, + + // $TEST$ unresolved + »notAParameter« < 0, + + // $TEST$ unresolved + »unresolved« < 0 + } + + fun myFunction3(afterMember: Int) +} + +fun myFunction4(afterGlobal: Int) + +class notAParameter diff --git a/packages/safe-ds-lang/tests/resources/scoping/references/in same file/to parameters/from parameter bound/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/references/in same file/to parameters/from parameter bound/main.sdstest new file mode 100644 index 000000000..dfd795e31 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/scoping/references/in same file/to parameters/from parameter bound/main.sdstest @@ -0,0 +1,39 @@ +package tests.scoping.references.inSameFile.toParameters.fromParameterBound + +// $TEST$ target annotation_p +annotation MyAnnotation(»p«: Int) where { + // $TEST$ references annotation_p + p < »p«, + + // $TEST$ unresolved + p > »unresolved«, +} + +// $TEST$ target class_p +class MyClass(»p«: Int) where { + // $TEST$ references class_p + p < »p«, + + // $TEST$ unresolved + p > »unresolved«, +} + +// $TEST$ target enumVariant_p +enum MyEnum { + MyEnumVariant(»p«: Int) where { + // $TEST$ references enumVariant_p + p < »p«, + + // $TEST$ unresolved + p > »unresolved«, + } +} + +// $TEST$ target function_p +fun myFunction(»p«: Int) where { + // $TEST$ references function_p + p < »p«, + + // $TEST$ unresolved + p > »unresolved«, +} diff --git a/packages/safe-ds-lang/tests/resources/scoping/type arguments/to type parameter in containing named type declaration/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/type arguments/to type parameter in containing named type declaration/main.sdstest index ac00229ff..fa3253f8f 100644 --- a/packages/safe-ds-lang/tests/resources/scoping/type arguments/to type parameter in containing named type declaration/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/scoping/type arguments/to type parameter in containing named type declaration/main.sdstest @@ -6,11 +6,7 @@ class MyClass<»T«>( p: MyClass<»T« = Int>, // $TEST$ references outerClass -) sub MyClass<»T« = Int> where { - - // $TEST$ references outerClass - T sub MyClass<»T« = Int>, -} { +) sub MyClass<»T« = Int> { // $TEST$ references outerClass attr a: MyClass<»T« = Int> @@ -20,19 +16,13 @@ class MyClass<»T«>( ) -> ( // $TEST$ references outerClass r: MyClass<»T« = Int>, - ) where { - // $TEST$ references outerClass - T sub MyClass<»T« = Int>, - } + ) enum MyEnum { MyEnumVariant( // $TEST$ references outerClass p: MyClass<»T« = Int>, - ) where { - // $TEST$ references outerClass - T sub MyClass<»T« = Int>, - } + ) } // $TEST$ target innerClass @@ -51,9 +41,6 @@ class MyClass<»T«>( ) -> ( // $TEST$ references innerClass r: MyClass<»T« = Int>, - ) where { - // $TEST$ references innerClass - T sub MyClass<»T« = Int>, - } + ) } } diff --git a/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in annotation/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in annotation/main.sdstest deleted file mode 100644 index 6b11ada09..000000000 --- a/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in annotation/main.sdstest +++ /dev/null @@ -1,21 +0,0 @@ -package tests.scoping.typeParameterBounds.inAnnotation - -fun myFunction1() - -annotation MyAnnotation where { - // $TEST$ unresolved - »Before« sub Int, - - // $TEST$ unresolved - »After« sub Int, - - // $TEST$ unresolved - »NotATypeParameter« sub Int, - - // $TEST$ unresolved - »Unresolved« sub Int -} - -fun myFunction2() - -class NotATypeParameter diff --git a/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in enum variant in nested enum/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in enum variant in nested enum/main.sdstest deleted file mode 100644 index 70dee5a77..000000000 --- a/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in enum variant in nested enum/main.sdstest +++ /dev/null @@ -1,29 +0,0 @@ -package tests.scoping.typeParameterBounds.inEnumVariantInNestedEnum - -// $TEST$ target container -class MyClass<»Container«> { - fun myFunction1() - - enum MyEnum { - MyEnumVariant where { - // $TEST$ references container - »Container« sub Int, - - // $TEST$ unresolved - »BeforeEnum« sub Int, - - // $TEST$ unresolved - »AfterEnum« sub Int, - - // $TEST$ unresolved - »NotATypeParameter« sub Int, - - // $TEST$ unresolved - »Unresolved« sub Int - } - } - - fun myFunction2() -} - -class NotATypeParameter diff --git a/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in global class/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in global class/main.sdstest deleted file mode 100644 index b74f0daa7..000000000 --- a/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in global class/main.sdstest +++ /dev/null @@ -1,25 +0,0 @@ -package tests.scoping.typeParameterBounds.inGlobalClass - -fun myFunction1() - -// $TEST$ target own -class MyClass<»Own«> where { - // $TEST$ references own - »Own« sub Int, - - // $TEST$ unresolved - »Before« sub Int, - - // $TEST$ unresolved - »After« sub Int, - - // $TEST$ unresolved - »NotATypeParameter« sub Int, - - // $TEST$ unresolved - »Unresolved« sub Int -} - -fun myFunction2() - -class NotATypeParameter diff --git a/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in global function/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in global function/main.sdstest deleted file mode 100644 index 83d8ab8a8..000000000 --- a/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in global function/main.sdstest +++ /dev/null @@ -1,25 +0,0 @@ -package tests.scoping.typeParameterBounds.inGlobalFunction - -fun myFunction1() - -// $TEST$ target own -fun myFunction2<»Own«>() where { - // $TEST$ references own - »Own« sub Int, - - // $TEST$ unresolved - »Before« sub Int, - - // $TEST$ unresolved - »After« sub Int, - - // $TEST$ unresolved - »NotATypeParameter« sub Int, - - // $TEST$ unresolved - »Unresolved« sub Int -} - -fun myFunction3() - -class NotATypeParameter diff --git a/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in method/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in method/main.sdstest deleted file mode 100644 index a5b3bc909..000000000 --- a/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in method/main.sdstest +++ /dev/null @@ -1,45 +0,0 @@ -package tests.scoping.typeParameterBounds.inMethod - -fun myFunction1() - -// $TEST$ target container -class MyClass1<»Container«, Overridden> { - fun myFunction2() - - // $TEST$ target own - // $TEST$ target overridden - fun myFunction3<»Own«, »Overridden«>() where { - // $TEST$ references own - »Own« sub Int, - - // $TEST$ references overridden - »Overridden« sub Int, - - // $TEST$ references container - »Container« sub Int, - - // $TEST$ unresolved - »BeforeMember« sub Int, - - // $TEST$ unresolved - »AfterMember« sub Int, - - // $TEST$ unresolved - »BeforeGlobal« sub Int, - - // $TEST$ unresolved - »AfterGlobal« sub Int, - - // $TEST$ unresolved - »NotATypeParameter« sub Int, - - // $TEST$ unresolved - »Unresolved« sub Int - } - - fun myFunction5() -} - -fun myFunction5() - -class NotATypeParameter diff --git a/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in nested class/main.sdstest b/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in nested class/main.sdstest deleted file mode 100644 index b91c18763..000000000 --- a/packages/safe-ds-lang/tests/resources/scoping/type parameter bounds/in nested class/main.sdstest +++ /dev/null @@ -1,45 +0,0 @@ -package tests.scoping.typeParameterBounds.inNestedClass - -fun myFunction1() - -// $TEST$ target container -class MyClass1<»Container«, Overridden> { - fun myFunction2() - - // $TEST$ target own - // $TEST$ target overridden - class MyClass2<»Own«, »Overridden«> where { - // $TEST$ references own - »Own« sub Int, - - // $TEST$ references overridden - »Overridden« sub Int, - - // $TEST$ references container - »Container« sub Int, - - // $TEST$ unresolved - »BeforeMember« sub Int, - - // $TEST$ unresolved - »AfterMember« sub Int, - - // $TEST$ unresolved - »BeforeGlobal« sub Int, - - // $TEST$ unresolved - »AfterGlobal« sub Int, - - // $TEST$ unresolved - »NotATypeParameter« sub Int, - - // $TEST$ unresolved - »Unresolved« sub Int - } - - fun myFunction3() -} - -fun myFunction4() - -class NotATypeParameter diff --git a/packages/safe-ds-lang/tests/resources/typing/expressions/indexed accesses/on lists/main.sdstest b/packages/safe-ds-lang/tests/resources/typing/expressions/indexed accesses/on lists/main.sdstest index 9b4231c88..99e63e19a 100644 --- a/packages/safe-ds-lang/tests/resources/typing/expressions/indexed accesses/on lists/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/typing/expressions/indexed accesses/on lists/main.sdstest @@ -41,7 +41,7 @@ segment mySegment(param1: List, param2: List?, param3: IntList) { »param3?[unresolved]«; } -class MyClass( +class MyClass, MyNullableList sub List?>( param1: MyList, param2: MyList?, param3: MyNullableList, @@ -82,7 +82,4 @@ class MyClass( // $TEST$ serialization Int? p12: Any? = »param3?[unresolved]«, -) where { - MyList sub List, - MyNullableList sub List?, -} +) diff --git a/packages/safe-ds-lang/tests/resources/typing/expressions/indexed accesses/on maps/main.sdstest b/packages/safe-ds-lang/tests/resources/typing/expressions/indexed accesses/on maps/main.sdstest index 2bec3a515..b55e8e772 100644 --- a/packages/safe-ds-lang/tests/resources/typing/expressions/indexed accesses/on maps/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/typing/expressions/indexed accesses/on maps/main.sdstest @@ -41,7 +41,7 @@ segment mySegment(param1: Map, param2: Map?, param3: M »param3?[unresolved]«; } -class MyClass( +class MyClass, MyNullableMap sub Map?>( param1: MyMap, param2: MyMap?, param3: MyNullableMap, @@ -82,7 +82,4 @@ class MyClass( // $TEST$ serialization Int? p12: Any? = »param3?[unresolved]«, -) where { - MyMap sub Map, - MyNullableMap sub Map?, -} +) diff --git a/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/class type and type parameter type/main.sdstest b/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/class type and type parameter type/main.sdstest index 87853362e..462677cca 100644 --- a/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/class type and type parameter type/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/class type and type parameter type/main.sdstest @@ -3,7 +3,7 @@ package tests.typing.lowestCommonSupertype.classTypeAndTypeParameterType class C class D -class Test( +class Test( c: C, unbounded: Unbounded, @@ -22,8 +22,4 @@ class Test( p4: Any = »[c, boundedByD]«, // $TEST$ serialization List p5: Any = »[c, boundedByDOrNull]«, -) where { - BoundedByC sub C, - BoundedByD sub D, - BoundedByDOrNull sub D?, -} +) diff --git a/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/enum type and type parameter type/main.sdstest b/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/enum type and type parameter type/main.sdstest index 633c35e72..bd98fa2f3 100644 --- a/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/enum type and type parameter type/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/enum type and type parameter type/main.sdstest @@ -6,7 +6,13 @@ enum E { enum F -class Test( +class Test< + Unbounded, + BoundedByEnum sub E, + BoundedByEnumVariant sub E.V, + BoundedByOtherEnum sub F, + BoundedByOtherEnumOrNull sub F? +>( e: E, unbounded: Unbounded, @@ -28,9 +34,4 @@ class Test p6: Any = »[e, boundedByOtherEnumOrNull]«, -) where { - BoundedByEnum sub E, - BoundedByEnumVariant sub E.V, - BoundedByOtherEnum sub F, - BoundedByOtherEnumOrNull sub F?, -} +) diff --git a/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/enum variant type and type parameter type/main.sdstest b/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/enum variant type and type parameter type/main.sdstest index bcac6b659..4fc207332 100644 --- a/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/enum variant type and type parameter type/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/enum variant type and type parameter type/main.sdstest @@ -5,7 +5,12 @@ enum E { V2 } -class D( +class D< + Unbounded, + BoundedByEnumVariant sub E.V1, + BoundedByOtherEnumVariant sub E.V2, + BoundedByOtherEnumVariantOrNull sub E.V2? +>( v: E.V1, unbounded: Unbounded, @@ -24,8 +29,4 @@ class D p5: Any = »[v, boundedByOtherEnumVariantOrNull]«, -) where { - BoundedByEnumVariant sub E.V1, - BoundedByOtherEnumVariant sub E.V2, - BoundedByOtherEnumVariantOrNull sub E.V2? -} +) diff --git a/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/literal type and type parameter type/main.sdstest b/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/literal type and type parameter type/main.sdstest index fd6ccaeaf..c883c0738 100644 --- a/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/literal type and type parameter type/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/literal type and type parameter type/main.sdstest @@ -1,6 +1,11 @@ package tests.typing.lowestCommonSupertype.literalTypeAndTypeParameterType -class Test( +class Test< + Unbounded, + BoundedByInt sub Int, + BoundedByString sub String, + BoundedByStringOrNull sub String? +>( unbounded: Unbounded, unboundedOrNull: Unbounded?, boundedByInt: BoundedByInt, @@ -17,8 +22,4 @@ class Test( p4: Any = »[1, boundedByString]«, // $TEST$ serialization List p5: Any = »[1, boundedByStringOrNull]«, -) where { - BoundedByInt sub Int, - BoundedByString sub String, - BoundedByStringOrNull sub String?, -} +) diff --git a/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/type parameter type and type parameter type/main.sdstest b/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/type parameter type and type parameter type/main.sdstest index 11fca4516..0dbef9256 100644 --- a/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/type parameter type and type parameter type/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/typing/lowest common supertype/type parameter type and type parameter type/main.sdstest @@ -3,13 +3,13 @@ package tests.typing.lowestCommonSupertype.typeParameterTypeAndTypeParameterType class C class D sub C class E sub C +class F -class Test( +class Test( nothingToAnyOrNull: NothingToAnyOrNull, nothingToD: NothingToD, nothingToE: NothingToE, - dToAnyOrNull: DToAnyOrNull, - dToC: DToC, + nothingToF: NothingToF, // $TEST$ serialization List a1: Any = »[nothingToAnyOrNull, nothingToAnyOrNull]«, @@ -18,37 +18,20 @@ class Test( // $TEST$ serialization List a3: Any = »[nothingToAnyOrNull, nothingToE]«, // $TEST$ serialization List - a4: Any = »[nothingToAnyOrNull, dToAnyOrNull]«, - // $TEST$ serialization List - a5: Any = »[nothingToAnyOrNull, dToC]«, + a4: Any = »[nothingToAnyOrNull, nothingToF]«, // $TEST$ serialization List b1: Any = »[nothingToD, nothingToD]«, // $TEST$ serialization List b2: Any = »[nothingToD, nothingToE]«, - // $TEST$ serialization List - b3: Any = »[nothingToD, dToAnyOrNull]«, - // $TEST$ serialization List - b4: Any = »[nothingToD, dToC]«, + // $TEST$ serialization List + b3: Any = »[nothingToD, nothingToF]«, // $TEST$ serialization List c1: Any = »[nothingToE, nothingToE]«, - // $TEST$ serialization List - c2: Any = »[nothingToE, dToAnyOrNull]«, - // $TEST$ serialization List - c3: Any = »[nothingToE, dToC]«, - - // $TEST$ serialization List - d1: Any = »[dToAnyOrNull, dToAnyOrNull]«, - // $TEST$ serialization List - d2: Any = »[dToAnyOrNull, dToC]«, + // $TEST$ serialization List + c2: Any = »[nothingToE, nothingToF]«, - // $TEST$ serialization List - e1: Any = »[dToC, dToC]«, -) where { - NothingToD sub D, - NothingToE sub E, - DToAnyOrNull super D, - DToC super D, - DToC sub C, -} + // $TEST$ serialization List + d1: Any = »[nothingToF, nothingToF]« +) diff --git a/packages/safe-ds-lang/tests/resources/typing/simplification/remove unneeded entries from union types/main.sdstest b/packages/safe-ds-lang/tests/resources/typing/simplification/remove unneeded entries from union types/main.sdstest index 3f35841d9..06d603687 100644 --- a/packages/safe-ds-lang/tests/resources/typing/simplification/remove unneeded entries from union types/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/typing/simplification/remove unneeded entries from union types/main.sdstest @@ -72,7 +72,7 @@ class TestsInvolvingNothing( p6: »union<() -> (), Nothing?>«, ) -class TestsInvolvingTypeParameters( +class TestsInvolvingTypeParameters( // $TEST$ serialization Unbounded a1: »union«, // $TEST$ serialization Unbounded @@ -123,39 +123,4 @@ class TestsInvolvingTypeParameters( b11: »union«, // $TEST$ serialization Any? b12: »union«, - - - // $TEST$ serialization union - c1: »union«, - // $TEST$ serialization union - c2: »union«, - - // $TEST$ serialization union - c3: »union«, - // $TEST$ serialization union - c4: »union«, - - // $TEST$ serialization BothBounds - c5: »union«, - // $TEST$ serialization BothBounds - c6: »union«, - - // $TEST$ serialization BothBounds - c7: »union«, - // $TEST$ serialization BothBounds - c8: »union«, - - // $TEST$ serialization BothBounds - c9: »union«, - // $TEST$ serialization BothBounds - c10: »union«, - - // $TEST$ serialization BothBounds? - c11: »union«, - // $TEST$ serialization BothBounds? - c12: »union«, -) where { - UpperBound sub Number, - BothBounds super Int, - BothBounds sub Any, -} +) diff --git a/packages/safe-ds-lang/tests/resources/validation/other/declarations/constraints/type parameter bounds/left operand must be own type parameter/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/other/declarations/constraints/type parameter bounds/left operand must be own type parameter/main.sdstest deleted file mode 100644 index fb5461869..000000000 --- a/packages/safe-ds-lang/tests/resources/validation/other/declarations/constraints/type parameter bounds/left operand must be own type parameter/main.sdstest +++ /dev/null @@ -1,61 +0,0 @@ -package tests.validation.other.declarations.constraints.typeParameterBounds.leftOperandMustBeOwnTypeParameter - -annotation MyAnnotation where { - // $TEST$ no error "The left operand must refer to a type parameter of the declaration with the bound." - »Unresolved« sub MyGlobalClass, -} - -class MyGlobalClass where { - // $TEST$ no error "The left operand must refer to a type parameter of the declaration with the bound." - »T1« sub MyGlobalClass, - - // $TEST$ no error "The left operand must refer to a type parameter of the declaration with the bound." - »Unresolved« sub MyGlobalClass -} { - class MyNestedClass where { - // $TEST$ error "The left operand must refer to a type parameter of the declaration with the bound." - »T1« sub MyGlobalClass, - - // $TEST$ no error "The left operand must refer to a type parameter of the declaration with the bound." - »T2« sub MyGlobalClass, - - // $TEST$ no error "The left operand must refer to a type parameter of the declaration with the bound." - »Unresolved« sub MyGlobalClass, - } - - enum MyNestedEnum { - MyEnumVariant where { - // $TEST$ error "The left operand must refer to a type parameter of the declaration with the bound." - »T1« sub MyGlobalClass, - - // $TEST$ no error "The left operand must refer to a type parameter of the declaration with the bound." - »Unresolved« sub MyGlobalClass, - } - } - - fun myMethod() where { - // $TEST$ error "The left operand must refer to a type parameter of the declaration with the bound." - »T1« sub MyGlobalClass, - - // $TEST$ no error "The left operand must refer to a type parameter of the declaration with the bound." - »T2« sub MyGlobalClass, - - // $TEST$ no error "The left operand must refer to a type parameter of the declaration with the bound." - »Unresolved« sub MyGlobalClass, - } -} - -enum MyGlobalEnum { - MyEnumVariant where { - // $TEST$ no error "The left operand must refer to a type parameter of the declaration with the bound." - »Unresolved« sub MyGlobalClass, - } -} - -fun myGlobalFunction() where { - // $TEST$ no error "The left operand must refer to a type parameter of the declaration with the bound." - »T1« sub MyGlobalClass, - - // $TEST$ no error "The left operand must refer to a type parameter of the declaration with the bound." - »Unresolved« sub MyGlobalClass, -} diff --git a/packages/safe-ds-lang/tests/resources/validation/other/declarations/constraints/type parameter bounds/right operand must be named type/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/other/declarations/constraints/type parameter bounds/right operand must be named type/main.sdstest deleted file mode 100644 index 7bed22f10..000000000 --- a/packages/safe-ds-lang/tests/resources/validation/other/declarations/constraints/type parameter bounds/right operand must be named type/main.sdstest +++ /dev/null @@ -1,102 +0,0 @@ -package tests.validation.other.declarations.typeParameters.rightOperandMustBeNamedType - -class C -enum E { - V -} - -class MyClass1 where { - // $TEST$ error "Bounds of type parameters must be named types." - T sub »() -> ()«, - // $TEST$ error "Bounds of type parameters must be named types." - T sub »() -> ()«, - - // $TEST$ error "Bounds of type parameters must be named types." - T super »() -> ()«, - // $TEST$ error "Bounds of type parameters must be named types." - T super »() -> ()«, -} - -class MyClass2 where { - // $TEST$ error "Bounds of type parameters must be named types." - T sub »literal<1>«, - // $TEST$ error "Bounds of type parameters must be named types." - T sub »literal<1>«, - - // $TEST$ error "Bounds of type parameters must be named types." - T super »literal<1>«, - // $TEST$ error "Bounds of type parameters must be named types." - T super »literal<1>«, -} - -class MyClass3 where { - // $TEST$ no error "Bounds of type parameters must be named types." - T sub »C«, - // $TEST$ no error "Bounds of type parameters must be named types." - T sub »C«, - - // $TEST$ no error "Bounds of type parameters must be named types." - T super »C«, - // $TEST$ no error "Bounds of type parameters must be named types." - T super »C«, -} - -class MyClass4 where { - // $TEST$ no error "Bounds of type parameters must be named types." - T sub »E«, - // $TEST$ no error "Bounds of type parameters must be named types." - T sub »E«, - - // $TEST$ no error "Bounds of type parameters must be named types." - T super »E«, - // $TEST$ no error "Bounds of type parameters must be named types." - T super »E«, -} - -class MyClass5 where { - // $TEST$ no error "Bounds of type parameters must be named types." - T sub »E.V«, - // $TEST$ no error "Bounds of type parameters must be named types." - T sub »E.V«, - - // $TEST$ no error "Bounds of type parameters must be named types." - T super »E.V«, - // $TEST$ no error "Bounds of type parameters must be named types." - T super »E.V«, -} - -class MyClass6 where { - // $TEST$ no error "Bounds of type parameters must be named types." - T1 sub »T2«, - // $TEST$ no error "Bounds of type parameters must be named types." - T1 sub »T2«, - - // $TEST$ no error "Bounds of type parameters must be named types." - T1 super »T2«, - // $TEST$ no error "Bounds of type parameters must be named types." - T1 super »T2«, -} - -class MyClass7 where { - // $TEST$ error "Bounds of type parameters must be named types." - T sub »union«, - // $TEST$ error "Bounds of type parameters must be named types." - T sub »union«, - - // $TEST$ error "Bounds of type parameters must be named types." - T super »union«, - // $TEST$ error "Bounds of type parameters must be named types." - T super »union«, -} - -class MyClass8 where { - // $TEST$ no error "Bounds of type parameters must be named types." - T sub »Unresolved«, - // $TEST$ no error "Bounds of type parameters must be named types." - T sub »Unresolved«, - - // $TEST$ no error "Bounds of type parameters must be named types." - T super »Unresolved«, - // $TEST$ no error "Bounds of type parameters must be named types." - T super »Unresolved«, -} diff --git a/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/bounds must be acyclic/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/bounds must be acyclic/main.sdstest deleted file mode 100644 index 0d8f8fc90..000000000 --- a/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/bounds must be acyclic/main.sdstest +++ /dev/null @@ -1,27 +0,0 @@ -package tests.validation.other.declarations.typeParameters.boundsMustBeAcyclic - -class C where { - // $TEST$ no error "Bounds of type parameters must be acyclic." - »T1 super Int«, - // $TEST$ no error "Bounds of type parameters must be acyclic." - »T1 sub Number«, - // $TEST$ no error "Bounds of type parameters must be acyclic." - »T1 super T1«, - // $TEST$ no error "Bounds of type parameters must be acyclic." - »T1 sub T1«, - - // $TEST$ error "Bounds of type parameters must be acyclic." - »T2 super T2«, - // $TEST$ error "Bounds of type parameters must be acyclic." - »T3 sub T3«, - - // $TEST$ error "Bounds of type parameters must be acyclic." - »T4 super T3«, - // $TEST$ error "Bounds of type parameters must be acyclic." - »T5 sub T3«, - - // $TEST$ no error "Bounds of type parameters must be acyclic." - »T6 super unknown«, - // $TEST$ no error "Bounds of type parameters must be acyclic." - »T6 sub unknown«, -} diff --git a/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/insufficient context/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/insufficient context/main.sdstest index 245ee9cf4..be989fcdb 100644 --- a/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/insufficient context/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/insufficient context/main.sdstest @@ -3,13 +3,13 @@ package tests.validation.other.declarations.typeParameters.insufficientContext // $TEST$ no error "Insufficient context to infer this type parameter." class MyClass1<»T«> // $TEST$ error "Insufficient context to infer this type parameter." -class MyClass2<»T«>() +class MyClass2<»T« sub Int>() // $TEST$ error "Insufficient context to infer this type parameter." class MyClass3<»T«>() { attr myAttr: T } // $TEST$ no error "Insufficient context to infer this type parameter." -class MyClass4<»T«>(param: T) +class MyClass4<»T« sub Int>(param: T) // $TEST$ no error "Insufficient context to infer this type parameter." class MyClass5<»T«>(param: MyClass4?) // $TEST$ no error "Insufficient context to infer this type parameter." @@ -24,7 +24,7 @@ class MyClass9<»T«>(param: union) class MyClass10<»T«>(param: union) // $TEST$ error "Insufficient context to infer this type parameter." -fun myFunction1<»T«>() +fun myFunction1<»T« sub Int>() // $TEST$ no error "Insufficient context to infer this type parameter." fun myFunction2<»T«>(param: T) // $TEST$ no error "Insufficient context to infer this type parameter." diff --git a/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/lower bound must be assignable to upper bound/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/lower bound must be assignable to upper bound/main.sdstest deleted file mode 100644 index 8d3ca47df..000000000 --- a/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/lower bound must be assignable to upper bound/main.sdstest +++ /dev/null @@ -1,28 +0,0 @@ -package tests.validation.other.declarations.typeParameters.lowerBoundMustBeAssignableToUpperBound - -class C< - // $TEST$ no error r"The lower bound .* is not assignable to the upper bound .*\." - »OnlyLowerBound«, - // $TEST$ no error r"The lower bound .* is not assignable to the upper bound .*\." - »OnlyUpperBound«, - // $TEST$ no error r"The lower bound .* is not assignable to the upper bound .*\." - »CompatibleBounds«, - // $TEST$ error "The lower bound 'Number' is not assignable to the upper bound 'String'." - »IncompatibleBounds«, - // $TEST$ no error r"The lower bound .* is not assignable to the upper bound .*\." - »UnresolvedLowerBound«, - // $TEST$ no error r"The lower bound .* is not assignable to the upper bound .*\." - »UnresolvedUpperBound«, -> where { - OnlyLowerBound super Number, - OnlyUpperBound sub Number, - - CompatibleBounds super Number, - CompatibleBounds sub Number, - - IncompatibleBounds super Number, - IncompatibleBounds sub String, - - UnresolvedLowerBound super unknown, - UnresolvedUpperBound sub unknown, -} diff --git a/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/multiple bounds/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/multiple bounds/main.sdstest deleted file mode 100644 index 5de2ee098..000000000 --- a/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/multiple bounds/main.sdstest +++ /dev/null @@ -1,138 +0,0 @@ -package tests.validation.other.typeParameters.multipleBounds - -class MyGlobalClass where { - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T1 sub Int«, - // $TEST$ error "The type parameter 'T1' can only have a single upper bound." - »T1 sub Number«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T1 super Int«, - // $TEST$ error "The type parameter 'T1' can only have a single lower bound." - »T1 super Number«, - - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T2 sub Int«, - // $TEST$ error "The type parameter 'T2' can only have a single upper bound." - »T2 sub Number«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T2 super Int«, - // $TEST$ error "The type parameter 'T2' can only have a single lower bound." - »T2 super Number«, - - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T3 sub Int«, - // $TEST$ error "The type parameter 'T3' can only have a single upper bound." - »T4 super T3«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T5 super Int«, - // $TEST$ error "The type parameter 'T5' can only have a single lower bound." - »T6 sub T5«, - - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T7 sub Int«, - // $TEST$ error "The type parameter 'T7' can only have a single upper bound." - »T7 sub T7«, - // $TEST$ error "The type parameter 'T7' can only have a single upper bound." - »T7 super T7«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T8 super Int«, - // $TEST$ error "The type parameter 'T8' can only have a single lower bound." - »T8 super T8«, - // $TEST$ error "The type parameter 'T8' can only have a single lower bound." - »T8 sub T8«, - - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »Unresolved sub Int«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »Unresolved sub Number«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »Unresolved super Int«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »Unresolved super Number«, -} { - class MyNestedClass where { - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T1 sub Int«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T1 sub Number«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T1 super Int«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T1 super Number«, - } - - enum MyNestedEnum { - MyNestedEnumVariant where { - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T1 sub Int«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T1 sub Number«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T1 super Int«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T1 super Number«, - } - } - - @Pure fun myMethod() where { - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T1 sub Int«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T1 sub Number«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T1 super Int«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T1 super Number«, - } -} - -@Pure fun myGlobalFunction() where { - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T1 sub Int«, - // $TEST$ error "The type parameter 'T1' can only have a single upper bound." - »T1 sub Number«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T1 super Int«, - // $TEST$ error "The type parameter 'T1' can only have a single lower bound." - »T1 super Number«, - - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T2 sub Int«, - // $TEST$ error "The type parameter 'T2' can only have a single upper bound." - »T2 sub Number«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T2 super Int«, - // $TEST$ error "The type parameter 'T2' can only have a single lower bound." - »T2 super Number«, - - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T3 sub Int«, - // $TEST$ error "The type parameter 'T3' can only have a single upper bound." - »T4 super T3«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T5 super Int«, - // $TEST$ error "The type parameter 'T5' can only have a single lower bound." - »T6 sub T5«, - - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T7 sub Int«, - // $TEST$ error "The type parameter 'T7' can only have a single upper bound." - »T7 sub T7«, - // $TEST$ error "The type parameter 'T7' can only have a single upper bound." - »T7 super T7«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »T8 super Int«, - // $TEST$ error "The type parameter 'T8' can only have a single lower bound." - »T8 super T8«, - // $TEST$ error "The type parameter 'T8' can only have a single lower bound." - »T8 sub T8«, - - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »Unresolved sub Int«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »Unresolved sub Number«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »Unresolved super Int«, - // $TEST$ no error r"The type parameter .* can only have a single .* bound\." - »Unresolved super Number«, -} diff --git a/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/upper bound must be named type/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/upper bound must be named type/main.sdstest new file mode 100644 index 000000000..5eeba74b0 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/upper bound must be named type/main.sdstest @@ -0,0 +1,31 @@ +package tests.validation.other.declarations.typeParameters.upperBoundMustBeNamedType + +class C +enum E { + V +} + +// $TEST$ error "The upper bound of a type parameter must be a named type." +class MyClass1 ()«> + +// $TEST$ error "The upper bound of a type parameter must be a named type." +class MyClass2«> + +// $TEST$ no error "The upper bound of a type parameter must be a named type." +class MyClass3 + +// $TEST$ no error "The upper bound of a type parameter must be a named type." +class MyClass4 + +// $TEST$ no error "The upper bound of a type parameter must be a named type." +class MyClass5 + +// $TEST$ no error "The upper bound of a type parameter must be a named type." +// $TEST$ no error "The upper bound of a type parameter must be a named type." +class MyClass6 + +// $TEST$ error "The upper bound of a type parameter must be a named type." +class MyClass7«> + +// $TEST$ no error "The upper bound of a type parameter must be a named type." +class MyClass8 diff --git a/packages/safe-ds-lang/tests/resources/validation/other/expressions/chained expression/missing null safety/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/other/expressions/chained expression/missing null safety/main.sdstest index 8047a2697..8f3b9ca3e 100644 --- a/packages/safe-ds-lang/tests/resources/validation/other/expressions/chained expression/missing null safety/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/validation/other/expressions/chained expression/missing null safety/main.sdstest @@ -93,7 +93,7 @@ segment indexedAccess( »unresolved?[0]«; } -class IndexedAccess( +class IndexedAccess?, NonNullable sub List>( nullable: Nullable, nonNullable: NonNullable, @@ -106,10 +106,7 @@ class IndexedAccess( p3: Any? = »nullable?[0]«, // $TEST$ no error "The receiver can be null so a null-safe indexed access must be used." p4: Any? = »nonNullable?[0]«, -) where { - Nullable sub List?, - NonNullable sub List -} +) segment memberAccess( myClass: MyClass, @@ -147,7 +144,7 @@ segment memberAccess( »unresolved?.a«; } -class MemberAccess( +class MemberAccess( nullable: Nullable, nonNullable: NonNullable, @@ -160,7 +157,4 @@ class MemberAccess( p3: Any? = »nullable?.a«, // $TEST$ no error "The receiver can be null so a null-safe member access must be used." p4: Any? = »nonNullable?.a«, -) where { - Nullable sub MyClass?, - NonNullable sub MyClass -} +) diff --git a/packages/safe-ds-lang/tests/resources/validation/style/unnecessary constraint list in annotation/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/style/unnecessary constraint list in annotation/main.sdstest index 19fb92a9d..18384871d 100644 --- a/packages/safe-ds-lang/tests/resources/validation/style/unnecessary constraint list in annotation/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/validation/style/unnecessary constraint list in annotation/main.sdstest @@ -4,6 +4,6 @@ package tests.validation.style.unnecessaryConstraintListInAnnotation annotation MyAnnotation1 »where {}« // $TEST$ no info "This constraint list can be removed." -annotation MyAnnotation2 »where { - T sub Int +annotation MyAnnotation2(p: Int) »where { + p < 0 }« diff --git a/packages/safe-ds-lang/tests/resources/validation/style/unnecessary constraint list in class/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/style/unnecessary constraint list in class/main.sdstest index 254eeb421..1819c189b 100644 --- a/packages/safe-ds-lang/tests/resources/validation/style/unnecessary constraint list in class/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/validation/style/unnecessary constraint list in class/main.sdstest @@ -4,6 +4,6 @@ package tests.validation.style.unnecessaryConstraintListInClass class MyClass1 »where {}« // $TEST$ no info "This constraint list can be removed." -class MyClass2 »where { - T sub Int +class MyClass2(p: Int) »where { + p < 0 }« diff --git a/packages/safe-ds-lang/tests/resources/validation/style/unnecessary constraint list in enum variant/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/style/unnecessary constraint list in enum variant/main.sdstest index 6e844adcf..e2e51aea7 100644 --- a/packages/safe-ds-lang/tests/resources/validation/style/unnecessary constraint list in enum variant/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/validation/style/unnecessary constraint list in enum variant/main.sdstest @@ -5,7 +5,7 @@ enum MyEnum { MyVariant1 »where {}« // $TEST$ no info "This constraint list can be removed." - MyVariant2() »where { - T sub Int + MyVariant2(p: Int) »where { + p < 0 }« } diff --git a/packages/safe-ds-lang/tests/resources/validation/style/unnecessary constraint list in function/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/style/unnecessary constraint list in function/main.sdstest index fa82757b9..e104e1769 100644 --- a/packages/safe-ds-lang/tests/resources/validation/style/unnecessary constraint list in function/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/validation/style/unnecessary constraint list in function/main.sdstest @@ -4,6 +4,6 @@ package tests.validation.style.unnecessaryConstraintListInFunction fun myFunction1() »where {}« // $TEST$ no info "This constraint list can be removed." -fun myFunction2() »where { - T sub Int +fun myFunction2(p: Int) »where { + p < 0 }« diff --git a/packages/safe-ds-lang/tests/resources/validation/style/unnecessary elvis operator/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/style/unnecessary elvis operator/main.sdstest index 7129938c7..3ba83ddca 100644 --- a/packages/safe-ds-lang/tests/resources/validation/style/unnecessary elvis operator/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/validation/style/unnecessary elvis operator/main.sdstest @@ -41,7 +41,7 @@ pipeline test { »null ?: null«; } -class TestsForTypeParameters( +class TestsForTypeParameters( nullable: Nullable, nonNullable: NonNullable, @@ -53,6 +53,4 @@ class TestsForTypeParameters( p3: Any? = »nonNullable ?: 2«, // $TEST$ info "The left operand is never null, so the elvis operator is unnecessary (keep the left operand)." p4: Any? = »nonNullable ?: null«, -) where { - NonNullable sub Any -} +) diff --git a/packages/safe-ds-lang/tests/resources/validation/style/unnecessary null safety/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/style/unnecessary null safety/main.sdstest index 07f9d8b90..a2bf48ff7 100644 --- a/packages/safe-ds-lang/tests/resources/validation/style/unnecessary null safety/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/validation/style/unnecessary null safety/main.sdstest @@ -93,7 +93,7 @@ segment indexedAccess( »unresolved?[0]«; } -class IndexedAccess( +class IndexedAccess?, NonNullable sub List>( nullable: Nullable, nonNullable: NonNullable, @@ -106,10 +106,7 @@ class IndexedAccess( p3: Any? = »nullable?[0]«, // $TEST$ info "The receiver is never null, so null-safety is unnecessary." p4: Any? = »nonNullable?[0]«, -) where { - Nullable sub List?, - NonNullable sub List -} +) segment memberAccess( myClass: MyClass, @@ -147,7 +144,7 @@ segment memberAccess( »unresolved?.a«; } -class MemberAccess( +class MemberAccess( nullable: Nullable, nonNullable: NonNullable, @@ -160,7 +157,4 @@ class MemberAccess( p3: Any? = »nullable?.a«, // $TEST$ info "The receiver is never null, so null-safety is unnecessary." p4: Any? = »nonNullable?.a«, -) where { - Nullable sub MyClass?, - NonNullable sub MyClass -} +) diff --git a/packages/safe-ds-vscode/syntaxes/safe-ds.tmLanguage.json b/packages/safe-ds-vscode/syntaxes/safe-ds.tmLanguage.json index 37f59818c..67a35c8ca 100644 --- a/packages/safe-ds-vscode/syntaxes/safe-ds.tmLanguage.json +++ b/packages/safe-ds-vscode/syntaxes/safe-ds.tmLanguage.json @@ -24,7 +24,7 @@ }, { "name": "keyword.operator.expression.safe-ds", - "match": "\\b(and|not|or|sub|super)\\b" + "match": "\\b(and|not|or|sub)\\b" }, { "name": "keyword.other.safe-ds",