aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-09-17 17:34:54 +0100
committerMichael Williamson <mike@zwobble.org>2023-09-17 17:34:54 +0100
commitf544626a85a2e5fedaec200c231b69728fbf99e9 (patch)
treef28d30e842082cce2afe58fda60ec5c0e3093376 /src/test/java
parentd6c6abb4e28f851969a40ff207648308be031090 (diff)
Type check assignment to tuple target
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java9
-rw-r--r--src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java4
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerAssignTests.java41
3 files changed, 50 insertions, 4 deletions
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 37a583ba..9f66f16c 100644
--- a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
+++ b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
@@ -228,6 +228,15 @@ public class TypedNodeMatchers {
);
}
+ public static Matcher<TypedTargetNode> isTypedTargetTuple(
+ Matcher<Iterable<? extends TypedTargetNode>> elements
+ ) {
+ return instanceOf(
+ TypedTargetNode.Tuple.class,
+ has("elements", x -> x.elements(), elements)
+ );
+ }
+
public static Matcher<TypedTargetNode> isTypedTargetVal(String name) {
return instanceOf(
TypedTargetNode.Val.class,
diff --git a/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java b/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java
index a41ab8d7..8c046e4a 100644
--- a/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java
+++ b/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java
@@ -154,6 +154,10 @@ public class Untyped {
return new UntypedTargetNode.Reassign(name, Sources.NULL);
}
+ public static UntypedTargetNode targetTuple(List<UntypedTargetNode> elements) {
+ return new UntypedTargetNode.Tuple(elements, Sources.NULL);
+ }
+
public static UntypedTargetNode targetVal(String name) {
return new UntypedTargetNode.Val(name, Sources.NULL);
}
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerAssignTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerAssignTests.java
index df18c0bb..20f3ef5d 100644
--- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerAssignTests.java
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerAssignTests.java
@@ -12,16 +12,17 @@ import org.shedlang.compiler.typechecker.typesets.TypeSets;
import org.shedlang.compiler.types.Types;
import org.shedlang.compiler.util.P;
+import java.util.List;
import java.util.Map;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.shedlang.compiler.ast.typed.TypedNodeMatchers.*;
import static org.zwobble.precisely.AssertThat.assertThat;
-import static org.zwobble.precisely.Matchers.equalTo;
+import static org.zwobble.precisely.Matchers.*;
public class TypeCheckerAssignTests {
@Test
- public void canTypeCheckAssign() {
+ public void canTypeCheckReassign() {
var untyped = Untyped.assign(Untyped.targetReassign("x"), Untyped.stringLiteral("hello"));
var context = TypeCheckerContext.EMPTY
.enterNamespace(P.map(
@@ -37,7 +38,7 @@ public class TypeCheckerAssignTests {
}
@Test
- public void whenExpressionIsNotSubTypeOfTargetVariableThenErrorIsThrown() {
+ public void whenExpressionIsNotSubTypeOfReassignTargetVariableThenErrorIsThrown() {
var untyped = Untyped.assign(Untyped.targetReassign("x"), Untyped.stringLiteral("hello"));
var context = TypeCheckerContext.EMPTY
.enterNamespace(P.map(
@@ -54,7 +55,7 @@ public class TypeCheckerAssignTests {
}
@Test
- public void whenTargetIsNotVarThenErrorIsThrown() {
+ public void whenReassignTargetIsNotVarThenErrorIsThrown() {
var untyped = Untyped.assign(Untyped.targetReassign("x"), Untyped.stringLiteral("hello"));
var context = TypeCheckerContext.EMPTY
.enterNamespace(P.map(
@@ -67,6 +68,38 @@ public class TypeCheckerAssignTests {
);
}
+ @Test
+ public void canTypeCheckTupleTarget() {
+ var untyped = Untyped.assign(
+ Untyped.targetTuple(List.of(
+ Untyped.targetVal("a"),
+ Untyped.targetVal("b"),
+ Untyped.targetVal("c")
+ )),
+ Untyped.reference("x")
+ );
+ var tupleType = Types.tuple(List.of(
+ Types.STRING,
+ Types.INT,
+ Types.BOOL
+ ));
+ var context = TypeCheckerContext.EMPTY
+ .enterNamespace(P.map(
+ Map.entry("x", Variable.defined(tupleType, VariableType.VAR))
+ ));
+
+ var typed = typeCheckFunctionStatement(untyped, context);
+
+ assertThat(typed.value(), isTypedAssignNode(
+ isTypedTargetTuple(isSequence(
+ isTypedTargetVal("a"),
+ isTypedTargetVal("b"),
+ isTypedTargetVal("c")
+ )),
+ anything()
+ ));
+ }
+
private static TypeCheckerResult<? extends TypedFunctionStatementNode> typeCheckFunctionStatement(
UntypedFunctionStatementNode untyped,
TypeCheckerContext context