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 6a3e0af09..32e4d020e 100644 --- a/packages/safe-ds-lang/src/language/grammar/safe-ds.langium +++ b/packages/safe-ds-lang/src/language/grammar/safe-ds.langium @@ -979,12 +979,14 @@ SdsTypeParameterList returns SdsTypeParameterList: interface SdsTypeParameter extends SdsNamedTypeDeclaration { variance?: string + defaultValue?: SdsType } SdsTypeParameter returns SdsTypeParameter: annotationCalls+=SdsAnnotationCall* variance=SdsTypeParameterVariance? name=ID + ('=' defaultValue=SdsType)? ; SdsTypeParameterVariance returns string: diff --git a/packages/safe-ds-lang/src/language/helpers/nodeProperties.ts b/packages/safe-ds-lang/src/language/helpers/nodeProperties.ts index 883e6386b..0c0423e9b 100644 --- a/packages/safe-ds-lang/src/language/helpers/nodeProperties.ts +++ b/packages/safe-ds-lang/src/language/helpers/nodeProperties.ts @@ -15,10 +15,13 @@ import { isSdsLambda, isSdsModule, isSdsModuleMember, + isSdsNamedType, isSdsParameter, isSdsPlaceholder, isSdsQualifiedImport, isSdsSegment, + isSdsTypeArgumentList, + isSdsTypeParameter, isSdsTypeParameterList, SdsAbstractCall, SdsAbstractResult, @@ -45,6 +48,7 @@ import { SdsLiteralType, SdsModule, SdsModuleMember, + SdsNamedType, SdsNamedTypeDeclaration, SdsParameter, SdsPlaceholder, @@ -144,6 +148,16 @@ export namespace TypeArgument { }; } +export namespace TypeParameter { + export const isOptional = (node: SdsTypeParameter | undefined): boolean => { + return Boolean(node?.defaultValue); + }; + + export const isRequired = (node: SdsTypeParameter | undefined): boolean => { + return isSdsTypeParameter(node) && !node.defaultValue; + }; +} + // ------------------------------------------------------------------------------------------------- // Accessors for list elements // ------------------------------------------------------------------------------------------------- @@ -297,8 +311,18 @@ export const getStatements = (node: SdsBlock | undefined): SdsStatement[] => { return node?.statements ?? []; }; -export const getTypeArguments = (node: SdsTypeArgumentList | undefined): SdsTypeArgument[] => { - return node?.typeArguments ?? []; +export const getTypeArguments = (node: SdsTypeArgumentList | SdsNamedType | undefined): SdsTypeArgument[] => { + if (!node) { + return []; + } + + if (isSdsTypeArgumentList(node)) { + return node.typeArguments; + } else if (isSdsNamedType(node)) { + return getTypeArguments(node.typeArgumentList); + } /* c8 ignore start */ else { + return []; + } /* c8 ignore stop */ }; export const getTypeParameters = ( 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 809bd4c27..3e453e94e 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 @@ -905,6 +905,7 @@ export class SafeDsFormatter extends AbstractFormatter { } formatter.property('variance').append(oneSpace()); + formatter.keyword('=').surround(oneSpace()); } private formatSdsTypeArgumentList(node: ast.SdsTypeArgumentList): void { diff --git a/packages/safe-ds-lang/src/language/validation/other/declarations/typeParameterLists.ts b/packages/safe-ds-lang/src/language/validation/other/declarations/typeParameterLists.ts new file mode 100644 index 000000000..beeeeeaef --- /dev/null +++ b/packages/safe-ds-lang/src/language/validation/other/declarations/typeParameterLists.ts @@ -0,0 +1,23 @@ +import { ValidationAcceptor } from 'langium'; +import { SdsTypeParameterList } from '../../../generated/ast.js'; +import { TypeParameter } from '../../../helpers/nodeProperties.js'; + +export const CODE_TYPE_PARAMETER_LIST_REQUIRED_AFTER_OPTIONAL = 'type-parameter-list/required-after-optional'; + +export const typeParameterListMustNotHaveRequiredTypeParametersAfterOptionalTypeParameters = ( + node: SdsTypeParameterList, + accept: ValidationAcceptor, +) => { + let foundOptional = false; + for (const typeParameter of node.typeParameters) { + if (TypeParameter.isOptional(typeParameter)) { + foundOptional = true; + } else if (foundOptional) { + accept('error', 'After the first optional type parameter all type parameters must be optional.', { + node: typeParameter, + property: 'name', + code: CODE_TYPE_PARAMETER_LIST_REQUIRED_AFTER_OPTIONAL, + }); + } + } +}; diff --git a/packages/safe-ds-lang/src/language/validation/other/types/namedTypes.ts b/packages/safe-ds-lang/src/language/validation/other/types/namedTypes.ts index b64552880..153104dc1 100644 --- a/packages/safe-ds-lang/src/language/validation/other/types/namedTypes.ts +++ b/packages/safe-ds-lang/src/language/validation/other/types/namedTypes.ts @@ -1,7 +1,7 @@ import { SdsNamedType } from '../../../generated/ast.js'; import { ValidationAcceptor } from 'langium'; import { SafeDsServices } from '../../../safe-ds-module.js'; -import { getTypeArguments, getTypeParameters } from '../../../helpers/nodeProperties.js'; +import { getTypeArguments, getTypeParameters, TypeParameter } from '../../../helpers/nodeProperties.js'; import { duplicatesBy } from '../../../../helpers/collections.js'; import { pluralize } from '../../../../helpers/strings.js'; @@ -50,6 +50,13 @@ export const namedTypeTypeArgumentListMustNotHavePositionalArgumentsAfterNamedAr }; export const namedTypeMustNotHaveTooManyTypeArguments = (node: SdsNamedType, accept: ValidationAcceptor): void => { + const actualTypeArgumentCount = getTypeArguments(node).length; + + // We can never have too many arguments in this case + if (actualTypeArgumentCount === 0) { + return; + } + // If the declaration is unresolved, we already show another error const namedTypeDeclaration = node.declaration?.ref; if (!namedTypeDeclaration) { @@ -57,14 +64,30 @@ export const namedTypeMustNotHaveTooManyTypeArguments = (node: SdsNamedType, acc } const typeParameters = getTypeParameters(namedTypeDeclaration); - const typeArguments = getTypeArguments(node.typeArgumentList); + const maxTypeArgumentCount = typeParameters.length; + + // All is good + if (actualTypeArgumentCount <= maxTypeArgumentCount) { + return; + } - if (typeArguments.length > typeParameters.length) { - const kind = pluralize(typeParameters.length, 'type argument'); - accept('error', `Expected ${typeParameters.length} ${kind} but got ${typeArguments.length}.`, { + const minTypeArgumentCount = typeParameters.filter(TypeParameter.isRequired).length; + const kind = pluralize(Math.max(minTypeArgumentCount, maxTypeArgumentCount), 'type argument'); + if (minTypeArgumentCount === maxTypeArgumentCount) { + accept('error', `Expected exactly ${minTypeArgumentCount} ${kind} but got ${actualTypeArgumentCount}.`, { node, property: 'typeArgumentList', code: CODE_NAMED_TYPE_TOO_MANY_TYPE_ARGUMENTS, }); + } else { + accept( + 'error', + `Expected between ${minTypeArgumentCount} and ${maxTypeArgumentCount} ${kind} but got ${actualTypeArgumentCount}.`, + { + node, + property: 'typeArgumentList', + code: CODE_NAMED_TYPE_TOO_MANY_TYPE_ARGUMENTS, + }, + ); } }; 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 936bbc8b0..1025b880f 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 @@ -179,6 +179,7 @@ import { } from './types.js'; import { statementMustDoSomething } from './other/statements/statements.js'; import { indexedAccessIndexMustBeValid } from './other/expressions/indexedAccess.js'; +import { typeParameterListMustNotHaveRequiredTypeParametersAfterOptionalTypeParameters } from './other/declarations/typeParameterLists.js'; /** * Register custom validation checks. @@ -355,6 +356,7 @@ export const registerValidationChecks = function (services: SafeDsServices) { ], SdsTypeParameterConstraint: [typeParameterConstraintLeftOperandMustBeOwnTypeParameter], SdsTypeParameterList: [ + typeParameterListMustNotHaveRequiredTypeParametersAfterOptionalTypeParameters, typeParameterListsShouldBeUsedWithCaution(services), typeParameterListShouldNotBeEmpty(services), ], diff --git a/packages/safe-ds-lang/src/language/validation/types.ts b/packages/safe-ds-lang/src/language/validation/types.ts index 0ab6f5452..03ee21fb2 100644 --- a/packages/safe-ds-lang/src/language/validation/types.ts +++ b/packages/safe-ds-lang/src/language/validation/types.ts @@ -23,7 +23,7 @@ import { SdsResult, SdsYield, } from '../generated/ast.js'; -import { getTypeArguments, getTypeParameters } from '../helpers/nodeProperties.js'; +import { getTypeArguments, getTypeParameters, TypeParameter } from '../helpers/nodeProperties.js'; import { SafeDsServices } from '../safe-ds-module.js'; import { NamedTupleType } from '../typing/model.js'; @@ -326,7 +326,7 @@ export const yieldTypeMustMatchResultType = (services: SafeDsServices) => { export const namedTypeMustSetAllTypeParameters = (services: SafeDsServices) => (node: SdsNamedType, accept: ValidationAcceptor): void => { - const expectedTypeParameters = getTypeParameters(node.declaration?.ref); + const expectedTypeParameters = getTypeParameters(node.declaration?.ref).filter(TypeParameter.isRequired); if (isEmpty(expectedTypeParameters)) { return; } @@ -350,7 +350,7 @@ export const namedTypeMustSetAllTypeParameters = } else { accept( 'error', - `The type '${node.declaration?.$refText}' is parameterized, so a type argument list must be added.`, + `The type '${node.declaration?.$refText}' has required type parameters, so a type argument list must be added.`, { node, code: CODE_TYPE_MISSING_TYPE_ARGUMENTS, diff --git a/packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/contravariant optional type parameter.sdstest b/packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/contravariant optional type parameter.sdstest new file mode 100644 index 000000000..2bfeaf86d --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/contravariant optional type parameter.sdstest @@ -0,0 +1,5 @@ +fun myFunction< in T = Int >() + +// ----------------------------------------------------------------------------- + +fun myFunction() diff --git a/packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/contravariant type parameter.sdstest b/packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/contravariant required type parameter.sdstest similarity index 100% rename from packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/contravariant type parameter.sdstest rename to packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/contravariant required type parameter.sdstest diff --git a/packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/covariant optional type parameter.sdstest b/packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/covariant optional type parameter.sdstest new file mode 100644 index 000000000..7e364ba94 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/covariant optional type parameter.sdstest @@ -0,0 +1,5 @@ +fun myFunction< out T = Int >() + +// ----------------------------------------------------------------------------- + +fun myFunction() diff --git a/packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/covariant type parameter.sdstest b/packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/covariant required type parameter.sdstest similarity index 100% rename from packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/covariant type parameter.sdstest rename to packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/covariant required type parameter.sdstest diff --git a/packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/invariant optional type parameter.sdstest b/packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/invariant optional type parameter.sdstest new file mode 100644 index 000000000..650755f6b --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/invariant optional type parameter.sdstest @@ -0,0 +1,5 @@ +fun myFunction< T = Int >() + +// ----------------------------------------------------------------------------- + +fun myFunction() diff --git a/packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/invariant type parameter.sdstest b/packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/invariant required type parameter.sdstest similarity index 100% rename from packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/invariant type parameter.sdstest rename to packages/safe-ds-lang/tests/resources/formatting/declarations/type parameters/invariant required type parameter.sdstest diff --git a/packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-contravariant optional type parameter.sdstest b/packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-contravariant optional type parameter.sdstest new file mode 100644 index 000000000..88d30d82b --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-contravariant optional type parameter.sdstest @@ -0,0 +1,3 @@ +// $TEST$ no_syntax_error + +fun myFunction() diff --git a/packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-contravariant type parameter.sdstest b/packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-contravariant required type parameter.sdstest similarity index 100% rename from packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-contravariant type parameter.sdstest rename to packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-contravariant required type parameter.sdstest diff --git a/packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-covariant optional type parameter.sdstest b/packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-covariant optional type parameter.sdstest new file mode 100644 index 000000000..1be49dfda --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-covariant optional type parameter.sdstest @@ -0,0 +1,3 @@ +// $TEST$ no_syntax_error + +fun myFunction() diff --git a/packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-covariant type parameter.sdstest b/packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-covariant required type parameter.sdstest similarity index 100% rename from packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-covariant type parameter.sdstest rename to packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-covariant required type parameter.sdstest diff --git a/packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-invariant optional type parameter.sdstest b/packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-invariant optional type parameter.sdstest new file mode 100644 index 000000000..ab7a29385 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-invariant optional type parameter.sdstest @@ -0,0 +1,3 @@ +// $TEST$ no_syntax_error + +fun myFunction() diff --git a/packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-invariant type parameter.sdstest b/packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-invariant required type parameter.sdstest similarity index 100% rename from packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-invariant type parameter.sdstest rename to packages/safe-ds-lang/tests/resources/grammar/declarations/type parameters/good-invariant required type parameter.sdstest diff --git a/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/must not have required after optional/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/must not have required after optional/main.sdstest new file mode 100644 index 000000000..f759ad68a --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/validation/other/declarations/type parameters/must not have required after optional/main.sdstest @@ -0,0 +1,28 @@ +package tests.validation.other.declarations.typeParameterLists.mustNotHaveRequiredAfterOptional + +// $TEST$ no error "After the first optional type parameter all type parameters must be optional." +// $TEST$ no error "After the first optional type parameter all type parameters must be optional." +// $TEST$ error "After the first optional type parameter all type parameters must be optional." +// $TEST$ no error "After the first optional type parameter all type parameters must be optional." +class MyClass1<»A«, »B« = Int, »C«, »D« = String> + +// $TEST$ no error "After the first optional type parameter all type parameters must be optional." +// $TEST$ no error "After the first optional type parameter all type parameters must be optional." +class MyClass2<»A«, »B« = Int> + +// $TEST$ no error "After the first optional type parameter all type parameters must be optional." +class MyClass3<»A«> + + +// $TEST$ no error "After the first optional type parameter all type parameters must be optional." +// $TEST$ no error "After the first optional type parameter all type parameters must be optional." +// $TEST$ error "After the first optional type parameter all type parameters must be optional." +// $TEST$ no error "After the first optional type parameter all type parameters must be optional." +fun myFunction1<»A«, »B« = Int, »C«, »D« = String>() + +// $TEST$ no error "After the first optional type parameter all type parameters must be optional." +// $TEST$ no error "After the first optional type parameter all type parameters must be optional." +fun myFunction2<»A«, »B« = Int>() + +// $TEST$ no error "After the first optional type parameter all type parameters must be optional." +fun myFunction3<»A«>() diff --git a/packages/safe-ds-lang/tests/resources/validation/other/types/type argument lists/too many type arguments/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/other/types/type argument lists/too many type arguments/main.sdstest index 6b86740a4..564e9add8 100644 --- a/packages/safe-ds-lang/tests/resources/validation/other/types/type argument lists/too many type arguments/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/validation/other/types/type argument lists/too many type arguments/main.sdstest @@ -1,17 +1,20 @@ package tests.validation.other.types.typeArgumentLists.tooManyTypeArguments -class MyClass1 +class MyClass1 class MyClass2 +class MyClass3 fun myFunction( - // $TEST$ no error r"Expected \d* type arguments? but got \d*\." - f: MyClass1»<>«, - // $TEST$ no error r"Expected \d* type arguments? but got \d*\." - g: MyClass1»«, - // $TEST$ error "Expected 1 type argument but got 2." - h: MyClass1»«, - // $TEST$ error "Expected 2 type arguments but got 3." - i: MyClass2»«, - // $TEST$ no error r"Expected \d* type arguments? but got \d*\." - j: Unresolved»« + // $TEST$ no error r"Expected .* type arguments? but got \d*\." + a: MyClass1»<>«, + // $TEST$ no error r"Expected .* type arguments? but got \d*\." + b: MyClass1»«, + // $TEST$ error "Expected exactly 1 type argument but got 2." + c: MyClass1»«, + // $TEST$ error "Expected exactly 2 type arguments but got 3." + d: MyClass2»«, + // $TEST$ error "Expected between 1 and 2 type arguments but got 3." + f: MyClass3»«, + // $TEST$ no error r"Expected .* type arguments? but got \d*\." + g: Unresolved»« ) diff --git a/packages/safe-ds-lang/tests/resources/validation/types/named types/missing required type parameter/dont show this error if the type argument list is missing altogether.sdstest b/packages/safe-ds-lang/tests/resources/validation/types/named types/missing required type parameter/dont show this error if the type argument list is missing altogether.sdstest new file mode 100644 index 000000000..1ee6c48c4 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/validation/types/named types/missing required type parameter/dont show this error if the type argument list is missing altogether.sdstest @@ -0,0 +1,9 @@ +package tests.validation.other.namedTypes.missingRequiredTypeParameter + +// $TEST$ no error r"The type parameters? .* must be set here\." + +class MyClass + +fun myFunction2( + myCallableType: MyClass +) diff --git a/packages/safe-ds-lang/tests/resources/validation/types/named types/missing required type parameter/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/types/named types/missing required type parameter/main.sdstest new file mode 100644 index 000000000..52049aea6 --- /dev/null +++ b/packages/safe-ds-lang/tests/resources/validation/types/named types/missing required type parameter/main.sdstest @@ -0,0 +1,32 @@ + +package tests.validation.types.namedTypes.missingRequiredTypeParameter + +class MyClassWithoutTypeParameter +class MyClassWithTypeParameters + +fun myFunction1( + // $TEST$ no error r"The type parameters? .* must be set here\." + a1: MyClassWithoutTypeParameter»<>«, + // $TEST$ no error r"The type parameters? .* must be set here\." + a2: MyClassWithoutTypeParameter»«, + // $TEST$ no error r"The type parameters? .* must be set here\." + a3: MyClassWithoutTypeParameter»«, + + // $TEST$ error "The type parameters 'T1', 'T2' must be set here." + b1: MyClassWithTypeParameters»<>«, + // $TEST$ error "The type parameter 'T2' must be set here." + b2: MyClassWithTypeParameters»«, + // $TEST$ error "The type parameter 'T1' must be set here." + b3: MyClassWithTypeParameters»«, + // $TEST$ no error r"The type parameters? .* must be set here\." + b4: MyClassWithTypeParameters»«, + // $TEST$ no error r"The type parameters? .* must be set here\." + b5: MyClassWithTypeParameters»«, + + // $TEST$ no error r"The type parameters? .* must be set here\." + d1: Unresolved»<>«, + // $TEST$ no error r"The type parameters? .* must be set here\." + d2: Unresolved»«, + // $TEST$ no error r"The type parameters? .* must be set here\." + d3: Unresolved»«, +) diff --git a/packages/safe-ds-lang/tests/resources/validation/types/named types/missing type argument list/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/types/named types/missing type argument list/main.sdstest index f2c86087e..e7793cda1 100644 --- a/packages/safe-ds-lang/tests/resources/validation/types/named types/missing type argument list/main.sdstest +++ b/packages/safe-ds-lang/tests/resources/validation/types/named types/missing type argument list/main.sdstest @@ -1,22 +1,27 @@ package tests.validation.types.namedTypes.missingTypeArgumentList class MyClassWithoutTypeParameters -class MyClassWithTypeParameters +class MyClassWithRequiredTypeParameters +class MyClassWithOptionalTypeParameters fun myFunction( - // $TEST$ no error r"The type '\w*' is parameterized, so a type argument list must be added\." + // $TEST$ no error r"The type '\w*' has required type parameters, so a type argument list must be added\." a1: »MyClassWithoutTypeParameters«, - // $TEST$ no error r"The type '\w*' is parameterized, so a type argument list must be added\." - b1: »MyClassWithoutTypeParameters«<>, + // $TEST$ no error r"The type '\w*' has required type parameters, so a type argument list must be added\." + a2: »MyClassWithoutTypeParameters«<>, - // $TEST$ error "The type 'MyClassWithTypeParameters' is parameterized, so a type argument list must be added." - c1: »MyClassWithTypeParameters«, - // $TEST$ no error r"The type '\w*' is parameterized, so a type argument list must be added\." - d1: »MyClassWithTypeParameters«<>, + // $TEST$ error "The type 'MyClassWithRequiredTypeParameters' has required type parameters, so a type argument list must be added." + b1: »MyClassWithRequiredTypeParameters«, + // $TEST$ no error r"The type '\w*' has required type parameters, so a type argument list must be added\." + b2: »MyClassWithRequiredTypeParameters«<>, + // $TEST$ no error r"The type '\w*' has required type parameters, so a type argument list must be added\." + c1: »MyClassWithOptionalTypeParameters«, + // $TEST$ no error r"The type '\w*' has required type parameters, so a type argument list must be added\." + c2: »MyClassWithOptionalTypeParameters«<>, - // $TEST$ no error r"The type '\w*' is parameterized, so a type argument list must be added\." - e: »UnresolvedClass«, - // $TEST$ no error r"The type '\w*' is parameterized, so a type argument list must be added\." - f: »UnresolvedClass«<>, + // $TEST$ no error r"The type '\w*' has required type parameters, so a type argument list must be added\." + d1: »UnresolvedClass«, + // $TEST$ no error r"The type '\w*' has required type parameters, so a type argument list must be added\." + d2: »UnresolvedClass«<>, ) diff --git a/packages/safe-ds-lang/tests/resources/validation/types/named types/missing type parameter/main.sdstest b/packages/safe-ds-lang/tests/resources/validation/types/named types/missing type parameter/main.sdstest deleted file mode 100644 index 1a9b1cf24..000000000 --- a/packages/safe-ds-lang/tests/resources/validation/types/named types/missing type parameter/main.sdstest +++ /dev/null @@ -1,37 +0,0 @@ - -package tests.validation.types.namedTypes.missingTypeParameter - -class MyClassWithoutTypeParameter -class MyClassWithOneTypeParameter -class MyClassWithTwoTypeParameters - -fun myFunction( - // $TEST$ no error r"The type parameters? .* must be set here\." - p1: MyClassWithoutTypeParameter»<>«, - // $TEST$ no error r"The type parameters? .* must be set here\." - p2: MyClassWithoutTypeParameter»«, - // $TEST$ no error r"The type parameters? .* must be set here\." - p3: MyClassWithoutTypeParameter»«, - - // $TEST$ error "The type parameter 'T' must be set here." - p4: MyClassWithOneTypeParameter»<>«, - // $TEST$ no error r"The type parameters? .* must be set here\." - p5: MyClassWithOneTypeParameter»«, - // $TEST$ no error r"The type parameters? .* must be set here\." - p6: MyClassWithOneTypeParameter»«, - - // $TEST$ error "The type parameters 'K', 'V' must be set here." - p7: MyClassWithTwoTypeParameters»<>«, - // $TEST$ error "The type parameter 'V' must be set here." - p8: MyClassWithTwoTypeParameters»«, - // $TEST$ error "The type parameters 'K', 'V' must be set here." - p9: MyClassWithTwoTypeParameters»«, - - - // $TEST$ no error r"The type parameters? .* must be set here\." - a1: Unresolved»<>«, - // $TEST$ no error r"The type parameters? .* must be set here\." - a2: Unresolved»«, - // $TEST$ no error r"The type parameters? .* must be set here\." - a3: Unresolved»«, -)