Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: compute types of lambdas that are passed as arguments #604

Merged
merged 3 commits into from
Oct 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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