diff options
3 files changed, 77 insertions, 2 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 a12677e..2d496e5 100644 --- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java @@ -393,14 +393,21 @@ public class TypeChecker { TypeCheckerNamespaceContext context ) { var typedReceiver = typeCheckTypeLevelExpression(untyped.receiver(), context); + // TODO: check this properly var receiver = (TypeConstructor<SimpleNativeType>) typedReceiver.value(); + if (untyped.args().size() != receiver.params().size()) { + throw new WrongNumberOfTypeLevelArgsError( + receiver.params().size(), + untyped.args().size(), + untyped.source() + ); + } + var args = untyped.args().stream() .map(untypedArg -> typeCheckMetaType(untypedArg, context).value()) .toList(); - // TODO: check number of args - var constructedType = new ConstructedNativeType(receiver, args); return new TypedConstructedTypeNode( diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/errors/WrongNumberOfTypeLevelArgsError.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/errors/WrongNumberOfTypeLevelArgsError.java new file mode 100644 index 0000000..86f57f2 --- /dev/null +++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/errors/WrongNumberOfTypeLevelArgsError.java @@ -0,0 +1,23 @@ +package org.zwobble.hobgoblin.compiler.typechecker.errors; + +import org.zwobble.hobgoblin.compiler.errors.SourceError; +import org.zwobble.hobgoblin.compiler.sources.Source; + +public class WrongNumberOfTypeLevelArgsError extends SourceError { + private final int expectedArgCount; + private final int actualArgCount; + + public WrongNumberOfTypeLevelArgsError(int expectedArgCount, int actualArgCount, Source source) { + super("expected " + expectedArgCount + " type-level args, but got " + actualArgCount, source); + this.expectedArgCount = expectedArgCount; + this.actualArgCount = actualArgCount; + } + + public int expectedArgCount() { + return expectedArgCount; + } + + public int actualArgCount() { + return actualArgCount; + } +} diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerConstructedTypeTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerConstructedTypeTests.java index fa511ba..09c0f8c 100644 --- a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerConstructedTypeTests.java +++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerConstructedTypeTests.java @@ -3,10 +3,12 @@ package org.zwobble.hobgoblin.compiler.typechecker; import org.junit.jupiter.api.Test; import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedArb; import org.zwobble.hobgoblin.compiler.sources.NullSource; +import org.zwobble.hobgoblin.compiler.typechecker.errors.WrongNumberOfTypeLevelArgsError; import org.zwobble.hobgoblin.compiler.types.*; import java.util.List; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.zwobble.hobgoblin.compiler.ast.typed.TypedNodeMatchers.isTypedConstructedTypeNode; import static org.zwobble.precisely.AssertThat.assertThat; import static org.zwobble.precisely.Matchers.equalTo; @@ -31,4 +33,47 @@ public class TypeCheckerConstructedTypeTests { equalTo(new ConstructedNativeType(listTypeConstructor, List.of(int32Type))) )); } + + @Test + public void whenThereAreTooFewArgsThenErrorIsThrown() { + var untyped = UntypedArb.constructedType( + UntypedArb.typeLevelReference("List"), + List.of() + ); + var context = TypeCheckerContextArb.namespaceContext(); + var listType = SimpleNativeType.builtin("List"); + var listTypeConstructor = new TypeConstructor<>(List.of(new TypeParam("T")), listType); + context.declare("List", new TypeLevelValueType(listTypeConstructor), NullSource.INSTANCE); + + var error = assertThrows( + WrongNumberOfTypeLevelArgsError.class, + () -> TypeChecker.typeCheckTypeLevelExpression(untyped, context) + ); + + assertThat(error.expectedArgCount(), equalTo(1)); + assertThat(error.actualArgCount(), equalTo(0)); + } + + @Test + public void whenThereAreTooManyArgsThenErrorIsThrown() { + var untyped = UntypedArb.constructedType( + UntypedArb.typeLevelReference("List"), + List.of( + UntypedArb.typeLevelReference("Int32"), + UntypedArb.typeLevelReference("Int64") + ) + ); + var context = TypeCheckerContextArb.namespaceContext(); + var listType = SimpleNativeType.builtin("List"); + var listTypeConstructor = new TypeConstructor<>(List.of(new TypeParam("T")), listType); + context.declare("List", new TypeLevelValueType(listTypeConstructor), NullSource.INSTANCE); + + var error = assertThrows( + WrongNumberOfTypeLevelArgsError.class, + () -> TypeChecker.typeCheckTypeLevelExpression(untyped, context) + ); + + assertThat(error.expectedArgCount(), equalTo(1)); + assertThat(error.actualArgCount(), equalTo(2)); + } } |
