From 27eeceb7adfe7a999f97d26a8eaf985e4d90eac2 Mon Sep 17 00:00:00 2001 From: Patrick Doyle Date: Wed, 1 May 2024 13:46:30 -0400 Subject: [PATCH] Enhance TypeValidation: give advice for primitives --- .../java/io/vena/bosk/TypeValidation.java | 4 ++ .../java/io/vena/bosk/TypeValidationTest.java | 55 ++++++++++++++++--- 2 files changed, 51 insertions(+), 8 deletions(-) diff --git a/bosk-core/src/main/java/io/vena/bosk/TypeValidation.java b/bosk-core/src/main/java/io/vena/bosk/TypeValidation.java index 27ee6f8a..4e116f4f 100644 --- a/bosk-core/src/main/java/io/vena/bosk/TypeValidation.java +++ b/bosk-core/src/main/java/io/vena/bosk/TypeValidation.java @@ -7,6 +7,7 @@ import io.vena.bosk.exceptions.InvalidFieldTypeException; import io.vena.bosk.exceptions.InvalidTypeException; import java.lang.annotation.Annotation; +import java.lang.invoke.MethodType; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.lang.reflect.Method; @@ -50,6 +51,9 @@ private static void validateType(Type theType, Set alreadyValidated) throw Class theClass = rawClass(theType); if (!isPublic(theClass.getModifiers())) { throw new InvalidTypeException("Class is not public: " + theClass.getName()); + } else if (theClass.isPrimitive()) { + Class wrapped = MethodType.methodType(theClass).wrap().returnType(); + throw new InvalidTypeException("Primitive types are not allowed in a bosk; use boxed " + wrapped.getSimpleName() + " instead of primitive " + theClass.getSimpleName()); } else if (isSimpleClass(theClass)) { // All allowed return; diff --git a/bosk-core/src/test/java/io/vena/bosk/TypeValidationTest.java b/bosk-core/src/test/java/io/vena/bosk/TypeValidationTest.java index 1be011d1..10178af2 100644 --- a/bosk-core/src/test/java/io/vena/bosk/TypeValidationTest.java +++ b/bosk-core/src/test/java/io/vena/bosk/TypeValidationTest.java @@ -134,14 +134,53 @@ public record BoxedPrimitives( Double doubleObject ) implements StateTreeNode { } - public record BooleanPrimitive(boolean field) implements StateTreeNode {} - public record BytePrimitive(byte field) implements StateTreeNode {} - public record CharPrimitive(char field) implements StateTreeNode {} - public record ShortPrimitive(short field) implements StateTreeNode {} - public record IntegerPrimitive(int field) implements StateTreeNode {} - public record LongPrimitive(long field) implements StateTreeNode {} - public record FloatPrimitive(float field) implements StateTreeNode {} - public record DoublePrimitive(double field) implements StateTreeNode {} + public record BooleanPrimitive(boolean field) implements StateTreeNode { + static void testException(InvalidTypeException e) { + assertThat(e.getMessage(), containsStringIgnoringCase("primitive")); + } + } + + public record BytePrimitive(byte field) implements StateTreeNode { + static void testException(InvalidTypeException e) { + assertThat(e.getMessage(), containsStringIgnoringCase("primitive")); + } + } + + public record CharPrimitive(char field) implements StateTreeNode { + static void testException(InvalidTypeException e) { + assertThat(e.getMessage(), containsStringIgnoringCase("primitive")); + } + } + + public record ShortPrimitive(short field) implements StateTreeNode { + static void testException(InvalidTypeException e) { + assertThat(e.getMessage(), containsStringIgnoringCase("primitive")); + } + } + + public record IntegerPrimitive(int field) implements StateTreeNode { + static void testException(InvalidTypeException e) { + assertThat(e.getMessage(), containsStringIgnoringCase("primitive")); + } + } + + public record LongPrimitive(long field) implements StateTreeNode { + static void testException(InvalidTypeException e) { + assertThat(e.getMessage(), containsStringIgnoringCase("primitive")); + } + } + + public record FloatPrimitive(float field) implements StateTreeNode { + static void testException(InvalidTypeException e) { + assertThat(e.getMessage(), containsStringIgnoringCase("primitive")); + } + } + + public record DoublePrimitive(double field) implements StateTreeNode { + static void testException(InvalidTypeException e) { + assertThat(e.getMessage(), containsStringIgnoringCase("primitive")); + } + } @Getter @FieldDefaults(level=AccessLevel.PRIVATE, makeFinal=true) @RequiredArgsConstructor public static final class SimpleTypes implements Entity {