aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-12-23 23:12:57 +0000
committerMichael Williamson <mike@zwobble.org>2023-12-23 23:12:57 +0000
commitc4498af1d2fb1f9456d16a39daba9e841d3537b9 (patch)
treea8c12b9f748edb767261d1674cc12664d4d1d2b1 /src/test/java
parent04204c8c4fb943b98409678bc47b924629bc6b1b (diff)
Add basic type checking for constructed types
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.java7
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerConstructedTypeTests.java87
-rw-r--r--src/test/java/org/shedlang/compiler/types/TypeMatchers.java10
4 files changed, 58 insertions, 55 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 4a5bf1c5..65f5f24b 100644
--- a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
+++ b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java
@@ -93,6 +93,15 @@ public class TypedNodeMatchers {
);
}
+ public static Matcher<TypedTypeLevelExpressionNode<?>> isTypedConstructedTypeNode(
+ Matcher<ConstructedType<?>> value
+ ) {
+ return instanceOf(
+ TypedConstructedTypeNode.class,
+ has("value", x -> x.value(), value)
+ );
+ }
+
public static TypedEffectDefinitionNodeMatcher isTypedEffectDefinitionNode() {
return TypedEffectDefinitionNodeMatcher.empty();
}
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 559ca461..41c52802 100644
--- a/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java
+++ b/src/test/java/org/shedlang/compiler/ast/untyped/Untyped.java
@@ -78,6 +78,13 @@ public class Untyped {
return new UntypedConditionalBranchNode(condition, body, Sources.NULL);
}
+ public static UntypedConstructedTypeNode constructedType(
+ UntypedTypeLevelExpressionNode receiver,
+ List<UntypedTypeLevelExpressionNode> args
+ ) {
+ return new UntypedConstructedTypeNode(receiver, args, Sources.NULL);
+ }
+
public static UntypedBinaryOperationNode equals(
UntypedExpressionNode left,
UntypedExpressionNode right
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerConstructedTypeTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerConstructedTypeTests.java
index a3c78120..80c7e82d 100644
--- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerConstructedTypeTests.java
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerConstructedTypeTests.java
@@ -2,73 +2,50 @@ package org.shedlang.compiler.typechecker;
import org.junit.jupiter.api.Test;
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.Effects;
+import org.shedlang.compiler.types.NamespaceName;
+import org.shedlang.compiler.types.TypeParam;
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.isTypedTypeLevelReferenceNode;
+import static org.shedlang.compiler.ast.typed.TypedNodeMatchers.isTypedConstructedTypeNode;
+import static org.shedlang.compiler.types.TypeMatchers.isConstructedType;
import static org.zwobble.precisely.AssertThat.assertThat;
import static org.zwobble.precisely.Matchers.equalTo;
+import static org.zwobble.precisely.Matchers.isSequence;
public class TypeCheckerConstructedTypeTests {
@Test
- public void whenNameIsBoundInEnvironmentThenTypeIsUsedFromEnvironment() {
- var untyped = Untyped.typeLevelReference("String");
- var context = TypeCheckerContext.EMPTY
- .enterGlobal(P.map(Map.entry("String", Types.metaType(Types.STRING))));
-
- var typed = TypeChecker.typeCheckTypeLevelExpression(TypeSets.META_TYPE, untyped, context);
-
- assertThat(typed, isTypedTypeLevelReferenceNode("String", Types.STRING));
- }
-
- @Test
- public void whenNameRefersToNonTypeLevelValueThenErrorIsThrown() {
- var untyped = Untyped.typeLevelReference("String");
- var context = TypeCheckerContext.EMPTY
- .enterGlobal(P.map(Map.entry("String", Types.STRING)));
-
- var error = assertThrows(
- UnexpectedTypeError.class,
- () -> TypeChecker.typeCheckTypeLevelExpression(TypeSets.META_TYPE, untyped, context)
+ public void typedNodeHasConstructedType() {
+ var untyped = Untyped.constructedType(
+ Untyped.typeLevelReference("Map"),
+ List.of(
+ Untyped.typeLevelReference("Int"),
+ Untyped.typeLevelReference("Bool")
+ )
);
-
- assertThat(error.expected(), equalTo(TypeSets.META_TYPE));
- assertThat(error.actual(), equalTo(Types.STRING));
- }
-
- @Test
- public void whenNameRefersToValueOfWrongTypeThenErrorIsThrown() {
- var untyped = Untyped.typeLevelReference("Io");
- var context = TypeCheckerContext.EMPTY
- .enterGlobal(P.map(Map.entry("Io", Types.effectType(Effects.IO))));
-
- var error = assertThrows(
- UnexpectedTypeError.class,
- () -> TypeChecker.typeCheckTypeLevelExpression(TypeSets.META_TYPE, untyped, context)
+ var structType = Types.struct(NamespaceName.of("Example", "Project"), "Map");
+ var typeConstructor = Types.typeConstructor(
+ List.of(
+ TypeParam.forStructType(structType, "K"),
+ TypeParam.forStructType(structType, "V")
+ ),
+ structType
);
-
- assertThat(error.expected(), equalTo(TypeSets.META_TYPE));
- assertThat(error.actual(), equalTo(Types.effectType(Effects.IO)));
- }
-
- @Test
- public void whenNameIsNotBoundInEnvironmentThenErrorIsThrown() {
- var untyped = Untyped.typeLevelReference("String");
var context = TypeCheckerContext.EMPTY
- .enterGlobal(P.map(Map.entry("Int", Types.metaType(Types.INT))));
-
- var error = assertThrows(
- UnknownVariableError.class,
- () -> TypeChecker.typeCheckTypeLevelExpression(TypeSets.META_TYPE, untyped, context)
- );
-
- assertThat(error.variableName(), equalTo("String"));
+ .enterGlobal(P.map(
+ Map.entry("Map", Types.typeConstructorType(typeConstructor)),
+ Map.entry("Int", Types.metaType(Types.INT)),
+ Map.entry("Bool", Types.metaType(Types.BOOL))
+ ));
+
+ var typed = TypeChecker.typeCheckTypeExpression(untyped, context);
+
+ assertThat(typed, isTypedConstructedTypeNode(isConstructedType(
+ equalTo(typeConstructor),
+ isSequence(equalTo(Types.INT), equalTo(Types.BOOL))
+ )));
}
}
diff --git a/src/test/java/org/shedlang/compiler/types/TypeMatchers.java b/src/test/java/org/shedlang/compiler/types/TypeMatchers.java
index b52bbdff..9b6f0d54 100644
--- a/src/test/java/org/shedlang/compiler/types/TypeMatchers.java
+++ b/src/test/java/org/shedlang/compiler/types/TypeMatchers.java
@@ -44,6 +44,16 @@ public class TypeMatchers {
);
}
+ public static Matcher<ConstructedType<?>> isConstructedType(
+ Matcher<TypeConstructor<?>> constructor,
+ Matcher<Iterable<? extends Type>> args
+ ) {
+ return allOf(
+ has("constructor", x -> x.constructor(), constructor),
+ has("args", x -> x.args(), args)
+ );
+ }
+
public static Matcher<Type> isTypeLevelValueType(Matcher<TypeLevelValue> value) {
return instanceOf(TypeLevelValueType.class, has("value", x -> x.value(), value));
}