From 731791dfc927af012aea21a4fd6df26a64426350 Mon Sep 17 00:00:00 2001 From: Maxou <5208681+mxyns@users.noreply.github.com> Date: Wed, 2 Mar 2022 12:57:16 +0100 Subject: [PATCH 1/3] tmp - record investigation / debugging --- .../jsoniter/ReflectionDecoderFactory.java | 2 +- .../com/jsoniter/ReflectionObjectDecoder.java | 3 ++ .../com/jsoniter/ReflectionRecordDecoder.java | 10 ++++ .../com/jsoniter/spi/ClassDescriptor.java | 17 ++++++- src/test/java/com/jsoniter/TestRecord.java | 49 +++++++++++++++++++ 5 files changed, 78 insertions(+), 3 deletions(-) create mode 100644 src/main/java/com/jsoniter/ReflectionRecordDecoder.java diff --git a/src/main/java/com/jsoniter/ReflectionDecoderFactory.java b/src/main/java/com/jsoniter/ReflectionDecoderFactory.java index d031cd28..2aaebc1d 100644 --- a/src/main/java/com/jsoniter/ReflectionDecoderFactory.java +++ b/src/main/java/com/jsoniter/ReflectionDecoderFactory.java @@ -24,7 +24,7 @@ public static Decoder create(ClassInfo classAndArgs) { return new ReflectionEnumDecoder(clazz); } if (clazz.isRecord()) { - return new ReflectionRecordDecoder(clazz, typeArgs); + return new ReflectionRecordDecoder(classAndArgs).create(); } return new ReflectionObjectDecoder(classAndArgs).create(); } diff --git a/src/main/java/com/jsoniter/ReflectionObjectDecoder.java b/src/main/java/com/jsoniter/ReflectionObjectDecoder.java index e1e76f73..8c0814d4 100644 --- a/src/main/java/com/jsoniter/ReflectionObjectDecoder.java +++ b/src/main/java/com/jsoniter/ReflectionObjectDecoder.java @@ -116,6 +116,7 @@ public class OnlyField implements Decoder { public Object decode(JsonIterator iter) throws IOException { try { + System.out.println("ONLY FIELD"); return decode_(iter); } catch (RuntimeException e) { throw e; @@ -181,6 +182,7 @@ public class WithCtor implements Decoder { @Override public Object decode(JsonIterator iter) throws IOException { try { + System.out.println("WITH CTOR"); return decode_(iter); } catch (RuntimeException e) { throw e; @@ -260,6 +262,7 @@ public class WithWrapper implements Decoder { @Override public Object decode(JsonIterator iter) throws IOException { try { + System.out.println("WITH WRAPPER"); return decode_(iter); } catch (RuntimeException e) { throw e; diff --git a/src/main/java/com/jsoniter/ReflectionRecordDecoder.java b/src/main/java/com/jsoniter/ReflectionRecordDecoder.java new file mode 100644 index 00000000..80bfd8ed --- /dev/null +++ b/src/main/java/com/jsoniter/ReflectionRecordDecoder.java @@ -0,0 +1,10 @@ +package com.jsoniter; + +import com.jsoniter.spi.ClassInfo; + +public class ReflectionRecordDecoder extends ReflectionObjectDecoder { + + public ReflectionRecordDecoder(ClassInfo classInfo) { + super(classInfo); + } +} diff --git a/src/main/java/com/jsoniter/spi/ClassDescriptor.java b/src/main/java/com/jsoniter/spi/ClassDescriptor.java index a47dbe5d..98217398 100644 --- a/src/main/java/com/jsoniter/spi/ClassDescriptor.java +++ b/src/main/java/com/jsoniter/spi/ClassDescriptor.java @@ -31,7 +31,7 @@ public static ClassDescriptor getDecodingClassDescriptor(ClassInfo classInfo, bo desc.classInfo = classInfo; desc.clazz = clazz; desc.lookup = lookup; - desc.ctor = getCtor(clazz); + desc.ctor = clazz.isRecord() ? getRecordCtor(clazz) : getCtor(clazz); desc.setters = getSetters(lookup, classInfo, includingPrivate); desc.getters = new ArrayList(); desc.fields = getFields(lookup, classInfo, includingPrivate); @@ -203,6 +203,20 @@ private static ConstructorDescriptor getCtor(Class clazz) { return cctor; } + private static ConstructorDescriptor getRecordCtor(Class clazz) { + ConstructorDescriptor cctor = new ConstructorDescriptor(); + try { + Constructor ctor = clazz.getDeclaredConstructors()[0]; + cctor.ctor = ctor; + for (Type parameter : ctor.getParameterTypes()) { + ClassInfo info = new ClassInfo(parameter); + } + } catch (Exception e) { + cctor.ctor = null; + } + return cctor; + } + private static List getFields(Map lookup, ClassInfo classInfo, boolean includingPrivate) { ArrayList bindings = new ArrayList(); for (Field field : getAllFields(classInfo.clazz)) { @@ -432,7 +446,6 @@ public List allDecoderBindings() { return bindings; } - public List allEncoderBindings() { ArrayList bindings = new ArrayList(8); bindings.addAll(fields); diff --git a/src/test/java/com/jsoniter/TestRecord.java b/src/test/java/com/jsoniter/TestRecord.java index 4ea8b92a..4320f60b 100644 --- a/src/test/java/com/jsoniter/TestRecord.java +++ b/src/test/java/com/jsoniter/TestRecord.java @@ -3,13 +3,62 @@ import junit.framework.TestCase; import java.io.IOException; +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.lang.reflect.Modifier; public class TestRecord extends TestCase { record TestRecord1(long field1) { + } + + public void test_print_record_reflection_info() { + + + Class clazz = TestRecord1.class; + + System.out.println("Record Constructors :"); + for (Constructor constructor : clazz.getConstructors()) { + System.out.println(constructor); + } + System.out.println("Record Methods : "); + for (Method method : clazz.getMethods()) { + System.out.println(method); + } + + System.out.println("Record Fields : "); + for (Field field : clazz.getFields()) { + System.out.println(field); + System.out.println(" modifiers : " + Modifier.toString(field.getModifiers())); + } + + System.out.println("Record Declared Fields : "); + for (Field field : clazz.getDeclaredFields()) { + System.out.println(field); + System.out.println(" modifiers : " + Modifier.toString(field.getModifiers())); + } + + try { + System.out.println("Record Default Declared Constructor : " + clazz.getDeclaredConstructor()); + } catch (Exception ex) { + System.err.println("No Record Default Declared Constructor!"); + } + + System.out.println("Record Declared Constructors : "); + for(Constructor constructor : clazz.getDeclaredConstructors()) { + System.out.println(constructor); + System.out.println(" name : " + constructor.getName()); + System.out.println(" modifiers : " + Modifier.toString(constructor.getModifiers())); + System.out.println(" input count : " + constructor.getParameterCount()); + System.out.println(" input types : "); + for (Class parameter : constructor.getParameterTypes()) + System.out.println(" " + parameter); + } } + public void test_record_error() throws IOException { JsonIterator iter = JsonIterator.parse("{ 'field1' : 1".replace('\'', '"')); From 092928db08f96080315524d78280a8c00625e68b Mon Sep 17 00:00:00 2001 From: xinmiao <> Date: Wed, 2 Mar 2022 16:46:55 +0100 Subject: [PATCH 2/3] test - empty record read --- src/test/java/com/jsoniter/SimpleRecord.java | 11 +++++++ src/test/java/com/jsoniter/TestRecord.java | 31 ++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/test/java/com/jsoniter/SimpleRecord.java diff --git a/src/test/java/com/jsoniter/SimpleRecord.java b/src/test/java/com/jsoniter/SimpleRecord.java new file mode 100644 index 00000000..7a740468 --- /dev/null +++ b/src/test/java/com/jsoniter/SimpleRecord.java @@ -0,0 +1,11 @@ +package com.jsoniter; + +public record SimpleRecord(String field1, String field2) { + public SimpleRecord() { + this(null, null); + } + public SimpleRecord(String field1, String field2) { + this.field1 = field1; + this.field2 = field2; + } +} \ No newline at end of file diff --git a/src/test/java/com/jsoniter/TestRecord.java b/src/test/java/com/jsoniter/TestRecord.java index 4320f60b..54d0ee01 100644 --- a/src/test/java/com/jsoniter/TestRecord.java +++ b/src/test/java/com/jsoniter/TestRecord.java @@ -1,5 +1,6 @@ package com.jsoniter; +import com.jsoniter.any.Any; import junit.framework.TestCase; import java.io.IOException; @@ -7,11 +8,19 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.util.Map; +import com.jsoniter.output.JsonStream; +import junit.framework.Test; public class TestRecord extends TestCase { record TestRecord1(long field1) { } + public record TestRecord0(Long id, String name) { + public TestRecord0() { + this(0L, ""); + } + } public void test_print_record_reflection_info() { @@ -57,11 +66,33 @@ public void test_print_record_reflection_info() { System.out.println(" " + parameter); } } + public void test_empty_record() throws IOException { + JsonIterator iter = JsonIterator.parse("{}"); + assertNotNull(iter.read(TestRecord0.class)); + } + public void test_empty_simple_record() throws IOException { + JsonIterator iter = JsonIterator.parse("{}"); + SimpleRecord simpleRecord = iter.read(SimpleRecord.class); + assertNull(simpleRecord.field1()); + iter.reset(iter.buf); + Object obj = iter.read(Object.class); + assertEquals(0, ((Map) obj).size()); + iter.reset(iter.buf); + Any any = iter.readAny(); + assertEquals(0, any.size()); + } + + public void test_one_field() throws IOException { + JsonIterator iter = JsonIterator.parse("{ 'field1'\r:\n\t'hello' }".replace('\'', '"')); + SimpleRecord simpleRecord = iter.read(SimpleRecord.class); + assertEquals("hello", simpleRecord.field1()); + } public void test_record_error() throws IOException { JsonIterator iter = JsonIterator.parse("{ 'field1' : 1".replace('\'', '"')); iter.read(TestRecord1.class); } + } From 20e4560c63098dfaae0d717529e1c4be3d9f8ca2 Mon Sep 17 00:00:00 2001 From: Maxou <5208681+mxyns@users.noreply.github.com> Date: Thu, 3 Mar 2022 19:59:31 +0100 Subject: [PATCH 3/3] test - tests showing different object decoder implementation use --- src/test/java/com/jsoniter/TestRecord.java | 34 ++++++++++++++++++---- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/src/test/java/com/jsoniter/TestRecord.java b/src/test/java/com/jsoniter/TestRecord.java index 4320f60b..c810f6a4 100644 --- a/src/test/java/com/jsoniter/TestRecord.java +++ b/src/test/java/com/jsoniter/TestRecord.java @@ -1,5 +1,8 @@ package com.jsoniter; +import com.jsoniter.annotation.JsonCreator; +import com.jsoniter.annotation.JsonProperty; +import com.jsoniter.spi.ClassInfo; import junit.framework.TestCase; import java.io.IOException; @@ -10,12 +13,10 @@ public class TestRecord extends TestCase { - record TestRecord1(long field1) { - } + record TestRecord1(long field1) {} public void test_print_record_reflection_info() { - Class clazz = TestRecord1.class; System.out.println("Record Constructors :"); @@ -58,10 +59,33 @@ public void test_print_record_reflection_info() { } } - public void test_record_error() throws IOException { - JsonIterator iter = JsonIterator.parse("{ 'field1' : 1".replace('\'', '"')); + JsonIterator iter = JsonIterator.parse("{ 'field1' : 1 }".replace('\'', '"')); + iter.read(TestRecord1.class); + } + + public void test_record_withOnlyFieldDecoder() throws IOException { + + assertEquals(ReflectionDecoderFactory.create(new ClassInfo(TestRecord1.class)).getClass(), ReflectionObjectDecoder.OnlyField.class); + + JsonIterator iter = JsonIterator.parse("{ 'field1' : 1 }".replace('\'', '"')); iter.read(TestRecord1.class); } + + public void test_record_withCtorDecoder() throws IOException { + + record TestRecord2(@JsonProperty long field1) { + + @JsonCreator + TestRecord2 {} + } + + assertEquals(ReflectionDecoderFactory.create(new ClassInfo(TestRecord2.class)).getClass(), ReflectionObjectDecoder.WithCtor.class); + + JsonIterator iter = JsonIterator.parse("{ 'field1' : 1 }".replace('\'', '"')); + TestRecord2 record = iter.read(TestRecord2.class); + + assertEquals(record.field1, 1); + } }