summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java3
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/NamespaceNameResolution.java9
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/RootNamespaceHasNoParentError.java10
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java3
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/typechecker/NamespaceNameResolutionTests.java37
5 files changed, 55 insertions, 7 deletions
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java b/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java
index 9dba876..f4c3add 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/HobgoblinCompiler.java
@@ -84,7 +84,8 @@ public class HobgoblinCompiler {
var importedNamespaceName = resolveNamespaceName(
namespaceNode.namespaceName(),
importNode.ancestorDepth(),
- importNode.namespaceName()
+ importNode.namespaceName(),
+ importNode.source()
);
if (!handledNamespaceNames.contains(importedNamespaceName)) {
unhandledDependencies.add(
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/NamespaceNameResolution.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/NamespaceNameResolution.java
index 28b709f..ec6187d 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/NamespaceNameResolution.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/NamespaceNameResolution.java
@@ -1,5 +1,6 @@
package org.zwobble.hobgoblin.compiler.typechecker;
+import org.zwobble.hobgoblin.compiler.sources.Source;
import org.zwobble.hobgoblin.compiler.types.NamespaceName;
import java.util.ArrayList;
@@ -11,13 +12,17 @@ public class NamespaceNameResolution {
public static NamespaceName resolveNamespaceName(
NamespaceName current,
Optional<Integer> importedAncestorDepth,
- NamespaceName importedNamespaceName
+ NamespaceName importedNamespaceName,
+ Source source
) {
if (importedAncestorDepth.isEmpty()) {
return importedNamespaceName;
}
- // TODO: handle invalid depth (too large).
+ if (importedAncestorDepth.get() > current.parts().size()) {
+ throw new RootNamespaceHasNoParentError(source);
+ }
+
// TODO: should always skip right-most part? For instance, within src/line.hob, does ./point reference src/point.hob or src/line/point.hob?
var parts = new ArrayList<>(current.parts().subList(0, current.parts().size() - importedAncestorDepth.get()));
parts.addAll(importedNamespaceName.parts());
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/RootNamespaceHasNoParentError.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/RootNamespaceHasNoParentError.java
new file mode 100644
index 0000000..f688274
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/RootNamespaceHasNoParentError.java
@@ -0,0 +1,10 @@
+package org.zwobble.hobgoblin.compiler.typechecker;
+
+import org.zwobble.hobgoblin.compiler.errors.SourceError;
+import org.zwobble.hobgoblin.compiler.sources.Source;
+
+public class RootNamespaceHasNoParentError extends SourceError {
+ public RootNamespaceHasNoParentError(Source source) {
+ super("Root namespace has no parent", source);
+ }
+}
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 abc4bec..e9e7e74 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
@@ -25,7 +25,8 @@ public class TypeChecker {
var importedNamespace = resolveNamespaceName(
untyped.namespaceName(),
untypedImport.ancestorDepth(),
- untypedImport.namespaceName()
+ untypedImport.namespaceName(),
+ untypedImport.source()
);
var importedNamespaceFields = context.namespaceFields(importedNamespace);
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/NamespaceNameResolutionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/NamespaceNameResolutionTests.java
index 7929e7d..da0eb90 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/NamespaceNameResolutionTests.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/NamespaceNameResolutionTests.java
@@ -1,10 +1,12 @@
package org.zwobble.hobgoblin.compiler.typechecker;
import org.junit.jupiter.api.Test;
+import org.zwobble.hobgoblin.compiler.sources.NullSource;
import org.zwobble.hobgoblin.compiler.types.NamespaceName;
import java.util.Optional;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.zwobble.hobgoblin.compiler.typechecker.NamespaceNameResolution.resolveNamespaceName;
import static org.zwobble.precisely.AssertThat.assertThat;
import static org.zwobble.precisely.Matchers.equalTo;
@@ -16,7 +18,12 @@ public class NamespaceNameResolutionTests {
var importedAncestorDepth = Optional.<Integer>empty();
var importedNamespaceName = NamespaceName.of("x", "y");
- var result = resolveNamespaceName(current, importedAncestorDepth, importedNamespaceName);
+ var result = resolveNamespaceName(
+ current,
+ importedAncestorDepth,
+ importedNamespaceName,
+ NullSource.INSTANCE
+ );
assertThat(result, equalTo(NamespaceName.of("x", "y")));
}
@@ -27,7 +34,12 @@ public class NamespaceNameResolutionTests {
var importedAncestorDepth = Optional.of(0);
var importedNamespaceName = NamespaceName.of("x", "y");
- var result = resolveNamespaceName(current, importedAncestorDepth, importedNamespaceName);
+ var result = resolveNamespaceName(
+ current,
+ importedAncestorDepth,
+ importedNamespaceName,
+ NullSource.INSTANCE
+ );
assertThat(result, equalTo(NamespaceName.of("a", "b", "x", "y")));
}
@@ -38,8 +50,27 @@ public class NamespaceNameResolutionTests {
var importedAncestorDepth = Optional.of(2);
var importedNamespaceName = NamespaceName.of("x", "y");
- var result = resolveNamespaceName(current, importedAncestorDepth, importedNamespaceName);
+ var result = resolveNamespaceName(
+ current,
+ importedAncestorDepth,
+ importedNamespaceName,
+ NullSource.INSTANCE
+ );
assertThat(result, equalTo(NamespaceName.of("a", "x", "y")));
}
+
+ @Test
+ public void whenAncestorDepthIsGreaterThanPartsThenErrorIsThrown() {
+ var current = NamespaceName.of("a", "b", "c");
+ var importedAncestorDepth = Optional.of(4);
+ var importedNamespaceName = NamespaceName.of("x", "y");
+
+ assertThrows(RootNamespaceHasNoParentError.class, () -> resolveNamespaceName(
+ current,
+ importedAncestorDepth,
+ importedNamespaceName,
+ NullSource.INSTANCE
+ ));
+ }
}