diff --git a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/RTTI.java b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/RTTI.java index eaf1e4e1a..9712f246e 100644 --- a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/RTTI.java +++ b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/RTTI.java @@ -532,7 +532,7 @@ private AttributeInfo( ) { this.name = name; this.category = category; - this.typeName = TypeName.of(typeName); + this.typeName = TypeName.parse(typeName); this.type = type; this.getter = getter; this.setter = setter; diff --git a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/TypeName.java b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/TypeName.java index efb56d427..7f9c922a2 100644 --- a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/TypeName.java +++ b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/TypeName.java @@ -5,22 +5,29 @@ public sealed interface TypeName { @NotNull static TypeName of(@NotNull String name) { + return new Simple(name); + } + + @NotNull + static TypeName of(@NotNull String name, TypeName argument) { + return new Parameterized(name, argument); + } + + @NotNull + static TypeName parse(@NotNull String name) { int start = name.indexOf('<'); if (start < 0) { - return new Simple(name); + return of(name); } int end = name.lastIndexOf('>'); if (start == 0 || end < start + 1) { - throw new IllegalArgumentException("Invalid template name: '" + name + "'"); + throw new IllegalArgumentException("Invalid parameterized name: '" + name + "'"); } String rawType = name.substring(0, start); String argumentType = name.substring(start + 1, end); - return new Parameterized(rawType, of(argumentType)); + return of(rawType, parse(argumentType)); } - @NotNull - String name(); - @NotNull String fullName(); diff --git a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/GenerateBindingsProcessor.java b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/GenerateBindingsProcessor.java index 078fd37f8..bab36771b 100644 --- a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/GenerateBindingsProcessor.java +++ b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/GenerateBindingsProcessor.java @@ -1,5 +1,6 @@ package com.shade.decima.rtti.generator; +import com.shade.decima.rtti.TypeName; import com.shade.decima.rtti.generator.data.ClassTypeInfo; import com.shade.decima.rtti.generator.data.TypeInfo; import com.shade.util.NotNull; @@ -102,7 +103,8 @@ public SourceVersion getSupportedSourceVersion() { private void reportMissingCallbacks(@NotNull TypeContext context, @NotNull GenerateBindings annotation) { Set typesMissingCallback = context.types().stream() .filter(info -> info instanceof ClassTypeInfo cls && cls.messages().contains("MsgReadBinary")) - .map(TypeInfo::fullName) + .map(TypeInfo::typeName) + .map(TypeName::fullName) .collect(Collectors.toSet()); for (GenerateBindings.Callback callback : annotation.callbacks()) { diff --git a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/TypeContext.java b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/TypeContext.java index debd172e5..0e0d87ecf 100644 --- a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/TypeContext.java +++ b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/TypeContext.java @@ -3,6 +3,7 @@ import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; +import com.shade.decima.rtti.TypeName; import com.shade.decima.rtti.generator.data.*; import com.shade.util.NotNull; @@ -13,18 +14,18 @@ import java.util.*; public class TypeContext { - private final Map types = new TreeMap<>(String::compareToIgnoreCase); + private final Map types = new TreeMap<>(Comparator.comparing(TypeName::fullName, String::compareToIgnoreCase)); public void load(@NotNull Path path) throws IOException { try (BufferedReader reader = Files.newBufferedReader(path)) { JsonObject root = JsonParser.parseReader(reader).getAsJsonObject(); Resolver resolver = new Resolver() { - private final Map pending = new HashMap<>(); + private final Map pending = new HashMap<>(); @NotNull @Override - public TypeInfoRef get(@NotNull String name) { + public TypeInfoRef get(@NotNull TypeName name) { if (pending.containsKey(name)) { return pending.get(name); } @@ -36,30 +37,24 @@ public TypeInfoRef get(@NotNull String name) { pending.put(name, new FutureRef(name)); - if (name.indexOf('<') >= 0) { - int templateStart = name.indexOf('<'); - int templateEnd = name.lastIndexOf('>'); - if (templateEnd < templateStart + 1) { - throw new IllegalArgumentException("Invalid template name: '" + name + "'"); - } - - String rawType = name.substring(0, templateStart); - String argumentType = name.substring(templateStart + 1, templateEnd); - - return resolve(get(rawType, argumentType)); + if (name instanceof TypeName.Parameterized parameterized) { + return resolve(getParameterizedType(parameterized.name(), parameterized.argument())); } else { - JsonObject info = root.getAsJsonObject(name); - if (info == null) { - throw new IllegalArgumentException("Unknown type: " + name); - } + return resolve(getSimpleType(name.fullName())); + } + } - return resolve(loadSingleType(name, info, this)); + @NotNull + private TypeInfo getSimpleType(@NotNull String name) { + JsonObject info = root.getAsJsonObject(name); + if (info == null) { + throw new IllegalArgumentException("Unknown type: " + name); } + return loadSingleType(name, info, this); } @NotNull - @Override - public TypeInfo get(@NotNull String name, @NotNull String argument) { + private TypeInfo getParameterizedType(@NotNull String name, @NotNull TypeName argument) { return switch (name) { case "Array", "TinyArray" -> new ContainerTypeInfo(name, get(argument)); case "Ref", "cptr" -> new PointerTypeInfo(name, get(argument)); @@ -69,12 +64,12 @@ public TypeInfo get(@NotNull String name, @NotNull String argument) { @NotNull private TypeInfoRef resolve(@NotNull TypeInfo info) { - FutureRef ref = pending.remove(info.fullName()); + FutureRef ref = pending.remove(info.typeName()); if (ref == null) { - throw new IllegalStateException("Type was not present in the queue: " + info.fullName()); + throw new IllegalStateException("Type was not present in the queue: " + info.typeName()); } - if (types.put(info.fullName(), info) != null) { - throw new IllegalStateException("Type was already resolved: " + info.fullName()); + if (types.put(info.typeName(), info) != null) { + throw new IllegalStateException("Type was already resolved: " + info.typeName()); } ref.resolved = info; return ref; @@ -85,16 +80,11 @@ private TypeInfoRef resolve(@NotNull TypeInfo info) { if (name.startsWith("$")) { continue; } - resolver.get(name); + resolver.get(TypeName.of(name)); } } } - @NotNull - public TypeInfo get(@NotNull String name) { - return Objects.requireNonNull(types.get(name), () -> "Unknown type: " + name); - } - @NotNull public Collection types() { return Collections.unmodifiableCollection(types.values()); @@ -115,7 +105,7 @@ private static TypeInfo loadSingleType(@NotNull String name, @NotNull JsonObject @NotNull private static TypeInfo loadAtomType(@NotNull String name, @NotNull JsonObject object, @NotNull Resolver resolver) { String base = object.get("base_type").getAsString(); - return new AtomTypeInfo(name, base.equals(name) ? null : resolver.get(base).value()); + return new AtomTypeInfo(name, base.equals(name) ? null : resolver.get(TypeName.of(base)).value()); } @NotNull @@ -150,8 +140,9 @@ private static TypeInfo loadCompoundType(@NotNull String name, @NotNull JsonObje if (object.has("bases")) { for (JsonElement element : object.getAsJsonArray("bases")) { JsonObject base = element.getAsJsonObject(); + TypeName baseName = TypeName.of(base.get("name").getAsString()); bases.add(new ClassBaseInfo( - (ClassTypeInfo) resolver.get(base.get("name").getAsString()).value(), + (ClassTypeInfo) resolver.get(baseName).value(), base.get("offset").getAsInt() )); } @@ -169,7 +160,7 @@ private static TypeInfo loadCompoundType(@NotNull String name, @NotNull JsonObje attrs.add(new ClassAttrInfo( attr.get("name").getAsString(), category, - resolver.get(attr.get("type").getAsString()), + resolver.get(TypeName.parse(attr.get("type").getAsString())), attr.has("min") ? attr.get("min").getAsString() : null, attr.has("max") ? attr.get("max").getAsString() : null, attrs.size(), @@ -199,17 +190,14 @@ private static TypeInfo loadCompoundType(@NotNull String name, @NotNull JsonObje private interface Resolver { @NotNull - TypeInfoRef get(@NotNull String name); - - @NotNull - TypeInfo get(@NotNull String name, @NotNull String argument); + TypeInfoRef get(@NotNull TypeName name); } private record ResolvedRef(@NotNull TypeInfo value) implements TypeInfoRef { @NotNull @Override - public String typeName() { - return value.fullName(); + public TypeName typeName() { + return value.typeName(); } @Override @@ -219,16 +207,16 @@ public String toString() { } private static class FutureRef implements TypeInfoRef { - private final String name; + private final TypeName name; private TypeInfo resolved; - public FutureRef(@NotNull String name) { + public FutureRef(@NotNull TypeName name) { this.name = name; } @NotNull @Override - public String typeName() { + public TypeName typeName() { return name; } diff --git a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/TypeGenerator.java b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/TypeGenerator.java index a065e1013..2d37080e0 100644 --- a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/TypeGenerator.java +++ b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/TypeGenerator.java @@ -37,7 +37,7 @@ public TypeSpec generate(@NotNull TypeInfo type) { } else if (type instanceof ContainerTypeInfo || type instanceof PointerTypeInfo) { return null; } else { - throw new IllegalArgumentException("Unknown type: " + type.fullName()); + throw new IllegalArgumentException("Unknown type: " + type.typeName()); } } diff --git a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/TypeNameUtil.java b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/TypeNameUtil.java index 7ca620191..c22db3fc2 100644 --- a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/TypeNameUtil.java +++ b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/TypeNameUtil.java @@ -28,10 +28,11 @@ static String getJavaConstantName(@NotNull EnumTypeInfo info, @NotNull EnumValue return "_" + info.values().indexOf(value); } + String type = info.typeName().fullName(); String name = value.name(); - if (name.toLowerCase(Locale.ROOT).startsWith(info.fullName().toLowerCase(Locale.ROOT))) { - name = name.substring(info.fullName().length() + 1); + if (name.toLowerCase(Locale.ROOT).startsWith(type.toLowerCase(Locale.ROOT))) { + name = name.substring(type.length() + 1); } name = name.replaceAll("[()]", "").replaceAll("/", "_"); @@ -121,12 +122,12 @@ static TypeName getTypeName(@NotNull TypeInfo type) { return ParameterizedTypeName.get(ClassName.get(List.class), argument); } } - throw new IllegalArgumentException("Unknown type: " + type.fullName()); + throw new IllegalArgumentException("Unknown type: " + type.typeName()); } @NotNull private static String getJavaTypeName(@NotNull TypeInfo info) { - String name = info.fullName(); + String name = info.typeName().fullName(); if (info instanceof EnumTypeInfo && name.matches("^[Ee][A-Z].*$")) { return name.substring(1); } diff --git a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/AtomTypeInfo.java b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/AtomTypeInfo.java index 8c916adb6..4994c3d0c 100644 --- a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/AtomTypeInfo.java +++ b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/AtomTypeInfo.java @@ -1,5 +1,6 @@ package com.shade.decima.rtti.generator.data; +import com.shade.decima.rtti.TypeName; import com.shade.util.NotNull; import com.shade.util.Nullable; @@ -9,7 +10,7 @@ public record AtomTypeInfo( ) implements TypeInfo { @NotNull @Override - public String fullName() { - return name; + public TypeName typeName() { + return TypeName.of(name); } } diff --git a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/ClassTypeInfo.java b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/ClassTypeInfo.java index a7ce91775..fc3fcf032 100644 --- a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/ClassTypeInfo.java +++ b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/ClassTypeInfo.java @@ -1,5 +1,6 @@ package com.shade.decima.rtti.generator.data; +import com.shade.decima.rtti.TypeName; import com.shade.util.NotNull; import java.util.List; @@ -27,8 +28,8 @@ public boolean isAssignableTo(@NotNull String name) { @NotNull @Override - public String fullName() { - return name; + public TypeName typeName() { + return TypeName.of(name); } @Override diff --git a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/ContainerTypeInfo.java b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/ContainerTypeInfo.java index 8652e6cdf..0a3fee2c2 100644 --- a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/ContainerTypeInfo.java +++ b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/ContainerTypeInfo.java @@ -1,5 +1,6 @@ package com.shade.decima.rtti.generator.data; +import com.shade.decima.rtti.TypeName; import com.shade.util.NotNull; public record ContainerTypeInfo( @@ -8,7 +9,7 @@ public record ContainerTypeInfo( ) implements TypeInfo { @NotNull @Override - public String fullName() { - return "%s<%s>".formatted(name, type.typeName()); + public TypeName typeName() { + return TypeName.of(name, type.typeName()); } } diff --git a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/EnumTypeInfo.java b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/EnumTypeInfo.java index f8d744bc3..34b7c3e8e 100644 --- a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/EnumTypeInfo.java +++ b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/EnumTypeInfo.java @@ -1,5 +1,6 @@ package com.shade.decima.rtti.generator.data; +import com.shade.decima.rtti.TypeName; import com.shade.util.NotNull; import java.util.List; @@ -12,7 +13,7 @@ public record EnumTypeInfo( ) implements TypeInfo { @NotNull @Override - public String fullName() { - return name; + public TypeName typeName() { + return TypeName.of(name); } } diff --git a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/PointerTypeInfo.java b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/PointerTypeInfo.java index 87b82acd0..11ffc9cbd 100644 --- a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/PointerTypeInfo.java +++ b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/PointerTypeInfo.java @@ -1,5 +1,6 @@ package com.shade.decima.rtti.generator.data; +import com.shade.decima.rtti.TypeName; import com.shade.util.NotNull; public record PointerTypeInfo( @@ -8,7 +9,7 @@ public record PointerTypeInfo( ) implements TypeInfo { @NotNull @Override - public String fullName() { - return "%s<%s>".formatted(name, type.typeName()); + public TypeName typeName() { + return TypeName.of(name, type.typeName()); } } diff --git a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/TypeInfo.java b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/TypeInfo.java index 35e0b75fe..1328c5278 100644 --- a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/TypeInfo.java +++ b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/TypeInfo.java @@ -1,10 +1,11 @@ package com.shade.decima.rtti.generator.data; +import com.shade.decima.rtti.TypeName; import com.shade.util.NotNull; public sealed interface TypeInfo permits AtomTypeInfo, ClassTypeInfo, EnumTypeInfo, ContainerTypeInfo, PointerTypeInfo { @NotNull - String fullName(); + TypeName typeName(); } diff --git a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/TypeInfoRef.java b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/TypeInfoRef.java index 77a6dc7f3..a2c1cae9b 100644 --- a/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/TypeInfoRef.java +++ b/modules/decima-rtti/src/main/java/com/shade/decima/rtti/generator/data/TypeInfoRef.java @@ -1,10 +1,11 @@ package com.shade.decima.rtti.generator.data; +import com.shade.decima.rtti.TypeName; import com.shade.util.NotNull; public interface TypeInfoRef { @NotNull - String typeName(); + TypeName typeName(); @NotNull TypeInfo value();