Skip to content

Commit

Permalink
feat: compute types of parameters of lambdas that are passed as argum…
Browse files Browse the repository at this point in the history
…ents
  • Loading branch information
lars-reimann committed Oct 5, 2023
1 parent b6966c6 commit 54947b1
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 16 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
Expand Up @@ -3,6 +3,7 @@ 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
Expand Up @@ -3,6 +3,7 @@ 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«);
}

0 comments on commit 54947b1

Please sign in to comment.