summaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2026-11-01 21:48:11 +0000
committerMichael Williamson <mike@zwobble.org>2026-11-01 21:48:11 +0000
commit158ebdbc74e74894a32be9c8908da4b068326b67 (patch)
treedefe734b21c4cd7201c8b298e6253211ced009ec /src/main/java
parent9f8eb523395296b5d37498d89423daedf8e0121d (diff)
Read tables as members from database schema
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java54
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java4
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/typechecker/errors/NoSuchMemberError.java24
-rw-r--r--src/main/java/org/zwobble/hobgoblin/compiler/types/TableInfo.java1
4 files changed, 74 insertions, 9 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 d73c245..da83e6f 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeChecker.java
@@ -163,16 +163,19 @@ public class TypeChecker {
UntypedDatabaseSchemaDefinitionNode untyped,
TypeCheckerNamespaceContext context
) {
+ var databaseSchema = new DatabaseSchema(context.namespaceName(), untyped.name());
var databaseSchemaInfo = new DatabaseSchemaInfo(new LinkedHashMap<>());
var typedBody = untyped.body().stream()
- .map(statement -> typeCheckDatabaseSchemaStatement(statement, databaseSchemaInfo, context))
+ .map(statement -> typeCheckDatabaseSchemaStatement(
+ statement,
+ databaseSchema,
+ databaseSchemaInfo,
+ context
+ ))
.toList();
- context.defineDatabaseSchema(
- new DatabaseSchema(context.namespaceName(), untyped.name()),
- databaseSchemaInfo
- );
+ context.defineDatabaseSchema(databaseSchema, databaseSchemaInfo);
return new TypedDatabaseSchemaDefinitionNode(
untyped.name(),
@@ -509,17 +512,24 @@ public class TypeChecker {
static TypedDatabaseSchemaStatementNode typeCheckDatabaseSchemaStatement(
UntypedDatabaseSchemaStatementNode statement,
+ DatabaseSchema databaseSchema,
DatabaseSchemaInfo databaseSchemaInfo,
TypeCheckerNamespaceContext context
) {
return switch (statement) {
case UntypedTableDefinitionNode untypedTableDefinition ->
- typeCheckTableDefinition(untypedTableDefinition, databaseSchemaInfo, context);
+ typeCheckTableDefinition(
+ untypedTableDefinition,
+ databaseSchema,
+ databaseSchemaInfo,
+ context
+ );
};
}
private static TypedTableDefinitionNode typeCheckTableDefinition(
UntypedTableDefinitionNode untyped,
+ DatabaseSchema databaseSchema,
DatabaseSchemaInfo databaseSchemaInfo,
TypeCheckerNamespaceContext context
) {
@@ -542,7 +552,8 @@ public class TypeChecker {
throw new NoSuchFieldError(rowType, untyped.primaryKey(), untyped.source());
}
- var tableInfo = new TableInfo(rowType, primaryKeyField.get());
+ var table = new Table(databaseSchema, untyped.name());
+ var tableInfo = new TableInfo(table, rowType, primaryKeyField.get());
databaseSchemaInfo.tables().put(untyped.name(), tableInfo);
@@ -694,12 +705,37 @@ public class TypeChecker {
case UntypedFunctionExpressionNode _ -> {
throw new UnsupportedOperationException("TODO");
}
- case UntypedMemberAccessNode _ -> {
- throw new UnsupportedOperationException("TODO");
+ case UntypedMemberAccessNode memberAccess -> {
+ return evalMemberAccess(memberAccess, context);
}
case UntypedReferenceNode reference -> {
return lookupTypeLevelValue(reference.name(), reference.source(), context);
}
}
}
+
+ private static TypeLevelValue evalMemberAccess(
+ UntypedMemberAccessNode memberAccess,
+ TypeCheckerNamespaceContext context
+ ) {
+ var receiver = evalExpression(memberAccess.receiver(), context);
+ switch (receiver) {
+ case DatabaseSchema databaseSchema -> {
+ var schemaInfo = context.databaseSchemaInfo(databaseSchema);
+ var tableInfo = schemaInfo.tables().get(memberAccess.memberName());
+ if (tableInfo != null) {
+ return tableInfo.table();
+ }
+ }
+
+ case Table _, Type _, TypeConstructor<?> _ -> {
+ }
+ }
+
+ throw new NoSuchMemberError(
+ new TypeLevelValueType(receiver),
+ memberAccess.memberName(),
+ memberAccess.source()
+ );
+ }
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java
index b18769d..4a82c05 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/TypeCheckerNamespaceContext.java
@@ -64,6 +64,10 @@ public class TypeCheckerNamespaceContext {
this.typesInfo.defineDatabaseSchema(databaseSchema, databaseSchemaInfo);
}
+ public DatabaseSchemaInfo databaseSchemaInfo(DatabaseSchema databaseSchema) {
+ return this.typesInfo.databaseSchemaInfo(databaseSchema);
+ }
+
public void defineEnumType(EnumType enumType, List<EnumVariant> enumVariants) {
this.typesInfo.defineEnumType(enumType, enumVariants);
}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/errors/NoSuchMemberError.java b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/errors/NoSuchMemberError.java
new file mode 100644
index 0000000..b2b1d55
--- /dev/null
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/typechecker/errors/NoSuchMemberError.java
@@ -0,0 +1,24 @@
+package org.zwobble.hobgoblin.compiler.typechecker.errors;
+
+import org.zwobble.hobgoblin.compiler.errors.SourceError;
+import org.zwobble.hobgoblin.compiler.sources.Source;
+import org.zwobble.hobgoblin.compiler.types.Type;
+
+public class NoSuchMemberError extends SourceError {
+ private final Type type;
+ private final String memberName;
+
+ public NoSuchMemberError(Type type, String memberName, Source source) {
+ super(type.describe() + " does not have a member named " + memberName, source);
+ this.type = type;
+ this.memberName = memberName;
+ }
+
+ public Type type() {
+ return type;
+ }
+
+ public String memberName() {
+ return memberName;
+ }
+}
diff --git a/src/main/java/org/zwobble/hobgoblin/compiler/types/TableInfo.java b/src/main/java/org/zwobble/hobgoblin/compiler/types/TableInfo.java
index 6632e51..b991b54 100644
--- a/src/main/java/org/zwobble/hobgoblin/compiler/types/TableInfo.java
+++ b/src/main/java/org/zwobble/hobgoblin/compiler/types/TableInfo.java
@@ -1,6 +1,7 @@
package org.zwobble.hobgoblin.compiler.types;
public record TableInfo(
+ Table table,
SimpleStructType rowType,
Field primaryKey
) {