(final @NotNull Json json, final @NotNull Class<T> klass)
| 254 | } |
| 255 | |
| 256 | ClassMeta(final @NotNull Json json, final @NotNull Class<T> klass) { |
| 257 | this.json = json; |
| 258 | this.klass = klass; |
| 259 | ctor = getDefCtor(klass); |
| 260 | int size = 0; |
| 261 | for (Class<?> c = klass; c != null; c = c.getSuperclass()) |
| 262 | for (Field field : getDeclaredFields(c)) |
| 263 | if ((field.getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) == 0 |
| 264 | && !field.getName().startsWith("this$")) |
| 265 | size++; |
| 266 | valueTable = new FieldMeta[1 << (32 - Integer.numberOfLeadingZeros(size * 2 - 1))]; |
| 267 | fieldMetas = new FieldMeta[size]; |
| 268 | ArrayList<Class<? super T>> classes = new ArrayList<>(2); |
| 269 | for (Class<? super T> c = klass; c != null; c = c.getSuperclass()) |
| 270 | classes.add(c); |
| 271 | for (int i = classes.size() - 1, j = 0; i >= 0; i--) { |
| 272 | Class<? super T> c = classes.get(i); |
| 273 | for (Field field : getDeclaredFields(c)) { |
| 274 | if ((field.getModifiers() & (Modifier.STATIC | Modifier.TRANSIENT)) != 0) |
| 275 | continue; |
| 276 | final String fieldName = field.getName(); |
| 277 | if (fieldName.startsWith("this$")) // closure field |
| 278 | continue; |
| 279 | Class<?> fieldClass = ensureNotNull(field.getType()); |
| 280 | Creator<?> fieldCtor = null; |
| 281 | KeyReader keyReader = null; |
| 282 | Integer v = typeMap.get(fieldClass); |
| 283 | int type; |
| 284 | if (v != null) |
| 285 | type = v; |
| 286 | else if (Collection.class.isAssignableFrom(fieldClass)) { // Collection<?> |
| 287 | if (!isAbstract(fieldClass)) |
| 288 | fieldCtor = getDefCtor(fieldClass); |
| 289 | else if (fieldClass.isAssignableFrom(ArrayList.class)) // AbstractList,AbstractCollection,List,Collection |
| 290 | fieldCtor = getDefCtor(ArrayList.class); |
| 291 | else if (fieldClass.isAssignableFrom(HashSet.class)) // AbstractSet,Set |
| 292 | fieldCtor = getDefCtor(HashSet.class); |
| 293 | else if (fieldClass.isAssignableFrom(ArrayDeque.class)) // Deque |
| 294 | fieldCtor = getDefCtor(ArrayDeque.class); |
| 295 | else if (fieldClass.isAssignableFrom(TreeSet.class)) // NavigableSet |
| 296 | fieldCtor = getDefCtor(TreeSet.class); |
| 297 | else if (fieldClass.isAssignableFrom(LinkedList.class)) // AbstractSequentialList |
| 298 | fieldCtor = getDefCtor(LinkedList.class); |
| 299 | else if (fieldClass.isAssignableFrom(PriorityQueue.class)) // AbstractQueue |
| 300 | fieldCtor = getDefCtor(PriorityQueue.class); |
| 301 | Class<?> subClass = getCollectionSubClass(field.getGenericType()); |
| 302 | if (subClass != null) { |
| 303 | v = typeMap.get(fieldClass = subClass); |
| 304 | type = TYPE_LIST_FLAG + (v != null ? v & 0xf : TYPE_CUSTOM); |
| 305 | } else |
| 306 | type = TYPE_LIST_FLAG + TYPE_OBJECT; |
| 307 | } else if (Map.class.isAssignableFrom(fieldClass)) { // Map<?,?> |
| 308 | if (!isAbstract(fieldClass)) |
| 309 | fieldCtor = getDefCtor(fieldClass); |
| 310 | else if (fieldClass.isAssignableFrom(HashMap.class)) // AbstractMap,Map |
| 311 | fieldCtor = getDefCtor(HashMap.class); |
| 312 | else if (fieldClass.isAssignableFrom(TreeMap.class)) // NavigableMap,SortedMap |
| 313 | fieldCtor = getDefCtor(TreeMap.class); |
nothing calls this directly
no test coverage detected