Skip to content

Commit adaa8d8

Browse files
committed
fix: don't show this error for classes without constructor
1 parent b2d6076 commit adaa8d8

File tree

3 files changed

+51
-48
lines changed

3 files changed

+51
-48
lines changed
Lines changed: 38 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,47 @@
1-
import { isSdsCallable, isSdsParameterList, isSdsUnionType, SdsTypeParameter } from '../../../generated/ast.js';
1+
import {
2+
isSdsCallable,
3+
isSdsClass,
4+
isSdsParameterList,
5+
isSdsUnionType,
6+
SdsTypeParameter,
7+
} from '../../../generated/ast.js';
28
import { findLocalReferences, getContainerOfType, hasContainerOfType, ValidationAcceptor } from 'langium';
3-
import { SafeDsServices } from '../../../safe-ds-module.js';
49

510
export const CODE_TYPE_PARAMETER_INSUFFICIENT_CONTEXT = 'type-parameter/insufficient-context';
611

7-
export const typeParameterMustHaveSufficientContext = (services: SafeDsServices) => {
8-
const builtinClasses = services.builtins.Classes;
12+
export const typeParameterMustHaveSufficientContext = (node: SdsTypeParameter, accept: ValidationAcceptor) => {
13+
const containingCallable = getContainerOfType(node, isSdsCallable);
14+
/* c8 ignore start */
15+
if (!containingCallable) {
16+
return;
17+
}
18+
/* c8 ignore stop */
919

10-
return (node: SdsTypeParameter, accept: ValidationAcceptor) => {
11-
const containingCallable = getContainerOfType(node, isSdsCallable);
12-
/* c8 ignore start */
13-
if (!containingCallable) {
14-
return;
15-
}
16-
/* c8 ignore stop */
20+
// Classes without constructor can only be used as named types, where type arguments are manifest
21+
if (isSdsClass(containingCallable) && !containingCallable.parameterList) {
22+
return;
23+
}
1724

18-
// Lists and maps are created using literals
19-
if (containingCallable === builtinClasses.List || containingCallable === builtinClasses.Map) {
20-
return;
21-
}
25+
// A type parameter must be referenced in the parameter list of the containing callable...
26+
let typeParameterHasInsufficientContext =
27+
!containingCallable.parameterList ||
28+
findLocalReferences(node, containingCallable.parameterList)
29+
// ...but references in a union type or in the parameter list of a callable type don't count
30+
.filter((reference) => {
31+
const referenceNode = reference.$refNode?.astNode;
32+
const containingParameterList = getContainerOfType(referenceNode, isSdsParameterList);
2233

23-
// A type parameter must be referenced in the parameter list of the containing callable...
24-
let typeParameterHasInsufficientContext =
25-
!containingCallable.parameterList ||
26-
findLocalReferences(node, containingCallable.parameterList)
27-
// ...but references in a union type or in the parameter list of a callable type don't count
28-
.filter((reference) => {
29-
const referenceNode = reference.$refNode?.astNode;
30-
const containingParameterList = getContainerOfType(referenceNode, isSdsParameterList);
34+
return (
35+
!hasContainerOfType(referenceNode, isSdsUnionType) &&
36+
containingParameterList === containingCallable.parameterList
37+
);
38+
})
39+
.isEmpty();
3140

32-
return (
33-
!hasContainerOfType(referenceNode, isSdsUnionType) &&
34-
containingParameterList === containingCallable.parameterList
35-
);
36-
})
37-
.isEmpty();
38-
39-
if (typeParameterHasInsufficientContext) {
40-
accept('error', 'Insufficient context to infer this type parameter.', {
41-
node,
42-
code: CODE_TYPE_PARAMETER_INSUFFICIENT_CONTEXT,
43-
});
44-
}
45-
};
41+
if (typeParameterHasInsufficientContext) {
42+
accept('error', 'Insufficient context to infer this type parameter.', {
43+
node,
44+
code: CODE_TYPE_PARAMETER_INSUFFICIENT_CONTEXT,
45+
});
46+
}
4647
};

src/language/validation/safe-ds-validator.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,7 @@ export const registerValidationChecks = function (services: SafeDsServices) {
284284
segmentResultListShouldNotBeEmpty,
285285
],
286286
SdsTemplateString: [templateStringMustHaveExpressionBetweenTwoStringParts],
287-
SdsTypeParameter: [typeParameterMustHaveSufficientContext(services)],
287+
SdsTypeParameter: [typeParameterMustHaveSufficientContext],
288288
SdsTypeParameterConstraint: [typeParameterConstraintLeftOperandMustBeOwnTypeParameter],
289289
SdsTypeParameterList: [typeParameterListShouldNotBeEmpty],
290290
SdsUnionType: [

tests/resources/validation/other/declarations/type parameters/insufficient context/main.sdstest

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
package tests.validation.other.declarations.typeParameters.insufficientContext
22

3-
// $TEST$ error "Insufficient context to infer this type parameter."
3+
// $TEST$ no error "Insufficient context to infer this type parameter."
44
class MyClass1<»T«>
55
// $TEST$ error "Insufficient context to infer this type parameter."
6-
class MyClass2<»T«> {
6+
class MyClass2<»T«>()
7+
// $TEST$ error "Insufficient context to infer this type parameter."
8+
class MyClass3<»T«>() {
79
attr myAttr: T
810
}
911
// $TEST$ no error "Insufficient context to infer this type parameter."
10-
class MyClass3<»T«>(param: T)
12+
class MyClass4<»T«>(param: T)
1113
// $TEST$ no error "Insufficient context to infer this type parameter."
12-
class MyClass4<»T«>(param: MyClass4<T>?)
14+
class MyClass5<»T«>(param: MyClass4<T>?)
1315
// $TEST$ no error "Insufficient context to infer this type parameter."
14-
class MyClass5<»T«>(param: MyEnum.MyEnumVariant1<T>)
16+
class MyClass6<»T«>(param: MyEnum.MyEnumVariant1<T>)
1517
// $TEST$ no error "Insufficient context to infer this type parameter."
16-
class MyClass6<»T«>(param: () -> (r: T))
18+
class MyClass7<»T«>(param: () -> (r: T))
1719
// $TEST$ error "Insufficient context to infer this type parameter."
18-
class MyClass7<»T«>(param: (p: T) -> ())
20+
class MyClass8<»T«>(param: (p: T) -> ())
1921
// $TEST$ error "Insufficient context to infer this type parameter."
20-
class MyClass8<»T«>(param: () -> (r: (p: T) -> ()))
22+
class MyClass9<»T«>(param: () -> (r: (p: T) -> ()))
2123
// $TEST$ error "Insufficient context to infer this type parameter."
22-
class MyClass9<»T«>(param: union<T>)
24+
class MyClass10<»T«>(param: union<T>)
2325
// $TEST$ error "Insufficient context to infer this type parameter."
24-
class MyClass10<»T«>(param: union<T, Int>)
26+
class MyClass11<»T«>(param: union<T, Int>)
2527

2628
enum MyEnum {
2729
// $TEST$ error "Insufficient context to infer this type parameter."

0 commit comments

Comments
 (0)