-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: error if type parameter is set multiple times
- Loading branch information
1 parent
4e675f8
commit 0ccdeaa
Showing
4 changed files
with
90 additions
and
23 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,48 @@ | ||
import { SdsNamedType } from '../../../generated/ast.js'; | ||
import { ValidationAcceptor } from 'langium'; | ||
import { SafeDsServices } from '../../../safe-ds-module.js'; | ||
import { typeArgumentsOrEmpty } from '../../../helpers/nodeProperties.js'; | ||
import { duplicatesBy } from '../../../helpers/collectionUtils.js'; | ||
|
||
export const CODE_NAMED_TYPE_DUPLICATE_TYPE_PARAMETER = 'named-type/duplicate-type-parameter'; | ||
export const CODE_NAMED_TYPE_POSITIONAL_AFTER_NAMED = 'named-type/positional-after-named'; | ||
|
||
export const namedTypeMustNotSetTypeParameterMultipleTimes = (services: SafeDsServices) => { | ||
const nodeMapper = services.helpers.NodeMapper; | ||
const typeArgumentToTypeParameterOrUndefined = nodeMapper.typeArgumentToTypeParameterOrUndefined.bind(nodeMapper); | ||
|
||
return (node: SdsNamedType, accept: ValidationAcceptor): void => { | ||
const typeArguments = typeArgumentsOrEmpty(node.typeArgumentList); | ||
const duplicates = duplicatesBy(typeArguments, typeArgumentToTypeParameterOrUndefined); | ||
|
||
for (const duplicate of duplicates) { | ||
const correspondingTypeParameter = typeArgumentToTypeParameterOrUndefined(duplicate)!; | ||
accept('error', `The type parameter '${correspondingTypeParameter.name}' is already set.`, { | ||
node: duplicate, | ||
code: CODE_NAMED_TYPE_DUPLICATE_TYPE_PARAMETER, | ||
}); | ||
} | ||
}; | ||
}; | ||
|
||
export const namedTypeTypeArgumentListMustNotHavePositionalArgumentsAfterNamedArguments = ( | ||
node: SdsNamedType, | ||
accept: ValidationAcceptor, | ||
): void => { | ||
const typeArgumentList = node.typeArgumentList; | ||
if (!typeArgumentList) { | ||
return; | ||
} | ||
|
||
let foundNamed = false; | ||
for (const typeArgument of typeArgumentList.typeArguments) { | ||
if (typeArgument.typeParameter) { | ||
foundNamed = true; | ||
} else if (foundNamed) { | ||
accept('error', 'After the first named type argument all type arguments must be named.', { | ||
node: typeArgument, | ||
code: CODE_NAMED_TYPE_POSITIONAL_AFTER_NAMED, | ||
}); | ||
} | ||
} | ||
}; |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
...esources/validation/other/types/type argument lists/duplicate type parameter/main.sdstest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
package tests.validation.other.types.typeArgumentLists.duplicateTypeParameters | ||
|
||
class MyClass<A, B> | ||
|
||
fun myFunction( | ||
f: MyClass< | ||
// $TEST$ no error r"The type parameter '\w+' is already set\." | ||
»Int«, | ||
// $TEST$ error "The type parameter 'A' is already set." | ||
»A = Int« | ||
>, | ||
g: MyClass< | ||
// $TEST$ no error r"The type parameter '\w+' is already set\." | ||
»B = Int«, | ||
// $TEST$ error "The type parameter 'B' is already set." | ||
»B = Int« | ||
>, | ||
h: MyClass< | ||
// $TEST$ no error r"The type parameter '\w+' is already set\." | ||
»A = Int«, | ||
// $TEST$ no error r"The type parameter '\w+' is already set\." | ||
»B = Int« | ||
>, | ||
i: MyClass< | ||
// $TEST$ no error r"The type parameter '\w+' is already set\." | ||
»Int«, | ||
// $TEST$ no error r"The type parameter '\w+' is already set\." | ||
»Int« | ||
>, | ||
j: MyClass< | ||
// $TEST$ no error r"The type parameter '\w+' is already set\." | ||
»Unresolved = Int«, | ||
// $TEST$ no error r"The type parameter '\w+' is already set\." | ||
»Unresolved = Int« | ||
> | ||
) |