@@ -307,9 +307,12 @@ public static final class Struct {
307
307
public final Map <String , Field > staticMembers ;
308
308
public final Map <String , Field > members ;
309
309
310
- private final SetOnce <Method > functionalMethod ;
310
+ public final Map <String , MethodHandle > getters ;
311
+ public final Map <String , MethodHandle > setters ;
312
+
313
+ public final Method functionalMethod ;
311
314
312
- private Struct (final String name , final Class <?> clazz , final org .objectweb .asm .Type type ) {
315
+ private Struct (String name , Class <?> clazz , org .objectweb .asm .Type type ) {
313
316
this .name = name ;
314
317
this .clazz = clazz ;
315
318
this .type = type ;
@@ -321,10 +324,13 @@ private Struct(final String name, final Class<?> clazz, final org.objectweb.asm.
321
324
staticMembers = new HashMap <>();
322
325
members = new HashMap <>();
323
326
324
- functionalMethod = new SetOnce <>();
327
+ getters = new HashMap <>();
328
+ setters = new HashMap <>();
329
+
330
+ functionalMethod = null ;
325
331
}
326
332
327
- private Struct (final Struct struct ) {
333
+ private Struct (Struct struct , Method functionalMethod ) {
328
334
name = struct .name ;
329
335
clazz = struct .clazz ;
330
336
type = struct .type ;
@@ -336,11 +342,14 @@ private Struct(final Struct struct) {
336
342
staticMembers = Collections .unmodifiableMap (struct .staticMembers );
337
343
members = Collections .unmodifiableMap (struct .members );
338
344
339
- functionalMethod = struct .functionalMethod ;
345
+ getters = Collections .unmodifiableMap (struct .getters );
346
+ setters = Collections .unmodifiableMap (struct .setters );
347
+
348
+ this .functionalMethod = functionalMethod ;
340
349
}
341
350
342
- private Struct freeze () {
343
- return new Struct (this );
351
+ private Struct freeze (Method functionalMethod ) {
352
+ return new Struct (this , functionalMethod );
344
353
}
345
354
346
355
@ Override
@@ -362,14 +371,6 @@ public boolean equals(Object object) {
362
371
public int hashCode () {
363
372
return name .hashCode ();
364
373
}
365
-
366
- /**
367
- * If this class is a functional interface according to JLS, returns its method.
368
- * Otherwise returns null.
369
- */
370
- public Method getFunctionalMethod () {
371
- return functionalMethod .get ();
372
- }
373
374
}
374
375
375
376
public static class Cast {
@@ -418,25 +419,6 @@ private Cast(Class<?> from, Class<?> to, boolean explicit, Class<?> unboxFrom, C
418
419
}
419
420
}
420
421
421
- public static final class RuntimeClass {
422
- private final Struct struct ;
423
- public final Map <MethodKey , Method > methods ;
424
- public final Map <String , MethodHandle > getters ;
425
- public final Map <String , MethodHandle > setters ;
426
-
427
- private RuntimeClass (final Struct struct , final Map <MethodKey , Method > methods ,
428
- final Map <String , MethodHandle > getters , final Map <String , MethodHandle > setters ) {
429
- this .struct = struct ;
430
- this .methods = Collections .unmodifiableMap (methods );
431
- this .getters = Collections .unmodifiableMap (getters );
432
- this .setters = Collections .unmodifiableMap (setters );
433
- }
434
-
435
- public Struct getStruct () {
436
- return struct ;
437
- }
438
- }
439
-
440
422
/** Returns whether or not a non-array type exists. */
441
423
public boolean isSimpleType (final String name ) {
442
424
return structsMap .containsKey (name );
@@ -569,7 +551,9 @@ public static Class<?> defClassToObjectClass(Class<?> clazz) {
569
551
}
570
552
571
553
public static String ClassToName (Class <?> clazz ) {
572
- if (clazz .isArray ()) {
554
+ if (clazz .isLocalClass () || clazz .isAnonymousClass ()) {
555
+ return null ;
556
+ } else if (clazz .isArray ()) {
573
557
Class <?> component = clazz .getComponentType ();
574
558
int dimensions = 1 ;
575
559
@@ -609,7 +593,7 @@ public Type ClassToType(Class<?> clazz) {
609
593
if (component == def .class ) {
610
594
return getType (structsMap .get (def .class .getSimpleName ()), dimensions );
611
595
} else {
612
- return getType (runtimeMap .get (component ). struct , dimensions );
596
+ return getType (structsMap .get (ClassToName ( component )) , dimensions );
613
597
}
614
598
} else if (clazz == def .class ) {
615
599
return getType (structsMap .get (def .class .getSimpleName ()), 0 );
@@ -618,6 +602,10 @@ public Type ClassToType(Class<?> clazz) {
618
602
return getType (structsMap .get (ClassToName (clazz )), 0 );
619
603
}
620
604
605
+ public Struct RuntimeClassToStruct (Class <?> clazz ) {
606
+ return structsMap .get (ClassToName (clazz ));
607
+ }
608
+
621
609
public static Class <?> TypeToClass (Type type ) {
622
610
if (def .class .getSimpleName ().equals (type .struct .name )) {
623
611
return ObjectClassTodefClass (type .clazz );
@@ -626,10 +614,6 @@ public static Class<?> TypeToClass(Type type) {
626
614
return type .clazz ;
627
615
}
628
616
629
- public RuntimeClass getRuntimeClass (Class <?> clazz ) {
630
- return runtimeMap .get (clazz );
631
- }
632
-
633
617
public Class <?> getClassFromBinaryName (String name ) {
634
618
Struct struct = structsMap .get (name .replace ('$' , '.' ));
635
619
@@ -659,14 +643,12 @@ private static String buildFieldCacheKey(String structName, String fieldName, St
659
643
660
644
// INTERNAL IMPLEMENTATION:
661
645
662
- private final Map <Class <?>, RuntimeClass > runtimeMap ;
663
646
private final Map <String , Struct > structsMap ;
664
647
private final Map <String , Type > simpleTypesMap ;
665
648
666
649
public Definition (List <Whitelist > whitelists ) {
667
650
structsMap = new HashMap <>();
668
651
simpleTypesMap = new HashMap <>();
669
- runtimeMap = new HashMap <>();
670
652
671
653
Map <Class <?>, Struct > javaClassesToPainlessStructs = new HashMap <>();
672
654
String origin = null ;
@@ -787,17 +769,6 @@ public Definition(List<Whitelist> whitelists) {
787
769
}
788
770
}
789
771
790
- // mark functional interfaces (or set null, to mark class is not)
791
- for (String painlessStructName : structsMap .keySet ()) {
792
- Struct painlessStruct = structsMap .get (painlessStructName );
793
-
794
- if (painlessStruct .name .equals (painlessStructName ) == false ) {
795
- continue ;
796
- }
797
-
798
- painlessStruct .functionalMethod .set (computeFunctionalInterfaceMethod (painlessStruct ));
799
- }
800
-
801
772
// precompute runtime classes
802
773
for (String painlessStructName : structsMap .keySet ()) {
803
774
Struct painlessStruct = structsMap .get (painlessStructName );
@@ -815,7 +786,7 @@ public Definition(List<Whitelist> whitelists) {
815
786
continue ;
816
787
}
817
788
818
- entry .setValue (entry .getValue ().freeze ());
789
+ entry .setValue (entry .getValue ().freeze (computeFunctionalInterfaceMethod ( entry . getValue ()) ));
819
790
}
820
791
821
792
voidType = getType ("void" );
@@ -1272,51 +1243,45 @@ private void copyStruct(String struct, List<String> children) {
1272
1243
* Precomputes a more efficient structure for dynamic method/field access.
1273
1244
*/
1274
1245
private void addRuntimeClass (final Struct struct ) {
1275
- final Map <MethodKey , Method > methods = struct .methods ;
1276
- final Map <String , MethodHandle > getters = new HashMap <>();
1277
- final Map <String , MethodHandle > setters = new HashMap <>();
1278
-
1279
- // add all members
1280
- for (final Map .Entry <String , Field > member : struct .members .entrySet ()) {
1281
- getters .put (member .getKey (), member .getValue ().getter );
1282
- setters .put (member .getKey (), member .getValue ().setter );
1283
- }
1284
-
1285
1246
// add all getters/setters
1286
- for (final Map .Entry <MethodKey , Method > method : methods .entrySet ()) {
1287
- final String name = method .getKey ().name ;
1288
- final Method m = method .getValue ();
1247
+ for (Map .Entry <MethodKey , Method > method : struct . methods .entrySet ()) {
1248
+ String name = method .getKey ().name ;
1249
+ Method m = method .getValue ();
1289
1250
1290
1251
if (m .arguments .size () == 0 &&
1291
1252
name .startsWith ("get" ) &&
1292
1253
name .length () > 3 &&
1293
1254
Character .isUpperCase (name .charAt (3 ))) {
1294
- final StringBuilder newName = new StringBuilder ();
1255
+ StringBuilder newName = new StringBuilder ();
1295
1256
newName .append (Character .toLowerCase (name .charAt (3 )));
1296
1257
newName .append (name .substring (4 ));
1297
- getters .putIfAbsent (newName .toString (), m .handle );
1258
+ struct . getters .putIfAbsent (newName .toString (), m .handle );
1298
1259
} else if (m .arguments .size () == 0 &&
1299
1260
name .startsWith ("is" ) &&
1300
1261
name .length () > 2 &&
1301
1262
Character .isUpperCase (name .charAt (2 ))) {
1302
- final StringBuilder newName = new StringBuilder ();
1263
+ StringBuilder newName = new StringBuilder ();
1303
1264
newName .append (Character .toLowerCase (name .charAt (2 )));
1304
1265
newName .append (name .substring (3 ));
1305
- getters .putIfAbsent (newName .toString (), m .handle );
1266
+ struct . getters .putIfAbsent (newName .toString (), m .handle );
1306
1267
}
1307
1268
1308
1269
if (m .arguments .size () == 1 &&
1309
1270
name .startsWith ("set" ) &&
1310
1271
name .length () > 3 &&
1311
1272
Character .isUpperCase (name .charAt (3 ))) {
1312
- final StringBuilder newName = new StringBuilder ();
1273
+ StringBuilder newName = new StringBuilder ();
1313
1274
newName .append (Character .toLowerCase (name .charAt (3 )));
1314
1275
newName .append (name .substring (4 ));
1315
- setters .putIfAbsent (newName .toString (), m .handle );
1276
+ struct . setters .putIfAbsent (newName .toString (), m .handle );
1316
1277
}
1317
1278
}
1318
1279
1319
- runtimeMap .put (struct .clazz , new RuntimeClass (struct , methods , getters , setters ));
1280
+ // add all members
1281
+ for (Map .Entry <String , Field > member : struct .members .entrySet ()) {
1282
+ struct .getters .put (member .getKey (), member .getValue ().getter );
1283
+ struct .setters .put (member .getKey (), member .getValue ().setter );
1284
+ }
1320
1285
}
1321
1286
1322
1287
/** computes the functional interface method for a class, or returns null */
0 commit comments