aboutsummaryrefslogtreecommitdiff
path: root/src/main/java
diff options
context:
space:
mode:
authorMichael Williamson <mike@zwobble.org>2023-12-25 12:05:46 +0000
committerMichael Williamson <mike@zwobble.org>2023-12-25 12:07:37 +0000
commit854545383ef1145223c181127a40a9a2cc2be638 (patch)
treef5265b11a9620681523602393ba75acc6fbdaf59 /src/main/java
parent1c0b88e256de6b4ea1b0c34ad525dfdad471f5ee (diff)
Support field accesses on constructed types
Diffstat (limited to 'src/main/java')
-rw-r--r--src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java12
-rw-r--r--src/main/java/org/shedlang/compiler/types/ConstructedType.java17
2 files changed, 29 insertions, 0 deletions
diff --git a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
index fe8c7b9a..f42a4030 100644
--- a/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
+++ b/src/main/java/org/shedlang/compiler/typechecker/TypeChecker.java
@@ -588,6 +588,18 @@ public class TypeChecker {
TypeCheckerContext context
) {
switch (receiverType) {
+ case ConstructedType<?> receiverTypeConstructed -> {
+ return fieldTypeOrEmpty(
+ receiverTypeConstructed.genericType(),
+ fieldName,
+ source,
+ context
+ ).map(genericFieldType -> TypeSubstitution.substitute(
+ genericFieldType,
+ receiverTypeConstructed.typeSubstitutionMap()
+ ));
+ }
+
case StructType receiverTypeStruct -> {
var structTypeInfo = context.structTypeInfo(receiverTypeStruct, source);
return structTypeInfo.fieldType(fieldName);
diff --git a/src/main/java/org/shedlang/compiler/types/ConstructedType.java b/src/main/java/org/shedlang/compiler/types/ConstructedType.java
index 558b227b..09cfcc83 100644
--- a/src/main/java/org/shedlang/compiler/types/ConstructedType.java
+++ b/src/main/java/org/shedlang/compiler/types/ConstructedType.java
@@ -1,5 +1,6 @@
package org.shedlang.compiler.types;
+import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;
@@ -14,4 +15,20 @@ public record ConstructedType<T extends StructuredType>(
.collect(Collectors.joining(", "));
return constructor.describe() + "[" + argsString + "]";
}
+
+ public T genericType() {
+ return constructor.genericType();
+ }
+
+ public TypeSubstitutionMap typeSubstitutionMap() {
+ var map = new HashMap<TypeParam, Type>();
+
+ for (var argIndex = 0; argIndex < args.size(); argIndex++) {
+ var param = constructor.params().get(argIndex);
+ var arg = args.get(argIndex);
+ map.put(param, arg);
+ }
+
+ return new TypeSubstitutionMap(map);
+ }
}