33import java .lang .reflect .*;
44import java .util .*;
55
6+ import static java .lang .reflect .Modifier .isTransient ;
7+
68public class ClassDescriptor {
79
810 public ClassInfo classInfo ;
@@ -30,10 +32,9 @@ public static ClassDescriptor getDecodingClassDescriptor(ClassInfo classInfo, bo
3032 desc .clazz = clazz ;
3133 desc .lookup = lookup ;
3234 desc .ctor = getCtor (clazz );
33- Map <String , Binding > allFields = getFields (lookup , classInfo , includingPrivate );
34- desc .setters = getSetters (lookup , classInfo , includingPrivate , allFields );
35+ desc .setters = getSetters (lookup , classInfo , includingPrivate );
3536 desc .getters = new ArrayList <Binding >();
36- desc .fields = omitTransient ( allFields );
37+ desc .fields = getFields ( lookup , classInfo , includingPrivate );
3738 desc .bindingTypeWrappers = new ArrayList <WrapperDescriptor >();
3839 desc .keyValueTypeWrappers = new ArrayList <Method >();
3940 desc .unwrappers = new ArrayList <UnwrapperDescriptor >();
@@ -86,9 +87,8 @@ public static ClassDescriptor getEncodingClassDescriptor(ClassInfo classInfo, bo
8687 desc .classInfo = classInfo ;
8788 desc .clazz = clazz ;
8889 desc .lookup = lookup ;
89- Map <String , Binding > allFields = getFields (lookup , classInfo , includingPrivate );
90- desc .getters = getGetters (lookup , classInfo , includingPrivate , allFields );
91- desc .fields = omitTransient (allFields );
90+ desc .fields = getFields (lookup , classInfo , includingPrivate );
91+ desc .getters = getGetters (lookup , classInfo , includingPrivate );
9292 desc .bindingTypeWrappers = new ArrayList <WrapperDescriptor >();
9393 desc .keyValueTypeWrappers = new ArrayList <Method >();
9494 desc .unwrappers = new ArrayList <UnwrapperDescriptor >();
@@ -113,16 +113,7 @@ public static ClassDescriptor getEncodingClassDescriptor(ClassInfo classInfo, bo
113113 return desc ;
114114 }
115115
116- private static List <Binding > omitTransient (Map <String , Binding > map ) {
117- List <Binding > out = new ArrayList <Binding >();
118- for (Binding binding : map .values ()) {
119- if (!binding .isTransient ) {
120- out .add (binding );
121- }
122- }
123- return out ;
124- }
125-
116+ // TODO: do not remove, set fromNames to []
126117 private static void decodingDeduplicate (ClassDescriptor desc ) {
127118 HashMap <String , Binding > byName = new HashMap <String , Binding >();
128119 for (Binding field : desc .fields ) {
@@ -190,6 +181,7 @@ private static void decodingDeduplicate(ClassDescriptor desc) {
190181 }
191182 }
192183
184+ // TODO: do not remove, set toNames to []
193185 private static void encodingDeduplicate (ClassDescriptor desc ) {
194186 HashMap <String , Binding > byName = new HashMap <String , Binding >();
195187 for (Binding field : desc .fields ) {
@@ -200,7 +192,6 @@ private static void encodingDeduplicate(ClassDescriptor desc) {
200192 byName .put (toName , field );
201193 }
202194 }
203-
204195 for (Binding getter : new ArrayList <Binding >(desc .getters )) {
205196 for (String toName : getter .toNames ) {
206197 Binding existing = byName .get (toName );
@@ -235,8 +226,8 @@ private static ConstructorDescriptor getCtor(Class clazz) {
235226 return cctor ;
236227 }
237228
238- private static Map < String , Binding > getFields (Map <String , Type > lookup , ClassInfo classInfo , boolean includingPrivate ) {
239- Map < String , Binding > output = new LinkedHashMap < String , Binding >();// To ensure fields order
229+ private static List < Binding > getFields (Map <String , Type > lookup , ClassInfo classInfo , boolean includingPrivate ) {
230+ ArrayList < Binding > bindings = new ArrayList < Binding >();
240231 for (Field field : getAllFields (classInfo .clazz , includingPrivate )) {
241232 if (Modifier .isStatic (field .getModifiers ())) {
242233 continue ;
@@ -247,21 +238,24 @@ private static Map<String, Binding> getFields(Map<String, Type> lookup, ClassInf
247238 if (includingPrivate ) {
248239 field .setAccessible (true );
249240 }
250- Binding binding = createBindingFromField (lookup , classInfo , field , Modifier .isTransient (field .getModifiers ()));
251- output .put (binding .name , binding );
241+ Binding binding = createBindingFromField (lookup , classInfo , field );
242+ if (isTransient (field .getModifiers ())) {
243+ binding .toNames = new String [0 ];
244+ binding .fromNames = new String [0 ];
245+ }
246+ bindings .add (binding );
252247 }
253- return output ;
248+ return bindings ;
254249 }
255250
256- private static Binding createBindingFromField (Map <String , Type > lookup , ClassInfo classInfo , Field field , boolean isTransient ) {
251+ private static Binding createBindingFromField (Map <String , Type > lookup , ClassInfo classInfo , Field field ) {
257252 try {
258253 Binding binding = new Binding (classInfo , lookup , field .getGenericType ());
259254 binding .fromNames = new String []{field .getName ()};
260255 binding .toNames = new String []{field .getName ()};
261256 binding .name = field .getName ();
262257 binding .annotations = field .getAnnotations ();
263258 binding .field = field ;
264- binding .isTransient = isTransient ;
265259 return binding ;
266260 } catch (Exception e ) {
267261 throw new JsonException ("failed to create binding for field: " + field , e );
@@ -281,7 +275,7 @@ private static List<Field> getAllFields(Class clazz, boolean includingPrivate) {
281275 return allFields ;
282276 }
283277
284- private static List <Binding > getSetters (Map <String , Type > lookup , ClassInfo classInfo , boolean includingPrivate , Map < String , Binding > allFields ) {
278+ private static List <Binding > getSetters (Map <String , Type > lookup , ClassInfo classInfo , boolean includingPrivate ) {
285279 ArrayList <Binding > setters = new ArrayList <Binding >();
286280 for (Method method : getAllMethods (classInfo .clazz , includingPrivate )) {
287281 if (Modifier .isStatic (method .getModifiers ())) {
@@ -306,9 +300,14 @@ private static List<Binding> getSetters(Map<String, Type> lookup, ClassInfo clas
306300 }
307301 try {
308302 String fromName = translateSetterName (methodName );
309- Binding field = allFields .get (fromName );
303+ Field field = null ;
304+ try {
305+ field = method .getDeclaringClass ().getDeclaredField (fromName );
306+ } catch (NoSuchFieldException e ) {
307+ // ignore
308+ }
310309 Binding setter = new Binding (classInfo , lookup , paramTypes [0 ]);
311- if (!( field == null ) && field .isTransient ) {
310+ if (field != null && isTransient ( field .getModifiers ()) ) {
312311 setter .fromNames = new String [0 ];
313312 } else {
314313 setter .fromNames = new String []{fromName };
@@ -348,7 +347,7 @@ private static String translateSetterName(String methodName) {
348347 return fromName ;
349348 }
350349
351- private static List <Binding > getGetters (Map <String , Type > lookup , ClassInfo classInfo , boolean includingPrivate , Map < String , Binding > allFields ) {
350+ private static List <Binding > getGetters (Map <String , Type > lookup , ClassInfo classInfo , boolean includingPrivate ) {
352351 ArrayList <Binding > getters = new ArrayList <Binding >();
353352 for (Method method : getAllMethods (classInfo .clazz , includingPrivate )) {
354353 if (Modifier .isStatic (method .getModifiers ())) {
@@ -368,12 +367,17 @@ private static List<Binding> getGetters(Map<String, Type> lookup, ClassInfo clas
368367 continue ;
369368 }
370369 String toName = methodName .substring ("get" .length ());
371- char [] fromNameChars = toName .toCharArray ();
372- fromNameChars [0 ] = Character .toLowerCase (fromNameChars [0 ]);
373- toName = new String (fromNameChars );
370+ char [] toNameChars = toName .toCharArray ();
371+ toNameChars [0 ] = Character .toLowerCase (toNameChars [0 ]);
372+ toName = new String (toNameChars );
374373 Binding getter = new Binding (classInfo , lookup , method .getGenericReturnType ());
375- Binding field = allFields .get (toName );
376- if (!(field == null ) && field .isTransient ) {
374+ Field field = null ;
375+ try {
376+ field = method .getDeclaringClass ().getDeclaredField (toName );
377+ } catch (NoSuchFieldException e ) {
378+ // ignore
379+ }
380+ if (field != null && isTransient (field .getModifiers ())) {
377381 getter .toNames = new String [0 ];
378382 } else {
379383 getter .toNames = new String []{toName };
0 commit comments