From 365d53ad8a7bf21602e37970a34b2de116a794b2 Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Tue, 16 Jun 2026 21:28:42 +0100 Subject: Type check imports --- .../compiler/typechecker/TypeChecker.java | 11 ++++ .../typechecker/TypeCheckerNamespaceTests.java | 58 ++++++++++++++++++++-- 2 files changed, 65 insertions(+), 4 deletions(-) (limited to 'src') 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 4b718a2..77b46bc 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java @@ -19,6 +19,17 @@ public class TypeChecker { ) { var namespaceContext = context.enterNamespace(untyped.namespaceName()); + for (var untypedImport : untyped.imports()) { + if (untypedImport.ancestorDepth().isPresent()) { + throw new UnsupportedOperationException("TODO: relative imports"); + } + + var importedNamespaceFields = context.namespaceFields(untypedImport.namespaceName()); + for (var importedName : untypedImport.importedNames()) { + namespaceContext.define(importedName, importedNamespaceFields.get(importedName)); + } + } + var fields = new ArrayList(); for (var untypedStatement : untyped.body()) { var type = declareNamespaceStatement(untypedStatement, namespaceContext); 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 cfe52c3..c4b31b8 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceTests.java @@ -3,12 +3,11 @@ package org.zwobble.hobgoblin.compiler.typechecker; import org.junit.jupiter.api.Test; import org.zwobble.hobgoblin.compiler.ast.typed.TypedNamespaceNode; import org.zwobble.hobgoblin.compiler.ast.typed.TypedStructDefinitionNode; -import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedNamespaceNode; -import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedStructDefinitionNode; -import org.zwobble.hobgoblin.compiler.types.NamespaceName; -import org.zwobble.hobgoblin.compiler.types.StructType; +import org.zwobble.hobgoblin.compiler.ast.untyped.*; +import org.zwobble.hobgoblin.compiler.types.*; import java.util.List; +import java.util.Optional; import static org.zwobble.hobgoblin.compiler.types.TypeMatchers.isMetaType; import static org.zwobble.precisely.AssertThat.assertThat; @@ -47,4 +46,55 @@ public class TypeCheckerNamespaceTests { isMetaType(new StructType(NamespaceName.of("a", "b"), "X")) ); } + + @Test + public void importsAreTypeChecked() { + var untyped = UntypedNamespaceNode.arbitrary() + .withNamespaceName(NamespaceName.of("a", "b")) + .withImports(List.of( + UntypedImportNode.arbitrary() + .withAncestorDepth(Optional.empty()) + .withNamespaceName(NamespaceName.of("a", "c")) + .withImportedNames(List.of("Y")) + .build() + )) + .withBody(List.of( + UntypedStructDefinitionNode.arbitrary() + .withName("X") + .withFields(List.of( + UntypedStructFieldDefinitionNode.arbitrary() + .withName("y") + .withType(UntypedTypeLevelReferenceNode.arbitrary().withName("Y").build()) + .build() + )) + .build() + )) + .build(); + var context = TypeCheckerContextArb.globalContext(); + context.defineNamespace(NamespaceName.of("a", "c"), List.of( + new Field("Y", new TypeLevelValueType(new SimpleNativeType(NamespaceName.of("a", "c"), "Y")) + ))); + + var typed = TypeChecker.typeCheckNamespace(untyped, context); + + assertThat(typed, instanceOf( + TypedNamespaceNode.class, + has("body", TypedNamespaceNode::body, isSequence( + instanceOf( + TypedStructDefinitionNode.class, + has( + "type", + TypedStructDefinitionNode::type, + equalTo(new StructType(NamespaceName.of("a", "b"), "X")) + ) + ) + )) + )); + assertThat( + context.toTypesInfo().fieldsOf(new StructType(NamespaceName.of("a", "b"), "X")), + isSequence( + equalTo(new Field("y", new SimpleNativeType(NamespaceName.of("a", "c"), "Y"))) + ) + ); + } } -- cgit v1.2.3