aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-06-10 15:01:43 +0100
committerMichael Williamson <mike@zwobble.org>2023-06-10 15:01:43 +0100
commit3352299423098fa32275345f46beec19892f6e99 (patch)
treef46760d005e82a841fd69fc87d9125d1f3867205 /src/test/java
parent01bd9f9bdfa3d6257d5fd0177c769b30de8f4930 (diff)
Add minimal type checking for function definition
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/shedlang/compiler/ast/typed/TypedFunctionDefinitionNodeMatcher.java51
-rw-r--r--src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java26
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java38
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerTypeLevelReferenceTests.java7
4 files changed, 118 insertions, 4 deletions
diff --git a/src/test/java/org/shedlang/compiler/ast/typed/TypedFunctionDefinitionNodeMatcher.java b/src/test/java/org/shedlang/compiler/ast/typed/TypedFunctionDefinitionNodeMatcher.java
new file mode 100644
index 00000000..04a06f64
--- /dev/null
+++ b/src/test/java/org/shedlang/compiler/ast/typed/TypedFunctionDefinitionNodeMatcher.java
@@ -0,0 +1,51 @@
+package org.shedlang.compiler.ast.typed;
+
+import org.pcollections.Empty;
+import org.pcollections.PVector;
+import org.shedlang.compiler.testing.MatcherBuilder;
+import org.zwobble.precisely.Matcher;
+
+import java.util.Optional;
+
+import static org.zwobble.precisely.Matchers.equalTo;
+import static org.zwobble.precisely.Matchers.has;
+
+public class TypedFunctionDefinitionNodeMatcher extends MatcherBuilder<TypedNamespaceStatementNode, TypedFunctionDefinitionNode, TypedFunctionDefinitionNodeMatcher> {
+ public static TypedFunctionDefinitionNodeMatcher empty() {
+ return new TypedFunctionDefinitionNodeMatcher(Empty.vector());
+ }
+
+ public TypedFunctionDefinitionNodeMatcher(PVector<Matcher<? super TypedFunctionDefinitionNode>> submatchers) {
+ super(submatchers);
+ }
+
+ @Override
+ protected Class<TypedFunctionDefinitionNode> expectedType() {
+ return TypedFunctionDefinitionNode.class;
+ }
+
+ @Override
+ protected TypedFunctionDefinitionNodeMatcher create(PVector<Matcher<? super TypedFunctionDefinitionNode>> submatchers) {
+ return new TypedFunctionDefinitionNodeMatcher(submatchers);
+ }
+
+ public TypedFunctionDefinitionNodeMatcher withBody(Matcher<Iterable<TypedFunctionStatementNode>> body) {
+ return with(has("body", x -> x.body(), body));
+ }
+
+ public TypedFunctionDefinitionNodeMatcher withEffect(Matcher<Optional<? extends TypedTypeLevelExpressionNode<?>>> effect) {
+ return with(has("effect", x -> x.effect(), effect));
+ }
+
+ public TypedFunctionDefinitionNodeMatcher withName(String name) {
+ return with(has("name", x -> x.name(), equalTo(name)));
+ }
+
+ public TypedFunctionDefinitionNodeMatcher withParams(Matcher<TypedParamsNode> params) {
+ return with(has("params", x -> x.params(), params));
+ }
+
+ public TypedFunctionDefinitionNodeMatcher withReturnType(Matcher<TypedTypeLevelExpressionNode<?>> returnType) {
+ return with(has("returnType", x -> x.returnType(), returnType));
+ }
+}
diff --git a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
index c3aaa729..474646d4 100644
--- a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
+++ b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
@@ -36,6 +36,10 @@ public class TypedNodeMatchers {
);
}
+ public static TypedFunctionDefinitionNodeMatcher isTypedFunctionDefinitionNode() {
+ return TypedFunctionDefinitionNodeMatcher.empty();
+ }
+
public static Matcher<TypedExpressionNode> isTypedIntLiteralNode(int value) {
return isTypedIntLiteralNode(BigInteger.valueOf(value));
}
@@ -57,6 +61,26 @@ public class TypedNodeMatchers {
);
}
+ public static Matcher<TypedParamNode> isTypedParamNode(
+ String name,
+ Matcher<TypedTypeLevelExpressionNode<?>> type
+ ) {
+ return allOf(
+ has("name", x -> x.name(), equalTo(name)),
+ has("type", x -> x.type(), type)
+ );
+ }
+
+ public static Matcher<TypedParamsNode> isTypedParamsNode(
+ Matcher<Iterable<TypedParamNode>> positional,
+ Matcher<Iterable<TypedParamNode>> named
+ ) {
+ return allOf(
+ has("positional", x -> x.positional(), positional),
+ has("named", x -> x.named(), named)
+ );
+ }
+
public static Matcher<TypedExpressionNode> isTypedReferenceNode(String name, Type type) {
return instanceOf(
TypedReferenceNode.class,
@@ -72,7 +96,7 @@ public class TypedNodeMatchers {
);
}
- public static Matcher<TypedTypeLevelExpressionNode> isTypedTypeLevelReferenceNode(
+ public static Matcher<TypedTypeLevelExpressionNode<?>> isTypedTypeLevelReferenceNode(
String name,
TypeLevelValue value
) {
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java
new file mode 100644
index 00000000..88027a69
--- /dev/null
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java
@@ -0,0 +1,38 @@
+package org.shedlang.compiler.typechecker;
+
+import org.junit.jupiter.api.Test;
+import org.shedlang.compiler.ast.untyped.Untyped;
+import org.shedlang.compiler.ast.untyped.UntypedFunctionDefinitionNode;
+import org.shedlang.compiler.types.Types;
+import org.shedlang.compiler.util.P;
+
+import java.util.Map;
+
+import static org.shedlang.compiler.ast.typed.TypedNodeMatchers.*;
+import static org.zwobble.precisely.AssertThat.assertThat;
+import static org.zwobble.precisely.Matchers.isOptionalEmpty;
+import static org.zwobble.precisely.Matchers.isSequence;
+
+public class TypeCheckerFunctionDefinitionTests {
+ @Test
+ public void canTypeCheckMinimalFunctionDefinition() {
+ var untyped = UntypedFunctionDefinitionNode.builder()
+ .withName("f")
+ .withReturnType(Untyped.typeLevelReference("Unit"))
+ .build();
+ var context = TypeCheckerContext.EMPTY
+ .enter(P.map(Map.entry("Unit", Types.metaType(Types.UNIT))));
+
+ var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
+
+ assertThat(
+ typed,
+ isTypedFunctionDefinitionNode()
+ .withName("f")
+ .withParams(isTypedParamsNode(isSequence(), isSequence()))
+ .withEffect(isOptionalEmpty())
+ .withReturnType(isTypedTypeLevelReferenceNode("Unit", Types.UNIT))
+ .withBody(isSequence())
+ );
+ }
+}
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerTypeLevelReferenceTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerTypeLevelReferenceTests.java
index a0597778..13e7dc2c 100644
--- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerTypeLevelReferenceTests.java
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerTypeLevelReferenceTests.java
@@ -5,6 +5,7 @@ import org.shedlang.compiler.ast.untyped.Untyped;
import org.shedlang.compiler.typechecker.errors.UnexpectedTypeError;
import org.shedlang.compiler.typechecker.errors.UnknownVariableError;
import org.shedlang.compiler.typechecker.typesets.TypeSets;
+import org.shedlang.compiler.types.Type;
import org.shedlang.compiler.types.Types;
import org.shedlang.compiler.util.P;
@@ -22,7 +23,7 @@ public class TypeCheckerTypeLevelReferenceTests {
var context = TypeCheckerContext.EMPTY
.enter(P.map(Map.entry("String", Types.metaType(Types.STRING))));
- var typed = TypeChecker.typeCheckTypeLevelExpression(untyped, context);
+ var typed = TypeChecker.typeCheckTypeLevelExpression(Type.class, untyped, context);
assertThat(typed, isTypedTypeLevelReferenceNode("String", Types.STRING));
}
@@ -35,7 +36,7 @@ public class TypeCheckerTypeLevelReferenceTests {
var error = assertThrows(
UnexpectedTypeError.class,
- () -> TypeChecker.typeCheckTypeLevelExpression(untyped, context)
+ () -> TypeChecker.typeCheckTypeLevelExpression(Type.class, untyped, context)
);
assertThat(error.expected(), equalTo(TypeSets.TYPE_LEVEL_VALUE));
@@ -50,7 +51,7 @@ public class TypeCheckerTypeLevelReferenceTests {
var error = assertThrows(
UnknownVariableError.class,
- () -> TypeChecker.typeCheckTypeLevelExpression(untyped, context)
+ () -> TypeChecker.typeCheckTypeLevelExpression(Type.class, untyped, context)
);
assertThat(error.variableName(), equalTo("String"));