aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-03 20:16:06 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-03 20:16:06 +0100
commit958053114ed20d91a3f17746398728efc0962927 (patch)
treef9a01f2623340499d9c09170be37bd4a1eec8fa1 /src/test/java
parent777935c03a692b9f21f73b6a5fd3a49f49572374 (diff)
Type-check val as namespace statement
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/shedlang/compiler/ast/typed/TypedNamespaceNodeMatcher.java45
-rw-r--r--src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java6
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java18
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerValTests.java42
4 files changed, 98 insertions, 13 deletions
diff --git a/src/test/java/org/shedlang/compiler/ast/typed/TypedNamespaceNodeMatcher.java b/src/test/java/org/shedlang/compiler/ast/typed/TypedNamespaceNodeMatcher.java
new file mode 100644
index 00000000..0d7ecf83
--- /dev/null
+++ b/src/test/java/org/shedlang/compiler/ast/typed/TypedNamespaceNodeMatcher.java
@@ -0,0 +1,45 @@
+package org.shedlang.compiler.ast.typed;
+
+import org.pcollections.Empty;
+import org.pcollections.PVector;
+import org.zwobble.precisely.MatchResult;
+import org.zwobble.precisely.Matcher;
+import org.zwobble.precisely.TextTree;
+
+import static org.zwobble.precisely.Matchers.allOf;
+import static org.zwobble.precisely.Matchers.has;
+
+public class TypedNamespaceNodeMatcher implements Matcher<TypedNamespaceNode> {
+ private final PVector<Matcher<? super TypedNamespaceNode>> submatchers;
+
+ public static TypedNamespaceNodeMatcher empty() {
+ return new TypedNamespaceNodeMatcher(Empty.vector());
+ }
+
+ public TypedNamespaceNodeMatcher(PVector<Matcher<? super TypedNamespaceNode>> submatchers) {
+ this.submatchers = submatchers;
+ }
+
+ @Override
+ public MatchResult match(TypedNamespaceNode actual) {
+ return toMatcher().match(actual);
+ }
+
+ @Override
+ public TextTree describe() {
+ return toMatcher().describe();
+ }
+
+ private Matcher<TypedNamespaceNode> toMatcher() {
+ return allOf(submatchers);
+ }
+
+
+ public TypedNamespaceNodeMatcher withBody(
+ Matcher<Iterable<? extends TypedNamespaceStatementNode>> body
+ ) {
+ return new TypedNamespaceNodeMatcher(
+ submatchers.plus(has("body", x -> x.body(), body))
+ );
+ }
+}
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 ccda182a..bc047b82 100644
--- a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
+++ b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
@@ -61,6 +61,10 @@ public class TypedNodeMatchers {
);
}
+ public static TypedNamespaceNodeMatcher isTypedNamespaceNode() {
+ return TypedNamespaceNodeMatcher.empty();
+ }
+
public static Matcher<TypedNamespaceNode> isTypedNamespaceNode(
Matcher<Iterable<? extends TypedNamespaceStatementNode>> body,
Matcher<Iterable<? extends String>> fieldNames
@@ -124,7 +128,7 @@ public class TypedNodeMatchers {
);
}
- public static Matcher<TypedFunctionStatementNode> isTypedValNode(
+ public static Matcher<TypedNode> isTypedValNode(
Matcher<? super TypedTargetNode> target,
Matcher<? super TypedExpressionNode> expression
) {
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java
index 31f80f9b..6dea7d63 100644
--- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java
@@ -30,7 +30,7 @@ public class TypeCheckerFunctionDefinitionTests {
var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
assertThat(
- typed,
+ typed.value(),
isTypedFunctionDefinitionNode()
.withName("f")
.withParams(isTypedParamsNode(isSequence(), isSequence()))
@@ -58,7 +58,7 @@ public class TypeCheckerFunctionDefinitionTests {
var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
assertThat(
- typed,
+ typed.value(),
isTypedFunctionDefinitionNode()
.withParams(
isTypedParamsNode(
@@ -90,7 +90,7 @@ public class TypeCheckerFunctionDefinitionTests {
var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
assertThat(
- typed,
+ typed.value(),
isTypedFunctionDefinitionNode()
.withEffect(isOptionalOf(isTypedTypeLevelReferenceNode("Io", Effects.IO)))
);
@@ -108,7 +108,7 @@ public class TypeCheckerFunctionDefinitionTests {
var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
assertThat(
- typed,
+ typed.value(),
isTypedFunctionDefinitionNode()
.withBody(isSequence(
isTypedExpressionStatementNode(isTypedStringLiteralNode("hello"))
@@ -132,7 +132,7 @@ public class TypeCheckerFunctionDefinitionTests {
var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
assertThat(
- typed,
+ typed.value(),
isTypedFunctionDefinitionNode()
.withBody(isSequence(
isTypedExpressionStatementNode(isTypedReferenceNode("x", Types.STRING))
@@ -156,7 +156,7 @@ public class TypeCheckerFunctionDefinitionTests {
var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
assertThat(
- typed,
+ typed.value(),
isTypedFunctionDefinitionNode()
.withBody(isSequence(
isTypedExpressionStatementNode(isTypedReferenceNode("x", Types.STRING))
@@ -190,7 +190,7 @@ public class TypeCheckerFunctionDefinitionTests {
var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
assertThat(
- typed,
+ typed.value(),
isTypedFunctionDefinitionNode()
.withBody(isSequence(
isTypedExpressionStatementNode(isTypedCallNode().withHasEffects(true))
@@ -214,7 +214,7 @@ public class TypeCheckerFunctionDefinitionTests {
var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
assertThat(
- typed,
+ typed.value(),
isTypedFunctionDefinitionNode()
.withFreeVariables(containsExactly(
has("name", x -> x.name(), equalTo("y"))
@@ -238,7 +238,7 @@ public class TypeCheckerFunctionDefinitionTests {
var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
assertThat(
- typed,
+ typed.value(),
isTypedFunctionDefinitionNode()
.withFreeVariables(containsExactly())
);
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerValTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerValTests.java
index f09c73e9..d80522dc 100644
--- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerValTests.java
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerValTests.java
@@ -3,6 +3,7 @@ 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.ast.untyped.UntypedNamespaceNode;
import org.shedlang.compiler.typechecker.errors.DuplicateVariableName;
import org.shedlang.compiler.typechecker.errors.ReferenceBeforeDefinitionError;
import org.shedlang.compiler.types.Types;
@@ -17,7 +18,7 @@ import static org.zwobble.precisely.Matchers.*;
public class TypeCheckerValTests {
@Test
- public void expressionIsTypeChecked() {
+ public void canTypeCheckAsFunctionStatement() {
var untyped = Untyped.val(Untyped.targetVariable("x"), Untyped.stringLiteral("hello"));
var typed = TypeChecker.typeCheckFunctionStatement(untyped, TypeCheckerContext.EMPTY);
@@ -29,7 +30,19 @@ public class TypeCheckerValTests {
}
@Test
- public void valCanBeReferencedAfterDefinition() {
+ public void canTypeCheckAsNamespaceStatement() {
+ var untyped = Untyped.val(Untyped.targetVariable("x"), Untyped.stringLiteral("hello"));
+
+ var typed = TypeChecker.typeCheckNamespaceStatement(untyped, TypeCheckerContext.EMPTY);
+
+ assertThat(typed.value(), isTypedValNode(
+ isTypedTargetVariable("x"),
+ isTypedStringLiteralNode("hello")
+ ));
+ }
+
+ @Test
+ public void valCanBeReferencedAfterDefinitionInFunction() {
var untyped = UntypedFunctionDefinitionNode.builder()
.addStatement(Untyped.val(Untyped.targetVariable("x"), Untyped.stringLiteral("hello")))
.addStatement(Untyped.expressionStatement(Untyped.reference("x")))
@@ -42,7 +55,7 @@ public class TypeCheckerValTests {
var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
assertThat(
- typed,
+ typed.value(),
isTypedFunctionDefinitionNode()
.withBody(isSequence(
isTypedValNode(anything(), anything()),
@@ -52,6 +65,29 @@ public class TypeCheckerValTests {
}
@Test
+ public void valCanBeReferencedAfterDefinitionInNamespace() {
+ var untyped = UntypedNamespaceNode.builder()
+ .addStatement(Untyped.val(Untyped.targetVariable("x"), Untyped.stringLiteral("hello")))
+ .addStatement(Untyped.val(Untyped.targetVariable("y"), Untyped.reference("x")))
+ .build();
+ var context = TypeCheckerContext.EMPTY
+ .enterBlockWithDefinedVariables(P.map(
+ Map.entry("Unit", Types.metaType(Types.UNIT))
+ ));
+
+ var typed = TypeChecker.typeCheckNamespace(untyped, context);
+
+ assertThat(
+ typed.value(),
+ isTypedNamespaceNode()
+ .withBody(isSequence(
+ isTypedValNode(anything(), anything()),
+ isTypedValNode(anything(), isTypedReferenceNode("x", Types.STRING))
+ ))
+ );
+ }
+
+ @Test
public void valCannotBeReferencedBeforeDefinition() {
var untyped = UntypedFunctionDefinitionNode.builder()
.addStatement(Untyped.expressionStatement(Untyped.reference("x")))