Skip to content

Commit 86931fa

Browse files
committed
make slice support ctor and setter
1 parent 4fa95cd commit 86931fa

4 files changed

Lines changed: 51 additions & 17 deletions

File tree

src/main/java/com/jsoniter/Codegen.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,13 @@ private static String genSource(String cacheKey, Class clazz, Type[] typeArgs) {
7676
if (Collection.class.isAssignableFrom(clazz)) {
7777
return CodegenImplArray.genCollection(clazz, typeArgs);
7878
}
79+
CustomizedConstructor ctor = ExtensionManager.getCtor(clazz);
80+
List<CustomizedSetter> setters = ExtensionManager.getSetters(clazz);
81+
List<Binding> fields = ExtensionManager.getFields(clazz);
7982
if (strictMode) {
80-
return CodegenImplObject.genObjectUsingSlice(clazz, cacheKey);
83+
return CodegenImplObject.genObjectUsingSlice(clazz, cacheKey, ctor, setters, fields);
8184
} else {
82-
return CodegenImplObject.genObjectUsingHash(clazz, cacheKey);
85+
return CodegenImplObject.genObjectUsingHash(clazz, cacheKey, ctor, setters, fields);
8386
}
8487
}
8588

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

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,32 @@ class CodegenImplObject {
1515
put("long", "0");
1616
}};
1717

18-
public static String genObjectUsingSlice(Class clazz, String cacheKey) {
19-
Map<Integer, Object> trieTree = buildTriTree(clazz);
18+
public static String genObjectUsingSlice(Class clazz, String cacheKey, CustomizedConstructor ctor,
19+
List<CustomizedSetter> setters, List<Binding> fields) {
20+
ArrayList<Binding> allBindings = new ArrayList<Binding>(fields);
21+
allBindings.addAll(ctor.parameters);
22+
for (CustomizedSetter setter : setters) {
23+
allBindings.addAll(setter.parameters);
24+
}
25+
if (allBindings.isEmpty()) {
26+
return genObjectUsingSkip(clazz, ctor);
27+
}
28+
Map<Integer, Object> trieTree = buildTriTree(allBindings);
2029
StringBuilder lines = new StringBuilder();
2130
append(lines, "public static Object decode_(com.jsoniter.JsonIterator iter) {");
2231
append(lines, "if (iter.readNull()) { return null; }");
23-
append(lines, "{{clazz}} obj = {{newInst}};");
24-
append(lines, "if (!com.jsoniter.CodegenAccess.readObjectStart(iter)) { return obj; }");
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);
38+
}
39+
for (CustomizedSetter setter : setters) {
40+
for (Binding param : setter.parameters) {
41+
appendVarDef(lines, param);
42+
}
43+
}
2544
append(lines, "com.jsoniter.Slice field = com.jsoniter.CodegenAccess.readObjectFieldAsSlice(iter);");
2645
append(lines, "boolean once = true;");
2746
append(lines, "while (once) {");
@@ -50,17 +69,26 @@ public static String genObjectUsingSlice(Class clazz, String cacheKey) {
5069
append(lines, "}"); // end of switch
5170
append(lines, "iter.skip();");
5271
append(lines, "}"); // end of while
53-
// append(lines, "if (c != '}') { com.jsoniter.CodegenAccess.reportIncompleteObject(iter); }");
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");
81+
}
5482
append(lines, "return obj;");
5583
append(lines, "}");
5684
return lines.toString()
5785
.replace("{{clazz}}", clazz.getCanonicalName())
5886
.replace("{{newInst}}", genNewInstCode(clazz, ExtensionManager.getCtor(clazz)));
5987
}
6088

61-
private static Map<Integer, Object> buildTriTree(Class clazz) {
89+
private static Map<Integer, Object> buildTriTree(ArrayList<Binding> allBindings) {
6290
Map<Integer, Object> trieTree = new HashMap<Integer, Object>();
63-
for (Binding field : ExtensionManager.getFields(clazz)) {
91+
for (Binding field : allBindings) {
6492
for (String fromName : field.fromNames) {
6593
byte[] fromNameBytes = fromName.getBytes();
6694
Map<Byte, Object> current = (Map<Byte, Object>) trieTree.get(fromNameBytes.length);
@@ -94,7 +122,8 @@ private static void addFieldDispatch(StringBuilder lines, int len, int i, Map<By
94122
}
95123
append(lines, String.format("field.at(%d)==%s", i, b));
96124
append(lines, ") {");
97-
CodegenImplNative.genField((Binding) entry.getValue(), cacheKey);
125+
Binding field = (Binding) entry.getValue();
126+
append(lines, String.format("_%s_ = %s;", field.name, CodegenImplNative.genField(field, cacheKey)));
98127
append(lines, "continue;");
99128
append(lines, "}");
100129
continue;
@@ -119,10 +148,8 @@ private static void addFieldDispatch(StringBuilder lines, int len, int i, Map<By
119148
}
120149
}
121150

122-
public static String genObjectUsingHash(Class clazz, String cacheKey) {
123-
CustomizedConstructor ctor = ExtensionManager.getCtor(clazz);
124-
List<Binding> fields = ExtensionManager.getFields(clazz);
125-
List<CustomizedSetter> setters = ExtensionManager.getSetters(clazz);
151+
public static String genObjectUsingHash(Class clazz, String cacheKey, CustomizedConstructor ctor,
152+
List<CustomizedSetter> setters, List<Binding> fields) {
126153
ArrayList<Binding> allBindings = new ArrayList<Binding>(fields);
127154
allBindings.addAll(ctor.parameters);
128155
for (CustomizedSetter setter : setters) {
@@ -158,11 +185,11 @@ public static String genObjectUsingHash(Class clazz, String cacheKey) {
158185
int intHash = (int) hash;
159186
if (intHash == 0) {
160187
// hash collision, 0 can not be used as sentinel
161-
return genObjectUsingSlice(clazz, cacheKey);
188+
return genObjectUsingSlice(clazz, cacheKey, ctor, setters, fields);
162189
}
163190
if (knownHashes.contains(intHash)) {
164191
// hash collision with other field can not be used as sentinel
165-
return genObjectUsingSlice(clazz, cacheKey);
192+
return genObjectUsingSlice(clazz, cacheKey, ctor, setters, fields);
166193
}
167194
knownHashes.add(intHash);
168195
append(lines, "case " + intHash + ": ");

src/test/java/com/jsoniter/TestCustomizeCtor.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
public class TestCustomizeCtor extends TestCase {
1010

1111
static {
12-
JsonIterator.enableStrictMode();
12+
// JsonIterator.enableStrictMode();
1313
}
1414

1515
public static class OneArgCtor {

src/test/java/com/jsoniter/TestCustomizeSetter.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@
88

99
public class TestCustomizeSetter extends TestCase {
1010

11+
static {
12+
// JsonIterator.enableStrictMode();
13+
}
14+
1115
public static class ObjectWithDefaultSetter {
1216
String field;
1317

0 commit comments

Comments
 (0)