summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java4
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerGlobalContext.java5
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/UnknownNamespaceError.java7
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceTests.java23
4 files changed, 34 insertions, 5 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
index 78bdc97..384ef19 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
@@ -29,7 +29,9 @@ public class TypeChecker {
untypedImport.source()
);
- var importedNamespaceFields = context.namespaceFields(importedNamespace);
+ var importedNamespaceFields = context.namespaceFields(importedNamespace)
+ .orElseThrow(() -> new UnknownNamespaceError(importedNamespace, untypedImport.source()));
+
for (var importedName : untypedImport.importedNames()) {
var fieldType = importedNamespaceFields.fieldType(importedName)
.orElseThrow(() -> new UnknownNamespaceFieldError(
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerGlobalContext.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerGlobalContext.java
index e50e424..ff6cd5e 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerGlobalContext.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerGlobalContext.java
@@ -43,8 +43,7 @@ public class TypeCheckerGlobalContext {
this.namespaceFieldsOf.put(namespaceName, new Fields(fields));
}
- public Fields namespaceFields(NamespaceName namespaceName) {
- // TODO: better error handling
- return Optional.ofNullable(namespaceFieldsOf.get(namespaceName)).orElseThrow();
+ public Optional<Fields> namespaceFields(NamespaceName namespaceName) {
+ return Optional.ofNullable(namespaceFieldsOf.get(namespaceName));
}
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/UnknownNamespaceError.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/UnknownNamespaceError.java
index fb06f3b..1ca4ac7 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/UnknownNamespaceError.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/UnknownNamespaceError.java
@@ -5,7 +5,14 @@ import org.zwobble.hobgoblin.compiler.sources.Source;
import org.zwobble.hobgoblin.compiler.types.NamespaceName;
public class UnknownNamespaceError extends SourceError {
+ private final NamespaceName namespaceName;
+
public UnknownNamespaceError(NamespaceName namespaceName, Source source) {
super("Unknown namespace: " + namespaceName, source);
+ this.namespaceName = namespaceName;
+ }
+
+ public NamespaceName namespaceName() {
+ return namespaceName;
}
}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceTests.java
index 3559578..82cccf3 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceTests.java
@@ -43,7 +43,7 @@ public class TypeCheckerNamespaceTests {
))
));
assertThat(
- context.namespaceFields(NamespaceName.of("a", "b")).fieldType("X").orElseThrow(),
+ context.namespaceFields(NamespaceName.of("a", "b")).orElseThrow().fieldType("X").orElseThrow(),
isMetaType(new StructType(NamespaceName.of("a", "b"), "X"))
);
}
@@ -100,6 +100,27 @@ public class TypeCheckerNamespaceTests {
}
@Test
+ public void whenNamespaceIsUnknownThenErrorIsThrown() {
+ var untyped = UntypedNamespaceNode.arbitrary()
+ .withImports(List.of(
+ UntypedImportNode.arbitrary()
+ .withAncestorDepth(Optional.empty())
+ .withNamespaceName(NamespaceName.of("a"))
+ .withImportedNames(List.of("A"))
+ .build()
+ ))
+ .build();
+ var context = TypeCheckerContextArb.globalContext();
+
+ var error = assertThrows(
+ UnknownNamespaceError.class,
+ () -> TypeChecker.typeCheckNamespace(untyped, context)
+ );
+
+ assertThat(error.namespaceName(), equalTo(NamespaceName.of("a")));
+ }
+
+ @Test
public void whenNamespaceHasNoSuchFieldThenErrorIsThrown() {
var untyped = UntypedNamespaceNode.arbitrary()
.withImports(List.of(