From b1ca0653b7bd80302a287faef3a7c7647f92d23a Mon Sep 17 00:00:00 2001 From: Michael Williamson Date: Thu, 28 Sep 2023 11:57:36 +0100 Subject: Define struct type info earlier --- .../compiler/ast/typed/TypedNodeMatchers.java | 9 ++++++ .../typechecker/TypeCheckerNamespaceTests.java | 35 +++++++++++++++++++++- 2 files changed, 43 insertions(+), 1 deletion(-) (limited to 'src/test/java') diff --git a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java index a21e3375..7bd1402d 100644 --- a/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java +++ b/src/test/java/org/shedlang/compiler/ast/typed/TypedNodeMatchers.java @@ -83,6 +83,15 @@ public class TypedNodeMatchers { ); } + public static Matcher isTypedExpressionNode( + Type type + ) { + return instanceOf( + TypedExpressionNode.class, + has("type", x -> x.type(), equalTo(type)) + ); + } + public static Matcher isTypedExpressionStatementNode( Matcher expression ) { diff --git a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerNamespaceTests.java b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerNamespaceTests.java index 5a081076..226769bf 100644 --- a/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerNamespaceTests.java +++ b/src/test/java/org/shedlang/compiler/typechecker/TypeCheckerNamespaceTests.java @@ -324,7 +324,7 @@ public class TypeCheckerNamespaceTests { } @Test - public void functionCanUseTypeDefinedLater() { + public void functionSignatureCanUseTypeDefinedLater() { var untyped = Untyped.namespace(NamespaceName.of("Example", "Project"), List.of( UntypedFunctionDefinitionNode.builder() .withName("printUser") @@ -361,6 +361,39 @@ public class TypeCheckerNamespaceTests { ); } + @Test + public void functionBodyCanAccessFieldOnTypeDefinedLater() { + var untyped = Untyped.namespace(NamespaceName.of("Example", "Project"), List.of( + UntypedFunctionDefinitionNode.builder() + .withName("printUser") + .addPositionalParam("user", Untyped.typeLevelReference("User")) + .withReturnType(Untyped.typeLevelReference("Unit")) + .addStatement(Untyped.expressionStatement(Untyped.fieldAccess(Untyped.reference("user"), "name"))) + .build(), + UntypedStructDefinitionNode.builder() + .withName("User") + .addField(Untyped.structFieldDefinition("name", Untyped.typeLevelReference("String"))) + .build() + )); + var context = TypeCheckerContext.EMPTY + .enterGlobal(P.map(Map.entry("String", Types.metaType(Types.STRING)))) + .enterGlobal(P.map(Map.entry("Unit", Types.metaType(Types.UNIT)))); + + var result = TypeChecker.typeCheckNamespace(untyped, context); + + assertThat( + result.value(), + isTypedNamespaceNode() + .withBody(isSequence( + isTypedFunctionDefinitionNode() + .withBody(isTypedBlockNode(isSequence( + isTypedExpressionStatementNode(isTypedExpressionNode(Types.STRING)) + ))), + isTypedStructDefinitionNode() + )) + ); + } + @Test public void structsCanHaveMutuallyRecursiveFields() { var namespaceName = NamespaceName.of("Example", "Project"); -- cgit v1.2.3