diff --git a/buildSrc/src/main/groovy/ethylene.library-conventions.gradle b/buildSrc/src/main/groovy/ethylene.library-conventions.gradle index ba80cdb..258459e 100644 --- a/buildSrc/src/main/groovy/ethylene.library-conventions.gradle +++ b/buildSrc/src/main/groovy/ethylene.library-conventions.gradle @@ -6,7 +6,7 @@ plugins { } group 'com.github.steanky' -version '0.23.1' +version '0.23.2' publishing { publications { diff --git a/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/Signature.java b/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/Signature.java index af0be4b..2f18b72 100644 --- a/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/Signature.java +++ b/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/Signature.java @@ -124,7 +124,7 @@ default boolean hasBuildingObject() { * @param element the element from which to initialize the building object * @return the initialized building object which will later be populated with data */ - default @NotNull TReturn initBuildingObject(@NotNull ConfigElement element) { + default @NotNull Object initBuildingObject(@NotNull ConfigElement element) { throw new UnsupportedOperationException("This signature does not support pre-initialized building objects"); } @@ -136,7 +136,7 @@ default boolean hasBuildingObject() { * @return a new object if this signature does not have a building object; otherwise, if a building object is * provided, populates it */ - @NotNull TReturn buildObject(@Nullable TReturn buildingObject, Object @NotNull [] args); + @NotNull Object buildObject(@Nullable Object buildingObject, Object @NotNull [] args); /** * Whether this signature should respect argument names when being matched. @@ -312,7 +312,7 @@ private SignatureImpl(int priority, Collection() { @Override - public Iterator iterator() { + public @NotNull Iterator iterator() { return new Iterator<>() { private final Iterator objectIterator = args.iterator(); private final Iterator> entryIterator = argumentTypes.iterator(); @@ -351,7 +351,7 @@ public boolean hasBuildingObject() { } @Override - public @NotNull T initBuildingObject(@NotNull ConfigElement element) { + public @NotNull Object initBuildingObject(@NotNull ConfigElement element) { if (buildingObjectInitializer == null) { //throws an exception return Signature.super.initBuildingObject(element); @@ -360,9 +360,10 @@ public boolean hasBuildingObject() { return buildingObjectInitializer.apply(element); } + @SuppressWarnings("unchecked") @Override - public @NotNull T buildObject(@Nullable T buildingObject, Object @NotNull [] args) { - return constructor.apply(buildingObject, new Arguments(args)); + public @NotNull T buildObject(@Nullable Object buildingObject, Object @NotNull [] args) { + return constructor.apply((T) buildingObject, new Arguments(args)); } @Override diff --git a/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/constructor/ConstructorSignature.java b/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/constructor/ConstructorSignature.java index c0627f8..d15652d 100644 --- a/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/constructor/ConstructorSignature.java +++ b/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/constructor/ConstructorSignature.java @@ -169,7 +169,7 @@ private static Map.Entry makeEntry(Parameter paramet @SuppressWarnings("unchecked") @Override - public @NotNull T buildObject(@Nullable T buildingObject, Object @NotNull [] args) { + public @NotNull T buildObject(@Nullable Object buildingObject, Object @NotNull [] args) { if (buildingObject != null) { throw new MapperException("ConstructorSignature does not support pre-initialized building objects"); } diff --git a/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/container/ArraySignature.java b/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/container/ArraySignature.java index b7a02d6..3e3a2e4 100644 --- a/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/container/ArraySignature.java +++ b/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/container/ArraySignature.java @@ -32,7 +32,7 @@ public ArraySignature(@NotNull Token componentType) { return new AbstractCollection<>() { @Override - public Iterator iterator() { + public @NotNull Iterator iterator() { return new Iterator<>() { private int i = 0; @@ -59,21 +59,29 @@ public int size() { }; } - - @SuppressWarnings({"SuspiciousSystemArraycopy", "unchecked"}) + @SuppressWarnings("SuspiciousSystemArraycopy") @Override - public T @NotNull [] buildObject(@NotNull T @Nullable [] buildingObject, Object @NotNull [] args) { + public @NotNull Object buildObject(@Nullable Object buildingObject, Object @NotNull [] args) { if (buildingObject == null) { - return (T[]) args; + buildingObject = Array.newInstance(containerType.componentType().rawType(), args.length); + } + + if (containerType.componentType().rawType().isPrimitive()) { + //manual arraycopy when component type is primitive, we must unbox as args will be boxed + for (int i = 0; i < args.length; i++) { + Array.set(buildingObject, i, args[i]); + } + + return buildingObject; } + //in other cases, we can do a likely-faster arraycopy System.arraycopy(args, 0, buildingObject, 0, args.length); return buildingObject; } - @SuppressWarnings("unchecked") @Override - protected @NotNull T @NotNull [] makeBuildingObject(@NotNull ConfigContainer container) { - return (T[]) Array.newInstance(containerType.componentType().rawType(), container.elementCollection().size()); + protected @NotNull Object makeBuildingObject(@NotNull ConfigContainer container) { + return Array.newInstance(containerType.componentType().rawType(), container.elementCollection().size()); } } diff --git a/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/container/CollectionSignature.java b/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/container/CollectionSignature.java index fadc361..cd2bf4d 100644 --- a/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/container/CollectionSignature.java +++ b/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/container/CollectionSignature.java @@ -37,7 +37,7 @@ public CollectionSignature(@NotNull Token componentType, @NotNull Token co return new AbstractCollection<>() { @Override - public Iterator iterator() { + public @NotNull Iterator iterator() { return new Iterator<>() { private final Iterator collectionIterator = objectCollection.iterator(); @@ -63,7 +63,7 @@ public int size() { @SuppressWarnings("unchecked") @Override - public @NotNull T buildObject(@Nullable T buildingObject, Object @NotNull [] args) { + public @NotNull T buildObject(@Nullable Object buildingObject, Object @NotNull [] args) { if (buildingObject != null) { Collection buildingCollection = (Collection) buildingObject; buildingCollection.addAll(Arrays.asList(args)); @@ -92,9 +92,8 @@ private Collection makeNewCollection(int size) { } } - @SuppressWarnings("unchecked") @Override - protected @NotNull T makeBuildingObject(@NotNull ConfigContainer container) { - return (T) makeNewCollection(container.entryCollection().size()); + protected @NotNull Object makeBuildingObject(@NotNull ConfigContainer container) { + return makeNewCollection(container.entryCollection().size()); } } diff --git a/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/container/ContainerSignatureBase.java b/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/container/ContainerSignatureBase.java index e8d175c..3e31494 100644 --- a/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/container/ContainerSignatureBase.java +++ b/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/container/ContainerSignatureBase.java @@ -127,7 +127,7 @@ public boolean hasBuildingObject() { } @Override - public @NotNull T initBuildingObject(@NotNull ConfigElement element) { + public @NotNull Object initBuildingObject(@NotNull ConfigElement element) { if (!element.isContainer()) { throw new MapperException("Expected container, got '" + element.type() + "'"); } @@ -165,7 +165,7 @@ public int length(@Nullable ConfigElement configElement) { * @param container the {@link ConfigContainer} used to create the building object * @return the new building object */ - protected abstract @NotNull T makeBuildingObject(@NotNull ConfigContainer container); + protected abstract @NotNull Object makeBuildingObject(@NotNull ConfigContainer container); /** * Information about a constructor. Container constructors may be parameterless (in which case they take no diff --git a/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/container/MapSignature.java b/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/container/MapSignature.java index c35057e..78189bc 100644 --- a/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/container/MapSignature.java +++ b/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/container/MapSignature.java @@ -9,10 +9,7 @@ import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.util.AbstractCollection; -import java.util.Collection; -import java.util.Iterator; -import java.util.Map; +import java.util.*; /** @@ -39,7 +36,7 @@ public MapSignature(@NotNull Token keyType, @NotNull Token valueType, @Not return new AbstractCollection<>() { @Override - public Iterator iterator() { + public @NotNull Iterator iterator() { return new Iterator<>() { private final Iterator> entryIterator = map.entrySet().iterator(); @@ -64,7 +61,7 @@ public int size() { @SuppressWarnings("unchecked") @Override - public @NotNull T buildObject(@Nullable T buildingObject, Object @NotNull [] args) { + public @NotNull T buildObject(@Nullable Object buildingObject, Object @NotNull [] args) { if (buildingObject != null) { Map buildingMap = (Map) buildingObject; finishMap(buildingMap, args); @@ -98,9 +95,8 @@ private Map getMap(int size) { } } - @SuppressWarnings("unchecked") @Override - protected @NotNull T makeBuildingObject(@NotNull ConfigContainer container) { - return (T) getMap(container.entryCollection().size()); + protected @NotNull Object makeBuildingObject(@NotNull ConfigContainer container) { + return getMap(container.entryCollection().size()); } } diff --git a/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/field/FieldSignature.java b/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/field/FieldSignature.java index 7c965b7..2892d4d 100644 --- a/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/field/FieldSignature.java +++ b/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/field/FieldSignature.java @@ -177,7 +177,7 @@ public boolean hasBuildingObject() { } @Override - public @NotNull T buildObject(@Nullable T buildingObject, Object @NotNull [] args) { + public @NotNull Object buildObject(@Nullable Object buildingObject, Object @NotNull [] args) { try { if (buildingObject != null) { finishObject(buildingObject, args); diff --git a/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/record/RecordSignature.java b/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/record/RecordSignature.java index 359fa9a..b57e607 100644 --- a/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/record/RecordSignature.java +++ b/ethylene-mapper/src/main/java/com/github/steanky/ethylene/mapper/signature/record/RecordSignature.java @@ -105,7 +105,7 @@ public RecordSignature(@NotNull Token genericReturnType) { @SuppressWarnings("unchecked") @Override - public @NotNull T buildObject(@Nullable T buildingObject, Object @NotNull [] args) { + public @NotNull T buildObject(@Nullable Object buildingObject, Object @NotNull [] args) { if (buildingObject != null) { throw new MapperException("Pre-initialized building objects are not supported by this signature"); } diff --git a/ethylene-mapper/src/test/java/com/github/steanky/ethylene/mapper/MappingConfigProcessorIntegrationTest.java b/ethylene-mapper/src/test/java/com/github/steanky/ethylene/mapper/MappingConfigProcessorIntegrationTest.java index 49b1524..7256868 100644 --- a/ethylene-mapper/src/test/java/com/github/steanky/ethylene/mapper/MappingConfigProcessorIntegrationTest.java +++ b/ethylene-mapper/src/test/java/com/github/steanky/ethylene/mapper/MappingConfigProcessorIntegrationTest.java @@ -220,6 +220,19 @@ public record Child(double data) {} public record Data(int x, Child child) {} + public record IntArrayContaining(int[] values) { + + } + + @Test + void intArray() throws ConfigProcessException { + ConfigProcessor processor = new MappingConfigProcessor<>(new Token<>() { + }, source, typeHinter, typeResolver, scalarSource, false); + + IntArrayContaining containing = processor.dataFromElement(ConfigElement.of("{values=[0, 1, 2, 3, 4]}")); + assertArrayEquals(new int[] {0, 1, 2, 3, 4}, containing.values); + } + @Test void upcastFloat() throws ConfigProcessException { ConfigProcessor processor = new MappingConfigProcessor<>(new Token<>() {