Skip to content

Commit 7ebbad4

Browse files
committed
handle name conflict
1 parent 4f74953 commit 7ebbad4

File tree

5 files changed

+115
-32
lines changed

5 files changed

+115
-32
lines changed

src/main/java/com/jsoniter/output/CodegenImplObject.java

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,24 @@ private static boolean hasFieldOutput(ClassDescriptor desc) {
4242
return false;
4343
}
4444

45-
private static String genField(Binding field) {
46-
String fieldCacheKey = field.encoderCacheKey();
45+
private static String genField(Binding binding) {
46+
String fieldCacheKey = binding.encoderCacheKey();
4747
Encoder encoder = JsoniterSpi.getEncoder(fieldCacheKey);
48-
if (encoder == null) {
49-
return CodegenImplNative.genWriteOp("obj." + field.name, field.valueType);
48+
if (binding.field != null) {
49+
if (encoder == null) {
50+
return CodegenImplNative.genWriteOp("obj." + binding.field.getName(), binding.valueType);
51+
} else {
52+
return String.format("com.jsoniter.output.CodegenAccess.writeVal(\"%s\", obj.%s, stream);",
53+
fieldCacheKey, binding.field.getName());
54+
}
55+
} else {
56+
if (encoder == null) {
57+
return CodegenImplNative.genWriteOp("obj." + binding.method.getName() + "()", binding.valueType);
58+
} else {
59+
return String.format("com.jsoniter.output.CodegenAccess.writeVal(\"%s\", obj.%s(), stream);",
60+
fieldCacheKey, binding.method.getName());
61+
}
5062
}
51-
return String.format("com.jsoniter.output.CodegenAccess.writeVal(\"%s\", obj.%s, stream);",
52-
fieldCacheKey, field.name);
5363
}
5464

5565
private static void append(StringBuilder lines, String str) {

src/main/java/com/jsoniter/spi/JsoniterSpi.java

Lines changed: 64 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ public static ClassDescriptor getEncodingClassDescriptor(Class clazz, boolean in
141141
for (Extension extension : extensions) {
142142
extension.updateClassDescriptor(desc);
143143
}
144-
// encodingDeduplicate(desc);
144+
encodingDeduplicate(desc);
145145
for (Binding binding : desc.allEncoderBindings()) {
146146
if (binding.toNames == null) {
147147
binding.toNames = new String[]{binding.name};
@@ -160,34 +160,74 @@ public static ClassDescriptor getEncodingClassDescriptor(Class clazz, boolean in
160160
}
161161

162162
private static void decodingDeduplicate(ClassDescriptor desc) {
163-
HashMap<String, Binding> fields = new HashMap<String, Binding>();
164-
165-
for (Binding field : new ArrayList<Binding>(desc.fields)) {
166-
if (fields.containsKey(field.name)) {
167-
// conflict
168-
if (field.method != null) {
169-
// this is method, prefer using it
170-
desc.fields.remove(fields.get(field.name));
171-
fields.put(field.name, field);
172-
} else {
173-
// this is not method, discard it
174-
desc.fields.remove(field);
175-
}
176-
} else {
177-
fields.put(field.name, field);
163+
HashMap<String, Binding> byName = new HashMap<String, Binding>();
164+
for (Binding field : desc.fields) {
165+
if (byName.containsKey(field.name)) {
166+
throw new JsonException("field name conflict: " + field.name);
167+
}
168+
byName.put(field.name, field);
169+
}
170+
for (Binding setter : desc.setters) {
171+
Binding existing = byName.get(setter.name);
172+
if (existing == null) {
173+
byName.put(setter.name, setter);
174+
continue;
175+
}
176+
if (desc.fields.remove(existing)) {
177+
continue;
178178
}
179+
throw new JsonException("setter name conflict: " + setter.name);
179180
}
180-
for (WrapperDescriptor setter : desc.wrappers) {
181-
for (Binding parameter : setter.parameters) {
182-
if (fields.containsKey(parameter.name)) {
183-
desc.fields.remove(fields.get(parameter.name));
181+
for (WrapperDescriptor wrapper : desc.wrappers) {
182+
for (Binding param : wrapper.parameters) {
183+
Binding existing = byName.get(param.name);
184+
if (existing == null) {
185+
byName.put(param.name, param);
186+
continue;
187+
}
188+
if (desc.fields.remove(existing)) {
189+
continue;
184190
}
191+
if (desc.setters.remove(existing)) {
192+
continue;
193+
}
194+
throw new JsonException("wrapper parameter name conflict: " + param.name);
185195
}
186196
}
187-
for (Binding parameter : desc.ctor.parameters) {
188-
if (fields.containsKey(parameter.name)) {
189-
desc.fields.remove(fields.get(parameter.name));
197+
for (Binding param : desc.ctor.parameters) {
198+
Binding existing = byName.get(param.name);
199+
if (existing == null) {
200+
byName.put(param.name, param);
201+
continue;
202+
}
203+
if (desc.fields.remove(existing)) {
204+
continue;
205+
}
206+
if (desc.setters.remove(existing)) {
207+
continue;
208+
}
209+
throw new JsonException("ctor parameter name conflict: " + param.name);
210+
}
211+
}
212+
213+
private static void encodingDeduplicate(ClassDescriptor desc) {
214+
HashMap<String, Binding> byName = new HashMap<String, Binding>();
215+
for (Binding field : desc.fields) {
216+
if (byName.containsKey(field.name)) {
217+
throw new JsonException("field name conflict: " + field.name);
218+
}
219+
byName.put(field.name, field);
220+
}
221+
for (Binding getter : desc.getters) {
222+
Binding existing = byName.get(getter.name);
223+
if (existing == null) {
224+
byName.put(getter.name, getter);
225+
continue;
226+
}
227+
if (desc.fields.remove(existing)) {
228+
continue;
190229
}
230+
throw new JsonException("getter name conflict: " + getter.name);
191231
}
192232
}
193233

@@ -313,7 +353,7 @@ private static List<Binding> getGetters(Map<String, Type> lookup, Class clazz, b
313353
toName = new String(fromNameChars);
314354
Binding getter = new Binding(clazz, lookup, method.getGenericReturnType());
315355
getter.toNames = new String[]{toName};
316-
getter.name = methodName + "()";
356+
getter.name = toName;
317357
getter.method = method;
318358
getters.add(getter);
319359
}

src/test/java/com/jsoniter/TestAnnotation.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,4 +249,22 @@ public void test_specify_property() throws IOException {
249249
assertEquals(Arrays.asList(100), obj.values);
250250
assertEquals(LinkedList.class, obj.values.getClass());
251251
}
252+
253+
public static class TestObject17 {
254+
public int field1;
255+
256+
public void setField1(int field1) {
257+
this.field1 = field1;
258+
}
259+
260+
@JsonCreator
261+
public void initialize(@JsonProperty("field1") int field1) {
262+
263+
}
264+
}
265+
266+
public void test_name_conflict() throws IOException {
267+
JsonIterator iter = JsonIterator.parse("{}");
268+
assertNotNull(iter.read(TestObject17.class));
269+
}
252270
}

src/test/java/com/jsoniter/TestGenerics.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -104,8 +104,8 @@ public void test_generic_super_class() throws IOException {
104104
put("field3", "decoder.java.util.List_java.lang.Integer_array");
105105
put("field4", "decoder.java.util.List_java.lang.String_array");
106106
put("field5", "decoder.java.lang.Float");
107-
put("getField6()", "decoder.java.util.List_java.util.Map_java.lang.String_java.util.List_java.lang.Integer");
108-
put("getField7()", "decoder.java.lang.Object");
107+
put("field6", "decoder.java.util.List_java.util.Map_java.lang.String_java.util.List_java.lang.Integer");
108+
put("field7", "decoder.java.lang.Object");
109109
put("field8", "decoder.java.util.List_java.lang.String");
110110
}}, fieldDecoderCacheKeys);
111111
}

src/test/java/com/jsoniter/output/TestAnnotation.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,19 @@ public void test_ignore() throws IOException {
6060
stream.close();
6161
assertEquals("{}", baos.toString());
6262
}
63+
64+
public static class TestObject4 {
65+
public int field1;
66+
67+
public int getField1() {
68+
return field1;
69+
}
70+
}
71+
72+
public void test_name_conflict() throws IOException {
73+
TestObject4 obj = new TestObject4();
74+
stream.writeVal(obj);
75+
stream.close();
76+
assertEquals("{\"field1\":0}", baos.toString());
77+
}
6378
}

0 commit comments

Comments
 (0)