@@ -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