Skip to content

Commit f74450c

Browse files
committed
generate simpler code for class with default ctor
1 parent 15fe781 commit f74450c

1 file changed

Lines changed: 73 additions & 45 deletions

File tree

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

Lines changed: 73 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,17 @@ public static String genObjectUsingSlice(Class clazz, String cacheKey, Customize
2929
StringBuilder lines = new StringBuilder();
3030
append(lines, "public static Object decode_(com.jsoniter.JsonIterator iter) {");
3131
append(lines, "if (iter.readNull()) { return null; }");
32-
for (Binding parameter : ctor.parameters) {
33-
appendVarDef(lines, parameter);
34-
}
35-
append(lines, "if (!com.jsoniter.CodegenAccess.readObjectStart(iter)) { return {{newInst}}; }");
36-
for (Binding field : fields) {
37-
appendVarDef(lines, field);
32+
if (ctor.parameters.isEmpty()) {
33+
append(lines, "{{clazz}} obj = {{newInst}};");
34+
append(lines, "if (!com.jsoniter.CodegenAccess.readObjectStart(iter)) { return obj; }");
35+
} else {
36+
for (Binding parameter : ctor.parameters) {
37+
appendVarDef(lines, parameter);
38+
}
39+
append(lines, "if (!com.jsoniter.CodegenAccess.readObjectStart(iter)) { return {{newInst}}; }");
40+
for (Binding field : fields) {
41+
appendVarDef(lines, field);
42+
}
3843
}
3944
for (CustomizedSetter setter : setters) {
4045
for (Binding param : setter.parameters) {
@@ -46,46 +51,47 @@ public static String genObjectUsingSlice(Class clazz, String cacheKey, Customize
4651
append(lines, "while (once) {");
4752
append(lines, "once = false;");
4853
append(lines, "switch (field.len) {");
49-
for (Map.Entry<Integer, Object> entry : trieTree.entrySet()) {
50-
Integer len = entry.getKey();
51-
append(lines, "case " + len + ": ");
52-
Map<Byte, Object> current = (Map<Byte, Object>) entry.getValue();
53-
addFieldDispatch(lines, len, 0, current, cacheKey, new ArrayList<Byte>());
54-
append(lines, "break;");
54+
String rendered = renderTriTree(cacheKey, trieTree);
55+
for (Binding field : fields) {
56+
rendered = rendered.replace("_" + field.name + "_", "obj." + field.name);
5557
}
58+
append(lines, rendered);
5659
append(lines, "}"); // end of switch
5760
append(lines, "iter.skip();");
5861
append(lines, "}"); // end of while
5962
append(lines, "while (com.jsoniter.CodegenAccess.nextToken(iter) == ',') {");
6063
append(lines, "field = com.jsoniter.CodegenAccess.readObjectFieldAsSlice(iter);");
6164
append(lines, "switch (field.len) {");
62-
for (Map.Entry<Integer, Object> entry : trieTree.entrySet()) {
63-
Integer len = entry.getKey();
64-
append(lines, "case " + len + ": ");
65-
Map<Byte, Object> current = (Map<Byte, Object>) entry.getValue();
66-
addFieldDispatch(lines, len, 0, current, cacheKey, new ArrayList<Byte>());
67-
append(lines, "break;");
68-
}
65+
append(lines, rendered);
6966
append(lines, "}"); // end of switch
7067
append(lines, "iter.skip();");
7168
append(lines, "}"); // end of while
72-
append(lines, String.format("%s obj = {{newInst}};", CodegenImplNative.getTypeName(clazz)));
73-
for (Binding field : fields) {
74-
append(lines, String.format("obj.%s = _%s_;", field.name, field.name));
75-
}
76-
for (CustomizedSetter setter : setters) {
77-
lines.append("obj.");
78-
lines.append(setter.methodName);
79-
appendInvocation(lines, setter.parameters);
80-
lines.append(";\n");
69+
if (!ctor.parameters.isEmpty()) {
70+
append(lines, String.format("%s obj = {{newInst}};", CodegenImplNative.getTypeName(clazz)));
71+
for (Binding field : fields) {
72+
append(lines, String.format("obj.%s = _%s_;", field.name, field.name));
73+
}
8174
}
75+
appendSetter(setters, lines);
8276
append(lines, "return obj;");
8377
append(lines, "}");
8478
return lines.toString()
8579
.replace("{{clazz}}", clazz.getCanonicalName())
8680
.replace("{{newInst}}", genNewInstCode(clazz, ExtensionManager.getCtor(clazz)));
8781
}
8882

83+
private static String renderTriTree(String cacheKey, Map<Integer, Object> trieTree) {
84+
StringBuilder switchBody = new StringBuilder();
85+
for (Map.Entry<Integer, Object> entry : trieTree.entrySet()) {
86+
Integer len = entry.getKey();
87+
append(switchBody, "case " + len + ": ");
88+
Map<Byte, Object> current = (Map<Byte, Object>) entry.getValue();
89+
addFieldDispatch(switchBody, len, 0, current, cacheKey, new ArrayList<Byte>());
90+
append(switchBody, "break;");
91+
}
92+
return switchBody.toString();
93+
}
94+
8995
private static Map<Integer, Object> buildTriTree(ArrayList<Binding> allBindings) {
9096
Map<Integer, Object> trieTree = new HashMap<Integer, Object>();
9197
for (Binding field : allBindings) {
@@ -111,7 +117,8 @@ private static Map<Integer, Object> buildTriTree(ArrayList<Binding> allBindings)
111117
return trieTree;
112118
}
113119

114-
private static void addFieldDispatch(StringBuilder lines, int len, int i, Map<Byte, Object> current, String cacheKey, List<Byte> bytesToCompare) {
120+
private static void addFieldDispatch(
121+
StringBuilder lines, int len, int i, Map<Byte, Object> current, String cacheKey, List<Byte> bytesToCompare) {
115122
for (Map.Entry<Byte, Object> entry : current.entrySet()) {
116123
Byte b = entry.getKey();
117124
if (i == len - 1) {
@@ -161,12 +168,19 @@ public static String genObjectUsingHash(Class clazz, String cacheKey, Customized
161168
StringBuilder lines = new StringBuilder();
162169
append(lines, "public static Object decode_(com.jsoniter.JsonIterator iter) {");
163170
append(lines, "if (iter.readNull()) { return null; }");
164-
for (Binding parameter : ctor.parameters) {
165-
appendVarDef(lines, parameter);
166-
}
167-
append(lines, "if (!com.jsoniter.CodegenAccess.readObjectStart(iter)) { return {{newInst}}; }");
168-
for (Binding field : fields) {
169-
appendVarDef(lines, field);
171+
if (ctor.parameters.isEmpty()) {
172+
// has default ctor
173+
append(lines, "{{clazz}} obj = {{newInst}};");
174+
append(lines, "if (!com.jsoniter.CodegenAccess.readObjectStart(iter)) { return obj; }");
175+
} else {
176+
// ctor requires binding
177+
for (Binding parameter : ctor.parameters) {
178+
appendVarDef(lines, parameter);
179+
}
180+
append(lines, "if (!com.jsoniter.CodegenAccess.readObjectStart(iter)) { return {{newInst}}; }");
181+
for (Binding field : fields) {
182+
appendVarDef(lines, field);
183+
}
170184
}
171185
for (CustomizedSetter setter : setters) {
172186
for (Binding param : setter.parameters) {
@@ -193,7 +207,11 @@ public static String genObjectUsingHash(Class clazz, String cacheKey, Customized
193207
}
194208
knownHashes.add(intHash);
195209
append(lines, "case " + intHash + ": ");
196-
append(lines, String.format("_%s_ = %s;", field.name, CodegenImplNative.genField(field, cacheKey)));
210+
if (ctor.parameters.isEmpty() && fields.contains(field)) {
211+
append(lines, String.format("obj.%s = %s;", field.name, CodegenImplNative.genField(field, cacheKey)));
212+
} else {
213+
append(lines, String.format("_%s_ = %s;", field.name, CodegenImplNative.genField(field, cacheKey)));
214+
}
197215
append(lines, "break;");
198216
}
199217
}
@@ -211,28 +229,38 @@ public static String genObjectUsingHash(Class clazz, String cacheKey, Customized
211229
}
212230
int intHash = (int) hash;
213231
append(lines, "case " + intHash + ": ");
214-
append(lines, String.format("_%s_ = %s;", field.name, CodegenImplNative.genField(field, cacheKey)));
232+
if (ctor.parameters.isEmpty() && fields.contains(field)) {
233+
append(lines, String.format("obj.%s = %s;", field.name, CodegenImplNative.genField(field, cacheKey)));
234+
} else {
235+
append(lines, String.format("_%s_ = %s;", field.name, CodegenImplNative.genField(field, cacheKey)));
236+
}
215237
append(lines, "continue;");
216238
}
217239
}
218240
append(lines, "}");
219241
append(lines, "iter.skip();");
220242
append(lines, "}");
221-
append(lines, CodegenImplNative.getTypeName(clazz) + " obj = {{newInst}};");
222-
for (Binding field : fields) {
223-
append(lines, String.format("obj.%s = _%s_;", field.name, field.name));
243+
if (!ctor.parameters.isEmpty()) {
244+
append(lines, CodegenImplNative.getTypeName(clazz) + " obj = {{newInst}};");
245+
for (Binding field : fields) {
246+
append(lines, String.format("obj.%s = _%s_;", field.name, field.name));
247+
}
224248
}
249+
appendSetter(setters, lines);
250+
append(lines, "return obj;");
251+
append(lines, "}");
252+
return lines.toString()
253+
.replace("{{clazz}}", clazz.getCanonicalName())
254+
.replace("{{newInst}}", genNewInstCode(clazz, ctor));
255+
}
256+
257+
private static void appendSetter(List<CustomizedSetter> setters, StringBuilder lines) {
225258
for (CustomizedSetter setter : setters) {
226259
lines.append("obj.");
227260
lines.append(setter.methodName);
228261
appendInvocation(lines, setter.parameters);
229262
lines.append(";\n");
230263
}
231-
append(lines, "return obj;");
232-
append(lines, "}");
233-
return lines.toString()
234-
.replace("{{clazz}}", clazz.getCanonicalName())
235-
.replace("{{newInst}}", genNewInstCode(clazz, ctor));
236264
}
237265

238266
private static void appendVarDef(StringBuilder lines, Binding parameter) {

0 commit comments

Comments
 (0)