aboutsummaryrefslogtreecommitdiff
path: root/src/test/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-07-16 17:57:35 +0100
committerMichael Williamson <mike@zwobble.org>2023-07-16 17:57:35 +0100
commit1fe69b87b1c409c3a4b7a27a165a8e0b71c62fa7 (patch)
treefb030eb472dfb51b7a456c913cd9dd1eb5e922e7 /src/test/java
parent4b88193205d2b681cb77b136ec3b858b58b42ede (diff)
Require variables to be declared before definition
Diffstat (limited to 'src/test/java')
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerContextTests.java17
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java39
-rw-r--r--src/test/java/org/shedlang/compiler/typechecker/TypeCheckerValTests.java40
3 files changed, 74 insertions, 22 deletions
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerContextTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerContextTests.java
index 650f23d5..f8529083 100644
--- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerContextTests.java
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerContextTests.java
@@ -2,11 +2,13 @@ package org.shedlang.compiler.typechecker;
import org.junit.jupiter.api.Test;
import org.shedlang.compiler.sources.Sources;
+import org.shedlang.compiler.typechecker.errors.UnknownVariableError;
import org.shedlang.compiler.types.Types;
import org.shedlang.compiler.util.P;
import java.util.Map;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.zwobble.precisely.AssertThat.assertThat;
import static org.zwobble.precisely.Matchers.equalTo;
import static org.zwobble.precisely.Matchers.isOptionalOf;
@@ -25,4 +27,19 @@ public class TypeCheckerContextTests {
assertThat(result.value(), isOptionalOf(equalTo(TypeCheckerContext.defined(Types.STRING))));
}
+
+ @Test
+ public void givenVariableIsUnknownWhenVariableIsDefinedThenErrorIsThrown() {
+ var context = TypeCheckerContext.EMPTY
+ .enterNamespace(P.map(
+ Map.entry("y", TypeCheckerContext.undefined())
+ ));
+
+ var error = assertThrows(
+ UnknownVariableError.class,
+ () -> context.define("x", Types.STRING, Sources.NULL)
+ );
+
+ assertThat(error.variableName(), equalTo("x"));
+ }
}
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java
index a39ec685..ee88b457 100644
--- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerFunctionDefinitionTests.java
@@ -1,6 +1,7 @@
package org.shedlang.compiler.typechecker;
import org.junit.jupiter.api.Test;
+import org.shedlang.compiler.ast.typed.TypedNamespaceStatementNode;
import org.shedlang.compiler.ast.untyped.Untyped;
import org.shedlang.compiler.ast.untyped.UntypedCallNode;
import org.shedlang.compiler.ast.untyped.UntypedFunctionDefinitionNode;
@@ -30,7 +31,7 @@ public class TypeCheckerFunctionDefinitionTests {
var context = TypeCheckerContext.EMPTY
.enterNamespaceWithDefinedVariables(P.map(Map.entry("Unit", Types.metaType(Types.UNIT))));
- var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
+ var typed = typeCheckNamespaceStatement(untyped, context);
assertThat(
typed.value(),
@@ -58,7 +59,7 @@ public class TypeCheckerFunctionDefinitionTests {
Map.entry("Unit", Types.metaType(Types.UNIT))
));
- var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
+ var typed = typeCheckNamespaceStatement(untyped, context);
assertThat(
typed.value(),
@@ -90,7 +91,7 @@ public class TypeCheckerFunctionDefinitionTests {
Map.entry("Unit", Types.metaType(Types.UNIT))
));
- var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
+ var typed = typeCheckNamespaceStatement(untyped, context);
assertThat(
typed.value(),
@@ -108,7 +109,7 @@ public class TypeCheckerFunctionDefinitionTests {
var context = TypeCheckerContext.EMPTY
.enterNamespaceWithDefinedVariables(P.map(Map.entry("Unit", Types.metaType(Types.UNIT))));
- var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
+ var typed = typeCheckNamespaceStatement(untyped, context);
assertThat(
typed.value(),
@@ -132,7 +133,7 @@ public class TypeCheckerFunctionDefinitionTests {
Map.entry("Unit", Types.metaType(Types.UNIT))
));
- var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
+ var typed = typeCheckNamespaceStatement(untyped, context);
assertThat(
typed.value(),
@@ -156,7 +157,7 @@ public class TypeCheckerFunctionDefinitionTests {
Map.entry("Unit", Types.metaType(Types.UNIT))
));
- var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
+ var typed = typeCheckNamespaceStatement(untyped, context);
assertThat(
typed.value(),
@@ -170,6 +171,7 @@ public class TypeCheckerFunctionDefinitionTests {
@Test
public void bodyHasEffectAsDefinedInSignature() {
var untyped = UntypedFunctionDefinitionNode.builder()
+ .withName("g")
.withEffect(Untyped.typeLevelReference("Io"))
.withReturnType(Untyped.typeLevelReference("Unit"))
.addStatement(Untyped.expressionStatement(
@@ -190,7 +192,7 @@ public class TypeCheckerFunctionDefinitionTests {
Map.entry("Unit", Types.metaType(Types.UNIT))
));
- var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
+ var typed = typeCheckNamespaceStatement(untyped, context);
assertThat(
typed.value(),
@@ -214,7 +216,7 @@ public class TypeCheckerFunctionDefinitionTests {
var error = assertThrows(
UnexpectedTypeError.class,
- () -> TypeChecker.typeCheckNamespaceStatement(untyped, context)
+ () -> typeCheckNamespaceStatement(untyped, context)
);
assertThat(error.expected(), equalTo(TypeSets.type(Types.STRING)));
@@ -231,7 +233,7 @@ public class TypeCheckerFunctionDefinitionTests {
Map.entry("Unit", Types.metaType(Types.UNIT))
));
- TypeChecker.typeCheckNamespaceStatement(untyped, context);
+ typeCheckNamespaceStatement(untyped, context);
}
@Test
@@ -246,7 +248,7 @@ public class TypeCheckerFunctionDefinitionTests {
var error = assertThrows(
UnexpectedTypeError.class,
- () -> TypeChecker.typeCheckNamespaceStatement(untyped, context)
+ () -> typeCheckNamespaceStatement(untyped, context)
);
assertThat(error.expected(), equalTo(TypeSets.type(Types.STRING)));
@@ -264,7 +266,7 @@ public class TypeCheckerFunctionDefinitionTests {
Map.entry("String", Types.metaType(Types.STRING))
));
- TypeChecker.typeCheckNamespaceStatement(untyped, context);
+ typeCheckNamespaceStatement(untyped, context);
}
@Test
@@ -280,7 +282,7 @@ public class TypeCheckerFunctionDefinitionTests {
Map.entry("y", Types.STRING)
));
- var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
+ var typed = typeCheckNamespaceStatement(untyped, context);
assertThat(
typed.value(),
@@ -304,7 +306,7 @@ public class TypeCheckerFunctionDefinitionTests {
Map.entry("Unit", Types.metaType(Types.UNIT))
));
- var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
+ var typed = typeCheckNamespaceStatement(untyped, context);
assertThat(
typed.value(),
@@ -312,4 +314,15 @@ public class TypeCheckerFunctionDefinitionTests {
.withFreeVariables(containsExactly())
);
}
+
+ private static TypeCheckerResult<? extends TypedNamespaceStatementNode> typeCheckNamespaceStatement(
+ UntypedFunctionDefinitionNode untyped,
+ TypeCheckerContext context
+ ) {
+ var environment = TypeChecker.declareVariables(untyped, EnvironmentBuilder.EMPTY);
+
+ context = context.enterNamespace(environment.build());
+
+ return TypeChecker.typeCheckNamespaceStatement(untyped, context);
+ }
}
diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerValTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerValTests.java
index 11a66f12..44abec8b 100644
--- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerValTests.java
+++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerValTests.java
@@ -1,9 +1,9 @@
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.ast.typed.TypedFunctionStatementNode;
+import org.shedlang.compiler.ast.typed.TypedNamespaceStatementNode;
+import org.shedlang.compiler.ast.untyped.*;
import org.shedlang.compiler.typechecker.errors.DuplicateVariableName;
import org.shedlang.compiler.typechecker.errors.ReferenceBeforeDefinitionError;
import org.shedlang.compiler.types.Types;
@@ -21,7 +21,7 @@ public class TypeCheckerValTests {
public void canTypeCheckAsFunctionStatement() {
var untyped = Untyped.val(Untyped.targetVariable("x"), Untyped.stringLiteral("hello"));
- var typed = TypeChecker.typeCheckFunctionStatement(untyped, TypeCheckerContext.EMPTY);
+ var typed = typeCheckFunctionStatement(untyped, TypeCheckerContext.EMPTY);
assertThat(typed.value(), isTypedValNode(
isTypedTargetVariable("x"),
@@ -33,7 +33,7 @@ public class TypeCheckerValTests {
public void canTypeCheckAsNamespaceStatement() {
var untyped = Untyped.val(Untyped.targetVariable("x"), Untyped.stringLiteral("hello"));
- var typed = TypeChecker.typeCheckNamespaceStatement(untyped, TypeCheckerContext.EMPTY);
+ var typed = typeCheckNamespaceStatement(untyped, TypeCheckerContext.EMPTY);
assertThat(typed.value(), isTypedValNode(
isTypedTargetVariable("x"),
@@ -52,7 +52,7 @@ public class TypeCheckerValTests {
Map.entry("Unit", Types.metaType(Types.UNIT))
));
- var typed = TypeChecker.typeCheckNamespaceStatement(untyped, context);
+ var typed = typeCheckNamespaceStatement(untyped, context);
assertThat(
typed.value(),
@@ -100,7 +100,7 @@ public class TypeCheckerValTests {
var error = assertThrows(
ReferenceBeforeDefinitionError.class,
- () -> TypeChecker.typeCheckNamespaceStatement(untyped, context)
+ () -> typeCheckNamespaceStatement(untyped, context)
);
assertThat(error.variableName(), equalTo("x"));
@@ -120,7 +120,7 @@ public class TypeCheckerValTests {
var error = assertThrows(
ReferenceBeforeDefinitionError.class,
- () -> TypeChecker.typeCheckNamespaceStatement(untyped, context)
+ () -> typeCheckNamespaceStatement(untyped, context)
);
assertThat(error.variableName(), equalTo("x"));
@@ -139,9 +139,31 @@ public class TypeCheckerValTests {
var error = assertThrows(
DuplicateVariableName.class,
- () -> TypeChecker.typeCheckNamespaceStatement(untyped, context)
+ () -> typeCheckNamespaceStatement(untyped, context)
);
assertThat(error.variableName(), equalTo("x"));
}
+
+ private static TypeCheckerResult<? extends TypedFunctionStatementNode> typeCheckFunctionStatement(
+ UntypedFunctionStatementNode untyped,
+ TypeCheckerContext context
+ ) {
+ var environment = TypeChecker.declareVariables(untyped, EnvironmentBuilder.EMPTY);
+
+ context = context.enterNamespace(environment.build());
+
+ return TypeChecker.typeCheckFunctionStatement(untyped, context);
+ }
+
+ private static TypeCheckerResult<? extends TypedNamespaceStatementNode> typeCheckNamespaceStatement(
+ UntypedNamespaceStatementNode untyped,
+ TypeCheckerContext context
+ ) {
+ var environment = TypeChecker.declareVariables(untyped, EnvironmentBuilder.EMPTY);
+
+ context = context.enterNamespace(environment.build());
+
+ return TypeChecker.typeCheckNamespaceStatement(untyped, context);
+ }
}