summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hobgoblin/src/ast/typed.hob20
-rw-r--r--hobgoblin/src/types.hob3
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedDatabaseSchemaDefinitionNode.java28
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedDatabaseSchemaStatementNode.java18
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNode.java56
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java37
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/ConstructedStructType.java2
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/HobgoblinNativeTypes.java4
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/SimpleStructType.java2
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/StructType.java4
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java2
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedDatabaseSchemaDefinitionNodeMatcher.java6
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNodeMatcher.java65
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerDatabaseSchemaDefinitionTests.java49
-rw-r--r--src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTableDefinitionTests.java38
15 files changed, 322 insertions, 12 deletions
diff --git a/hobgoblin/src/ast/typed.hob b/hobgoblin/src/ast/typed.hob
index 5581940..b65ecdd 100644
--- a/hobgoblin/src/ast/typed.hob
+++ b/hobgoblin/src/ast/typed.hob
@@ -5,17 +5,22 @@ import {
NamespaceName,
SimpleNativeType,
SimpleStructType,
+ StructType,
SumType,
Type,
TypeOrConstructor,
} from types;
+// == Namespaces ==
+
struct TypedNamespaceNode {
field namespaceName: NamespaceName;
field body: List[TypedNamespaceStatementNode];
field source: Source;
}
+// == Namespace statements ==
+
sum TypedNamespaceStatementNode {
variant TypedDatabaseSchemaDefinitionNode;
variant TypedEnumDefinitionNode;
@@ -26,6 +31,7 @@ sum TypedNamespaceStatementNode {
struct TypedDatabaseSchemaDefinitionNode {
field name: String;
+ field body: List[TypedDatabaseSchemaStatementNode];
field docComment: DocComment;
field source: Source;
}
@@ -73,3 +79,17 @@ struct TypedSumVariantDefinitionNode {
field type: Type;
field source: Source;
}
+
+// == Database schema statements ==
+
+sum TypedDatabaseSchemaStatementNode {
+ variant TypedTableDefinitionNode;
+}
+
+struct TypedTableDefinitionNode {
+ field name: String;
+ field rowType: StructType;
+ field primaryKey: String;
+ field docComment: DocComment;
+ field source: Source;
+}
diff --git a/hobgoblin/src/types.hob b/hobgoblin/src/types.hob
index 4e3a971..5e96164 100644
--- a/hobgoblin/src/types.hob
+++ b/hobgoblin/src/types.hob
@@ -13,6 +13,9 @@ native SimpleNativeType {
native SimpleStructType {
}
+native StructType {
+}
+
native SumType {
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedDatabaseSchemaDefinitionNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedDatabaseSchemaDefinitionNode.java
index 2b9f394..9b0edd9 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedDatabaseSchemaDefinitionNode.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedDatabaseSchemaDefinitionNode.java
@@ -7,32 +7,50 @@ package org.zwobble.hobgoblin.compiler.ast.typed;
public record TypedDatabaseSchemaDefinitionNode(
String name,
+ java.util.List<org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode> body,
org.zwobble.hobgoblin.compiler.ast.DocComment docComment,
org.zwobble.hobgoblin.compiler.sources.Source source
) implements org.zwobble.hobgoblin.compiler.ast.typed.TypedNamespaceStatementNode {
public static org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder arbitrary() {
- return new org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder("", org.zwobble.hobgoblin.compiler.ast.HobgoblinNativeAst.arbitraryDocComment(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource());
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder("", java.util.List.of(), org.zwobble.hobgoblin.compiler.ast.HobgoblinNativeAst.arbitraryDocComment(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource());
}
public record Builder(
String name,
+ java.util.List<org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode> body,
org.zwobble.hobgoblin.compiler.ast.DocComment docComment,
org.zwobble.hobgoblin.compiler.sources.Source source
) implements org.zwobble.hobgoblin.compiler.ast.typed.TypedNamespaceStatementNode.Builder {
public org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode build() {
- return new org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode(name, docComment, source);
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode(name, body, docComment, source);
}
public org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder withName(String name) {
- return new org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder(name, docComment, source);
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder(name, body, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder withBody(java.util.List<org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode> body) {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder(name, body, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder addBodyElement(org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode bodyElement) {
+ var body = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode>(this.body);
+ body.add(bodyElement);
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder(name, body, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder addBodyElement(org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode.Builder bodyElement) {
+ var body = new java.util.ArrayList<org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode>(this.body);
+ body.add(bodyElement.build());
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder(name, body, docComment, source);
}
public org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder withDocComment(org.zwobble.hobgoblin.compiler.ast.DocComment docComment) {
- return new org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder(name, docComment, source);
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder(name, body, docComment, source);
}
public org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder withSource(org.zwobble.hobgoblin.compiler.sources.Source source) {
- return new org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder(name, docComment, source);
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder(name, body, docComment, source);
}
// Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode.Builder body
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedDatabaseSchemaStatementNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedDatabaseSchemaStatementNode.java
new file mode 100644
index 0000000..4c11011
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedDatabaseSchemaStatementNode.java
@@ -0,0 +1,18 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.typed;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode imports
+
+public sealed interface TypedDatabaseSchemaStatementNode permits org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode {
+ public interface Builder {
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode build();
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode body
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNode.java b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNode.java
new file mode 100644
index 0000000..315aeef
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNode.java
@@ -0,0 +1,56 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.typed;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode imports
+
+public record TypedTableDefinitionNode(
+ String name,
+ org.zwobble.hobgoblin.compiler.types.StructType rowType,
+ String primaryKey,
+ org.zwobble.hobgoblin.compiler.ast.DocComment docComment,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+) implements org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode {
+ public static org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder arbitrary() {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder("", org.zwobble.hobgoblin.compiler.types.HobgoblinNativeTypes.arbitraryStructType(), "", org.zwobble.hobgoblin.compiler.ast.HobgoblinNativeAst.arbitraryDocComment(), org.zwobble.hobgoblin.compiler.sources.HobgoblinNativeSources.arbitrarySource());
+ }
+
+ public record Builder(
+ String name,
+ org.zwobble.hobgoblin.compiler.types.StructType rowType,
+ String primaryKey,
+ org.zwobble.hobgoblin.compiler.ast.DocComment docComment,
+ org.zwobble.hobgoblin.compiler.sources.Source source
+ ) implements org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode.Builder {
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode build() {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode(name, rowType, primaryKey, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder withName(String name) {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder(name, rowType, primaryKey, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder withRowType(org.zwobble.hobgoblin.compiler.types.StructType rowType) {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder(name, rowType, primaryKey, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder withPrimaryKey(String primaryKey) {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder(name, rowType, primaryKey, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder withDocComment(org.zwobble.hobgoblin.compiler.ast.DocComment docComment) {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder(name, rowType, primaryKey, docComment, source);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder withSource(org.zwobble.hobgoblin.compiler.sources.Source source) {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder(name, rowType, primaryKey, docComment, source);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.Builder body
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode body
+}
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 8178d8d..3022814 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
@@ -115,11 +115,11 @@ public class TypeChecker {
TypeCheckerNamespaceContext context
) {
return switch (untyped) {
- case UntypedDatabaseSchemaDefinitionNode untypedDatabaseSchemaDefinitionNode ->
- defineDatabaseSchemaDefinition(untypedDatabaseSchemaDefinitionNode, context);
+ case UntypedDatabaseSchemaDefinitionNode untypedDatabaseSchemaDefinition ->
+ defineDatabaseSchemaDefinition(untypedDatabaseSchemaDefinition, context);
- case UntypedEnumDefinitionNode untypedEnumDefinitionNode ->
- defineEnumDefinition(untypedEnumDefinitionNode, context);
+ case UntypedEnumDefinitionNode untypedEnumDefinition ->
+ defineEnumDefinition(untypedEnumDefinition, context);
case UntypedNativeTypeDefinitionNode untypedNativeTypeDefinition ->
defineNativeTypeDefinition(untypedNativeTypeDefinition, context);
@@ -138,6 +138,9 @@ public class TypeChecker {
) {
return new TypedDatabaseSchemaDefinitionNode(
untyped.name(),
+ untyped.body().stream()
+ .map(statement -> typeCheckDatabaseSchemaStatement(statement, context))
+ .toList(),
untyped.docComment(),
untyped.source()
);
@@ -451,6 +454,32 @@ public class TypeChecker {
}
}
+ static TypedDatabaseSchemaStatementNode typeCheckDatabaseSchemaStatement(
+ UntypedDatabaseSchemaStatementNode statement,
+ TypeCheckerNamespaceContext context
+ ) {
+ return switch (statement) {
+ case UntypedTableDefinitionNode untypedTableDefinition ->
+ typeCheckTableDefinition(untypedTableDefinition, context);
+ };
+ }
+
+ private static TypedTableDefinitionNode typeCheckTableDefinition(
+ UntypedTableDefinitionNode untyped,
+ TypeCheckerNamespaceContext context
+ ) {
+ var rowType = typeCheckMetaType(untyped.rowType(), context);
+
+ return new TypedTableDefinitionNode(
+ untyped.name(),
+ // TODO: handle not struct type.
+ (StructType) rowType.value(),
+ untyped.primaryKey(),
+ untyped.docComment(),
+ untyped.source()
+ );
+ }
+
static TypedTypeLevelExpressionNode<? extends TypeLevelValue> typeCheckTypeLevelExpression(
UntypedTypeLevelExpressionNode untyped,
TypeCheckerNamespaceContext context
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/ConstructedStructType.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/ConstructedStructType.java
index a95e07f..87f6e7c 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/types/ConstructedStructType.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/ConstructedStructType.java
@@ -5,5 +5,5 @@ import java.util.List;
public record ConstructedStructType(
TypeConstructor<SimpleStructType> constructor,
List<Type> args
-) implements ConstructedType, Type {
+) implements ConstructedType, Type, StructType {
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/HobgoblinNativeTypes.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/HobgoblinNativeTypes.java
index 14294f9..37e6935 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/types/HobgoblinNativeTypes.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/HobgoblinNativeTypes.java
@@ -23,6 +23,10 @@ public class HobgoblinNativeTypes {
return new SimpleStructType(arbitraryNamespaceName(), "");
}
+ public static SimpleStructType arbitraryStructType() {
+ return arbitrarySimpleStructType();
+ }
+
public static SumType arbitrarySumType() {
return new SumType(arbitraryNamespaceName(), "");
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/SimpleStructType.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/SimpleStructType.java
index a67eeb0..2f5e37b 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/types/SimpleStructType.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/SimpleStructType.java
@@ -1,6 +1,6 @@
package org.zwobble.hobgoblin.compiler.types;
-public record SimpleStructType(NamespaceName namespaceName, String name) implements Type, SimpleType, ConstructibleType {
+public record SimpleStructType(NamespaceName namespaceName, String name) implements Type, SimpleType, ConstructibleType, StructType {
@Override
public String describe() {
return namespaceName.toString() + "." + name;
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/StructType.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/StructType.java
new file mode 100644
index 0000000..0f65574
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/StructType.java
@@ -0,0 +1,4 @@
+package org.zwobble.hobgoblin.compiler.types;
+
+public sealed interface StructType extends Type permits ConstructedStructType, SimpleStructType {
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java
index 57b85cd..ed03bc0 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/Type.java
@@ -1,5 +1,5 @@
package org.zwobble.hobgoblin.compiler.types;
-public sealed interface Type extends TypeLevelValue permits ConstructedNativeType, ConstructedStructType, ConstructedType, ConstructibleType, EnumType, SimpleNativeType, SimpleType, SimpleStructType, SumType, TypeLevelValueType, TypeParam {
+public sealed interface Type extends TypeLevelValue permits ConstructedNativeType, ConstructedStructType, ConstructedType, ConstructibleType, EnumType, SimpleNativeType, SimpleStructType, SimpleType, StructType, SumType, TypeLevelValueType, TypeParam {
String name();
}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedDatabaseSchemaDefinitionNodeMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedDatabaseSchemaDefinitionNodeMatcher.java
index 107873f..8c23065 100644
--- a/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedDatabaseSchemaDefinitionNodeMatcher.java
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedDatabaseSchemaDefinitionNodeMatcher.java
@@ -36,6 +36,12 @@ public final class TypedDatabaseSchemaDefinitionNodeMatcher implements org.zwobb
return new org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNodeMatcher(submatchers);
}
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNodeMatcher withBody(org.zwobble.precisely.Matcher<? super java.util.List<org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaStatementNode>> body) {
+ var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode>>(this.submatchers);
+ submatchers.add(org.zwobble.precisely.Matchers.has("body", org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode::body, (org.zwobble.precisely.Matcher) body));
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNodeMatcher(submatchers);
+ }
+
public org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNodeMatcher withDocComment(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.DocComment> docComment) {
var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode>>(this.submatchers);
submatchers.add(org.zwobble.precisely.Matchers.has("docComment", org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNode::docComment, (org.zwobble.precisely.Matcher) docComment));
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNodeMatcher.java b/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNodeMatcher.java
new file mode 100644
index 0000000..18b827b
--- /dev/null
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/ast/typed/TypedTableDefinitionNodeMatcher.java
@@ -0,0 +1,65 @@
+// Generated by hobgoblin.
+
+package org.zwobble.hobgoblin.compiler.ast.typed;
+
+// Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher imports
+// Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher imports
+
+public final class TypedTableDefinitionNodeMatcher implements org.zwobble.precisely.Matcher<java.lang.Object> {
+ public static org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher isTypedTableDefinitionNode() {
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher(java.util.List.of());
+ }
+
+ private final java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode>> submatchers;
+
+ private TypedTableDefinitionNodeMatcher(
+ java.util.List<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode>> submatchers
+ ) {
+ this.submatchers = submatchers;
+ }
+
+ public org.zwobble.precisely.MatchResult match(java.lang.Object actual) {
+ return this.toMatcher().match(actual);
+ }
+
+ public org.zwobble.precisely.TextTree describe() {
+ return this.toMatcher().describe();
+ }
+
+ private org.zwobble.precisely.Matcher<java.lang.Object> toMatcher() {
+ return org.zwobble.precisely.Matchers.instanceOf(org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode.class, this.submatchers);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher withName(org.zwobble.precisely.Matcher<? super String> name) {
+ var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode>>(this.submatchers);
+ submatchers.add(org.zwobble.precisely.Matchers.has("name", org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode::name, (org.zwobble.precisely.Matcher) name));
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher(submatchers);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher withRowType(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.types.StructType> rowType) {
+ var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode>>(this.submatchers);
+ submatchers.add(org.zwobble.precisely.Matchers.has("rowType", org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode::rowType, (org.zwobble.precisely.Matcher) rowType));
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher(submatchers);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher withPrimaryKey(org.zwobble.precisely.Matcher<? super String> primaryKey) {
+ var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode>>(this.submatchers);
+ submatchers.add(org.zwobble.precisely.Matchers.has("primaryKey", org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode::primaryKey, (org.zwobble.precisely.Matcher) primaryKey));
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher(submatchers);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher withDocComment(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.DocComment> docComment) {
+ var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode>>(this.submatchers);
+ submatchers.add(org.zwobble.precisely.Matchers.has("docComment", org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode::docComment, (org.zwobble.precisely.Matcher) docComment));
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher(submatchers);
+ }
+
+ public org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher withSource(org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.sources.Source> source) {
+ var submatchers = new java.util.ArrayList<org.zwobble.precisely.Matcher<? super org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode>>(this.submatchers);
+ submatchers.add(org.zwobble.precisely.Matchers.has("source", org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNode::source, (org.zwobble.precisely.Matcher) source));
+ return new org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher(submatchers);
+ }
+
+ // Custom area start: org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher body
+ // Custom area end: org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher body
+}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerDatabaseSchemaDefinitionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerDatabaseSchemaDefinitionTests.java
new file mode 100644
index 0000000..574bf26
--- /dev/null
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerDatabaseSchemaDefinitionTests.java
@@ -0,0 +1,49 @@
+package org.zwobble.hobgoblin.compiler.typechecker;
+
+import org.junit.jupiter.api.Test;
+import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedDatabaseSchemaDefinitionNode;
+import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode;
+import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTypeLevelReferenceNode;
+import org.zwobble.hobgoblin.compiler.sources.NullSource;
+import org.zwobble.hobgoblin.compiler.types.NamespaceName;
+import org.zwobble.hobgoblin.compiler.types.SimpleStructType;
+import org.zwobble.hobgoblin.compiler.types.Types;
+
+import static org.zwobble.hobgoblin.compiler.ast.typed.TypedDatabaseSchemaDefinitionNodeMatcher.isTypedDatabaseSchemaDefinitionNode;
+import static org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher.isTypedTableDefinitionNode;
+import static org.zwobble.hobgoblin.compiler.typechecker.TypeCheckerTesting.typeCheckNamespaceStatement;
+import static org.zwobble.precisely.AssertThat.assertThat;
+import static org.zwobble.precisely.Matchers.equalTo;
+import static org.zwobble.precisely.Matchers.isSequence;
+
+public class TypeCheckerDatabaseSchemaDefinitionTests {
+ @Test
+ public void databaseSchemaStatementsAreTypeChecked() {
+ var untyped = UntypedDatabaseSchemaDefinitionNode.arbitrary()
+ .withName("blogApp")
+ .addBodyElement(UntypedTableDefinitionNode.arbitrary()
+ .withName("authors")
+ .withRowType(UntypedTypeLevelReferenceNode.arbitrary()
+ .withName("Author")
+ .build()
+ )
+ .build()
+ )
+ .build();
+ var globalContext = TypeCheckerContextArb.globalContext();
+ var namespaceContext = globalContext.enterNamespace(NamespaceName.of("App"));
+ var authorType = new SimpleStructType(NamespaceName.of("App"), "Author");
+ namespaceContext.declare("Author", Types.metaType(authorType), NullSource.INSTANCE);
+
+ var typed = typeCheckNamespaceStatement(untyped, namespaceContext);
+
+ assertThat(typed, isTypedDatabaseSchemaDefinitionNode()
+ .withName(equalTo("blogApp"))
+ .withBody(isSequence(
+ isTypedTableDefinitionNode()
+ .withName(equalTo("authors"))
+ .withRowType(equalTo(authorType))
+ ))
+ );
+ }
+}
diff --git a/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTableDefinitionTests.java b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTableDefinitionTests.java
new file mode 100644
index 0000000..7c08688
--- /dev/null
+++ b/src/test/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerTableDefinitionTests.java
@@ -0,0 +1,38 @@
+package org.zwobble.hobgoblin.compiler.typechecker;
+
+import org.junit.jupiter.api.Test;
+import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTableDefinitionNode;
+import org.zwobble.hobgoblin.compiler.ast.untyped.UntypedTypeLevelReferenceNode;
+import org.zwobble.hobgoblin.compiler.sources.NullSource;
+import org.zwobble.hobgoblin.compiler.types.NamespaceName;
+import org.zwobble.hobgoblin.compiler.types.SimpleStructType;
+import org.zwobble.hobgoblin.compiler.types.Types;
+
+import static org.zwobble.hobgoblin.compiler.ast.typed.TypedTableDefinitionNodeMatcher.isTypedTableDefinitionNode;
+import static org.zwobble.hobgoblin.compiler.typechecker.TypeChecker.typeCheckDatabaseSchemaStatement;
+import static org.zwobble.precisely.AssertThat.assertThat;
+import static org.zwobble.precisely.Matchers.equalTo;
+
+public class TypeCheckerTableDefinitionTests {
+ @Test
+ public void databaseSchemaStatementsAreTypeChecked() {
+ var untyped = UntypedTableDefinitionNode.arbitrary()
+ .withName("authors")
+ .withRowType(UntypedTypeLevelReferenceNode.arbitrary()
+ .withName("Author")
+ .build()
+ )
+ .build();
+ var globalContext = TypeCheckerContextArb.globalContext();
+ var namespaceContext = globalContext.enterNamespace(NamespaceName.of("App"));
+ var authorType = new SimpleStructType(NamespaceName.of("App"), "Author");
+ namespaceContext.declare("Author", Types.metaType(authorType), NullSource.INSTANCE);
+
+ var typed = typeCheckDatabaseSchemaStatement(untyped, namespaceContext);
+
+ assertThat(typed, isTypedTableDefinitionNode()
+ .withName(equalTo("authors"))
+ .withRowType(equalTo(authorType))
+ );
+ }
+}