aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2024-12-19 18:39:32 +0000
committerMichael Williamson <mike@zwobble.org>2024-12-19 18:39:32 +0000
commitfd8ec8d57f27a669e657d80c4534dd09dc922b4f (patch)
tree6c20fc7e01716b7caa28864cfa1404ce157a6d71 /src
parent69d904e54d413e58ee854de474fbd82d3e94a81e (diff)
Type check method parameters
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java27
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java71
2 files changed, 85 insertions, 13 deletions
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
index f525a809..d6b8b813 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
@@ -865,18 +865,21 @@ public class TypeChecker {
param.source()
);
- var positionalParams = typedSignature.params().positional().stream()
- .map(typedParamNode -> {
- // TODO: check that type is not present
- return thisType
- .map(type -> new PartialFunctionSignature.Param(
- typedParamNode.name(),
- type,
- typedParamNode.source()
- ))
- .orElseGet(() -> typedParamNodeToParam.apply(typedParamNode));
- })
- .toList();
+ var positionalParams = new ArrayList<PartialFunctionSignature.Param>();
+ for (var paramIndex = 0; paramIndex < typedSignature.params().positional().size(); paramIndex++) {
+ var typedParamNode = typedSignature.params().positional().get(paramIndex);
+ var currentParamIndex = paramIndex;
+ var paramType = thisType
+ .filter(type -> currentParamIndex == 0)
+ // TODO: check that explicit type is not present
+ .map(type -> new PartialFunctionSignature.Param(
+ typedParamNode.name(),
+ type,
+ typedParamNode.source()
+ ))
+ .orElseGet(() -> typedParamNodeToParam.apply(typedParamNode));
+ positionalParams.add(paramType);
+ }
var namedParams = typedSignature.params().named().stream()
.map(typedParamNodeToParam)
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java
index eba1b735..09df039c 100644
--- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerStructDefinitionTests.java
@@ -282,7 +282,7 @@ public class TypeCheckerStructDefinitionTests {
}
@Test
- public void canTypeCheckMethodWithNoParams() {
+ public void canTypeCheckMethodWithOnlyThisParam() {
var untyped = UntypedStructDefinitionNode.builder()
.withName("ExampleStruct")
.addMethod(
@@ -328,4 +328,73 @@ public class TypeCheckerStructDefinitionTests {
))
);
}
+
+ @Test
+ public void canTypeCheckMethodWithMultipleParams() {
+ var untyped = UntypedStructDefinitionNode.builder()
+ .withName("ExampleStruct")
+ .addMethod(
+ UntypedFunctionDefinitionNode.builder()
+ .addPositionalParam("this", Optional.empty())
+ .addPositionalParam("a", Untyped.typeLevelReference("Bool"))
+ .addNamedParam("b", Untyped.typeLevelReference("Int"))
+ .withName("a")
+ .withReturnType(Untyped.typeLevelReference("Unit"))
+ .build()
+ )
+ .build();
+ var context = TypeCheckerContext.EMPTY
+ .enterGlobal(P.map(
+ Map.entry("Unit", Types.metaType(Types.UNIT)),
+ Map.entry("Bool", Types.metaType(Types.BOOL)),
+ Map.entry("Int", Types.metaType(Types.INT))
+ ));
+
+ var typed = typeCheckNamespaceStatement(untyped, context);
+
+ assertThat(
+ typed.value(),
+ isTypedStructDefinitionNode()
+ .withMethods(isSequence(
+ isTypedFunctionDefinitionNode()
+ .withParams(isTypedParamsNode(
+ isSequence(
+ isTypedParamNode("this", isOptionalEmpty()),
+ isTypedParamNode(
+ "a",
+ isOptionalOf(isTypedTypeLevelReferenceNode(
+ "Bool",
+ Types.BOOL
+ ))
+ )
+ ),
+ isSequence(
+ isTypedParamNode(
+ "b",
+ isOptionalOf(isTypedTypeLevelReferenceNode(
+ "Int",
+ Types.INT
+ ))
+ )
+ )
+ ))
+ ))
+ );
+ var structTypeInfo = typed.context().toTypeInfos()
+ .structTypeInfo(Types.struct(NAMESPACE_NAME, "ExampleStruct"))
+ .orElseThrow();
+ assertThat(
+ structTypeInfo,
+ has("methods", x -> x.methods(), isSequence(
+ equalTo(new MethodInfo(
+ "a",
+ FunctionType.builder()
+ .addPositionalParam(Types.BOOL)
+ .addNamedParam("b", Types.INT)
+ .withReturnType(Types.UNIT)
+ .build()
+ ))
+ ))
+ );
+ }
}