Skip to content

Commit

Permalink
feat: compute types of lambdas that are passed as arguments (#604)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
lars-reimann authored Oct 5, 2023
1 parent a13e5b5 commit 25c8707
Show file tree
Hide file tree
Showing 18 changed files with 45 additions and 32 deletions.
6 changes: 3 additions & 3 deletions src/language/helpers/safe-ds-node-mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,10 @@ import { argumentsOrEmpty, parametersOrEmpty, typeArgumentsOrEmpty, typeParamete
import { isNamedArgument, isNamedTypeArgument } from './checks.js';

export class SafeDsNodeMapper {
private readonly typeComputer: SafeDsTypeComputer;
private readonly typeComputer: () => SafeDsTypeComputer;

constructor(services: SafeDsServices) {
this.typeComputer = new SafeDsTypeComputer(services);
this.typeComputer = () => services.types.TypeComputer;
}

/**
Expand All @@ -36,7 +36,7 @@ export class SafeDsNodeMapper {
if (isSdsAnnotationCall(node)) {
return node.annotation?.ref;
} else if (isSdsCall(node)) {
const receiverType = this.typeComputer.computeType(node.receiver);
const receiverType = this.typeComputer().computeType(node.receiver);
if (receiverType instanceof CallableType) {
return receiverType.sdsCallable;
} else if (receiverType instanceof StaticType) {
Expand Down
29 changes: 16 additions & 13 deletions src/language/typing/safe-ds-type-computer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,19 @@ import {
resultsOrEmpty,
typeArgumentsOrEmpty,
} from '../helpers/shortcuts.js';
import { SafeDsNodeMapper } from '../helpers/safe-ds-node-mapper.js';

export class SafeDsTypeComputer {
readonly astNodeLocator: AstNodeLocator;
readonly coreClasses: SafeDsCoreClasses;
private readonly astNodeLocator: AstNodeLocator;
private readonly coreClasses: SafeDsCoreClasses;
private readonly nodeMapper: SafeDsNodeMapper;

readonly typeCache: WorkspaceCache<string, Type>;

constructor(readonly services: SafeDsServices) {
this.astNodeLocator = services.workspace.AstNodeLocator;
this.coreClasses = services.builtins.CoreClasses;
this.nodeMapper = services.helpers.NodeMapper;

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

// Lambda passed as argument
/* c8 ignore start */
if (isSdsArgument(containerOfLambda)) {
// val containerType = when (val container = callable.eContainer()) {
// is SdsArgument -> container.parameterOrNull()?.inferType(context)
// }
//
// return when (containerType) {
// is CallableType -> containerType.parameters.getOrElse(thisIndex) { Any(context) }
// else -> Any(context)
// }
const parameter = this.nodeMapper.argumentToParameterOrUndefined(containerOfLambda);
if (!parameter) {
return UnknownType;
}

return NotImplementedType;
const parameterType = this.computeType(parameter?.type);
if (!(parameterType instanceof CallableType)) {
return UnknownType;
}

const parameterPosition = node.$containerIndex ?? -1;
return parameterType.getParameterTypeByPosition(parameterPosition) ?? UnknownType;
}
/* c8 ignore stop */

// Yielded lambda
else if (isSdsAssignment(containerOfLambda)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.typing.declarations.parameters.ofBlockLambdas
package tests.typing.declarations.parameters.ofBlockLambdas.thatAreIsolated

segment mySegment() {
// $TEST$ serialization $Unknown
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.typing.declarations.parameters.ofBlockLambdas
package tests.typing.declarations.parameters.ofBlockLambdas.thatArePassedAsArguments

// $TEST$ equivalence_class parameterType1
fun higherOrderFunction1(param: (a: »String«) -> ())
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.typing.declarations.parameters.ofBlockLambdas
package tests.typing.declarations.parameters.ofBlockLambdas.thatAreYielded

segment mySegment() -> (
// $TEST$ equivalence_class parameterType2
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.typing.declarations.parameters.ofBlockLambdas
package tests.typing.declarations.parameters.ofBlockLambdas.withManifestTypes

segment mySegment() {
// $TEST$ equivalence_class parameterType3
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.typing.declarations.parameters.ofExpressionLambdas
package tests.typing.declarations.parameters.ofExpressionLambdas.thatAreIsolated

segment mySegment() {
// $TEST$ serialization $Unknown
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.typing.declarations.parameters.ofExpressionLambdas
package tests.typing.declarations.parameters.ofExpressionLambdas.thatArePassedAsArguments

// $TEST$ equivalence_class parameterType1
fun higherOrderFunction1(param: (a: »String«) -> r: String)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.typing.declarations.parameters.ofExpressionLambdas
package tests.typing.declarations.parameters.ofExpressionLambdas.thatAreYielded

segment mySegment() -> (
// $TEST$ equivalence_class parameterType2
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.typing.declarations.parameters.ofExpressionLambdas
package tests.typing.declarations.parameters.ofExpressionLambdas.withManifestTypes

segment mySegment() {
// $TEST$ equivalence_class parameterType3
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.typing.expressions.blockLambdas
package tests.typing.expressions.blockLambdas.thatAreIsolated

segment mySegment() {
// $TEST$ serialization (p: $Unknown) -> (r: Int, s: $Unknown)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package tests.typing.expressions.blockLambdas
package tests.typing.expressions.blockLambdas.thatArePassedAsArguments

fun higherOrderFunction1(param: (p: String) -> (r: Int, s: String))
fun higherOrderFunction2(param: () -> ())
fun normalFunction(param: Int)
fun parameterlessFunction()

segment mySegment() {
// $TEST$ serialization (p: String) -> (r: Int, s: String)
Expand Down Expand Up @@ -37,4 +38,9 @@ segment mySegment() {
normalFunction(param = »(p) {
yield r, yield s = 1;
}«);

// $TEST$ serialization (p: $Unknown) -> (r: Int, s: $Unknown)
parameterlessFunction(»(p) {
yield r, yield s = 1;
}«);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.typing.expressions.blockLambdas
package tests.typing.expressions.blockLambdas.thatAreYielded

segment mySegment() -> (
r: (p: String) -> (r: Int, s: String),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.typing.expressions.blockLambdas
package tests.typing.expressions.blockLambdas.withManifestTypes

segment mySegment() {
// $TEST$ serialization (p: Int) -> (r: Int, s: String)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.typing.expressions.expressionLambdas
package tests.typing.expressions.expressionLambdas.thatAreIsolated

segment mySegment() {
// $TEST$ serialization (p: $Unknown) -> (result: Int)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
package tests.typing.expressions.expressionLambdas
package tests.typing.expressions.expressionLambdas.thatArePassedAsArguments

fun higherOrderFunction1(param: (p: String) -> (r: Int))
fun higherOrderFunction2(param: () -> ())
fun normalFunction(param: Int)
fun parameterlessFunction()

segment mySegment() {
// $TEST$ serialization (p: String) -> (result: Int)
Expand All @@ -22,4 +23,7 @@ segment mySegment() {

// $TEST$ serialization (p: $Unknown) -> (result: Int)
normalFunction(param = »(p) -> 1«);

// $TEST$ serialization (p: $Unknown) -> (result: Int)
parameterlessFunction(»(p) -> 1«);
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.typing.expressions.expressionLambdas
package tests.typing.expressions.expressionLambdas.thatAreYielded

segment mySegment() -> (
r: (p: String) -> (),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package tests.typing.expressions.expressionLambdas
package tests.typing.expressions.expressionLambdas.withManifestTypes

segment mySegment() {
// $TEST$ serialization (p: Int) -> (result: Int)
Expand Down

0 comments on commit 25c8707

Please sign in to comment.