Skip to content

Commit 25c8707

Browse files
authored
feat: compute types of lambdas that are passed as arguments (#604)
Closes partially #541 ### Summary of Changes * Compute the type of parameters of lambdas that are passed as arguments. * Compute the type of lambdas that are passed as arguments.
1 parent a13e5b5 commit 25c8707

File tree

18 files changed

+45
-32
lines changed

18 files changed

+45
-32
lines changed

src/language/helpers/safe-ds-node-mapper.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,10 @@ import { argumentsOrEmpty, parametersOrEmpty, typeArgumentsOrEmpty, typeParamete
2323
import { isNamedArgument, isNamedTypeArgument } from './checks.js';
2424

2525
export class SafeDsNodeMapper {
26-
private readonly typeComputer: SafeDsTypeComputer;
26+
private readonly typeComputer: () => SafeDsTypeComputer;
2727

2828
constructor(services: SafeDsServices) {
29-
this.typeComputer = new SafeDsTypeComputer(services);
29+
this.typeComputer = () => services.types.TypeComputer;
3030
}
3131

3232
/**
@@ -36,7 +36,7 @@ export class SafeDsNodeMapper {
3636
if (isSdsAnnotationCall(node)) {
3737
return node.annotation?.ref;
3838
} else if (isSdsCall(node)) {
39-
const receiverType = this.typeComputer.computeType(node.receiver);
39+
const receiverType = this.typeComputer().computeType(node.receiver);
4040
if (receiverType instanceof CallableType) {
4141
return receiverType.sdsCallable;
4242
} else if (receiverType instanceof StaticType) {

src/language/typing/safe-ds-type-computer.ts

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -79,16 +79,19 @@ import {
7979
resultsOrEmpty,
8080
typeArgumentsOrEmpty,
8181
} from '../helpers/shortcuts.js';
82+
import { SafeDsNodeMapper } from '../helpers/safe-ds-node-mapper.js';
8283

8384
export class SafeDsTypeComputer {
84-
readonly astNodeLocator: AstNodeLocator;
85-
readonly coreClasses: SafeDsCoreClasses;
85+
private readonly astNodeLocator: AstNodeLocator;
86+
private readonly coreClasses: SafeDsCoreClasses;
87+
private readonly nodeMapper: SafeDsNodeMapper;
8688

8789
readonly typeCache: WorkspaceCache<string, Type>;
8890

8991
constructor(readonly services: SafeDsServices) {
9092
this.astNodeLocator = services.workspace.AstNodeLocator;
9193
this.coreClasses = services.builtins.CoreClasses;
94+
this.nodeMapper = services.helpers.NodeMapper;
9295

9396
this.typeCache = new WorkspaceCache(services.shared);
9497
}
@@ -214,20 +217,20 @@ export class SafeDsTypeComputer {
214217
const containerOfLambda = containingCallable.$container;
215218

216219
// Lambda passed as argument
217-
/* c8 ignore start */
218220
if (isSdsArgument(containerOfLambda)) {
219-
// val containerType = when (val container = callable.eContainer()) {
220-
// is SdsArgument -> container.parameterOrNull()?.inferType(context)
221-
// }
222-
//
223-
// return when (containerType) {
224-
// is CallableType -> containerType.parameters.getOrElse(thisIndex) { Any(context) }
225-
// else -> Any(context)
226-
// }
221+
const parameter = this.nodeMapper.argumentToParameterOrUndefined(containerOfLambda);
222+
if (!parameter) {
223+
return UnknownType;
224+
}
227225

228-
return NotImplementedType;
226+
const parameterType = this.computeType(parameter?.type);
227+
if (!(parameterType instanceof CallableType)) {
228+
return UnknownType;
229+
}
230+
231+
const parameterPosition = node.$containerIndex ?? -1;
232+
return parameterType.getParameterTypeByPosition(parameterPosition) ?? UnknownType;
229233
}
230-
/* c8 ignore stop */
231234

232235
// Yielded lambda
233236
else if (isSdsAssignment(containerOfLambda)) {

tests/resources/typing/declarations/parameters/of block lambdas/that are isolated.sdstest renamed to tests/resources/typing/declarations/parameters/of block lambdas/that are isolated/main.sdstest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package tests.typing.declarations.parameters.ofBlockLambdas
1+
package tests.typing.declarations.parameters.ofBlockLambdas.thatAreIsolated
22

33
segment mySegment() {
44
// $TEST$ serialization $Unknown
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package tests.typing.declarations.parameters.ofBlockLambdas
1+
package tests.typing.declarations.parameters.ofBlockLambdas.thatArePassedAsArguments
22

33
// $TEST$ equivalence_class parameterType1
44
fun higherOrderFunction1(param: (a: »String«) -> ())

tests/resources/typing/declarations/parameters/of block lambdas/that are yielded.sdstest renamed to tests/resources/typing/declarations/parameters/of block lambdas/that are yielded/main.sdstest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package tests.typing.declarations.parameters.ofBlockLambdas
1+
package tests.typing.declarations.parameters.ofBlockLambdas.thatAreYielded
22

33
segment mySegment() -> (
44
// $TEST$ equivalence_class parameterType2

tests/resources/typing/declarations/parameters/of block lambdas/with manifest types.sdstest renamed to tests/resources/typing/declarations/parameters/of block lambdas/with manifest types/main.sdstest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package tests.typing.declarations.parameters.ofBlockLambdas
1+
package tests.typing.declarations.parameters.ofBlockLambdas.withManifestTypes
22

33
segment mySegment() {
44
// $TEST$ equivalence_class parameterType3

tests/resources/typing/declarations/parameters/of expression lambdas/that are isolated.sdstest renamed to tests/resources/typing/declarations/parameters/of expression lambdas/that are isolated/main.sdstest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package tests.typing.declarations.parameters.ofExpressionLambdas
1+
package tests.typing.declarations.parameters.ofExpressionLambdas.thatAreIsolated
22

33
segment mySegment() {
44
// $TEST$ serialization $Unknown
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package tests.typing.declarations.parameters.ofExpressionLambdas
1+
package tests.typing.declarations.parameters.ofExpressionLambdas.thatArePassedAsArguments
22

33
// $TEST$ equivalence_class parameterType1
44
fun higherOrderFunction1(param: (a: »String«) -> r: String)

tests/resources/typing/declarations/parameters/of expression lambdas/that are yielded.sdstest renamed to tests/resources/typing/declarations/parameters/of expression lambdas/that are yielded/main.sdstest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package tests.typing.declarations.parameters.ofExpressionLambdas
1+
package tests.typing.declarations.parameters.ofExpressionLambdas.thatAreYielded
22

33
segment mySegment() -> (
44
// $TEST$ equivalence_class parameterType2

tests/resources/typing/declarations/parameters/of expression lambdas/with manifest types.sdstest renamed to tests/resources/typing/declarations/parameters/of expression lambdas/with manifest types/main.sdstest

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package tests.typing.declarations.parameters.ofExpressionLambdas
1+
package tests.typing.declarations.parameters.ofExpressionLambdas.withManifestTypes
22

33
segment mySegment() {
44
// $TEST$ equivalence_class parameterType3

0 commit comments

Comments
 (0)