2626import org .objectweb .asm .ClassReader ;
2727import org .objectweb .asm .ClassWriter ;
2828import org .objectweb .asm .Opcodes ;
29+ import org .objectweb .asm .Type ;
2930import org .objectweb .asm .commons .SerialVersionUIDAdder ;
3031import org .objectweb .asm .tree .ClassNode ;
3132import org .objectweb .asm .util .CheckClassAdapter ;
3233
33- import edu .columbia .cs .psl .chroniclerj .analysis .MutabilityAnalyzer ;
3434import edu .columbia .cs .psl .chroniclerj .struct .AnnotatedMethod ;
3535import edu .columbia .cs .psl .chroniclerj .visitor .CallbackDuplicatingClassVisitor ;
3636import edu .columbia .cs .psl .chroniclerj .visitor .NonDeterministicLoggingClassVisitor ;
@@ -40,14 +40,6 @@ public class Instrumenter {
4040
4141 private static Logger logger = Logger .getLogger (Instrumenter .class );
4242
43- public static HashMap <String , AnnotatedMethod > annotatedMethods = new HashMap <String , AnnotatedMethod >();
44-
45- public static HashMap <String , ClassNode > instrumentedClasses = new HashMap <String , ClassNode >();
46-
47- private static MutabilityAnalyzer ma = new MutabilityAnalyzer (annotatedMethods );
48-
49- public static HashMap <String , HashSet <MethodCall >> methodCalls = new HashMap <String , HashSet <MethodCall >>();
50-
5143 private static final int NUM_PASSES = 2 ;
5244
5345 private static final int PASS_ANALYZE = 0 ;
@@ -66,36 +58,13 @@ public class Instrumenter {
6658
6759 private static String lastInstrumentedClass ;
6860
69- public static String getParentType (String type ) {
70- final ClassNode cn = instrumentedClasses .get (type );
71- if (cn == null )
72- return null ;
73- return cn .superName ;
74- }
75-
76- public static AnnotatedMethod getAnnotatedMethod (String owner , String name , String desc ) {
77- String lookupKey = owner + "." + name + ":" + desc ;
78- return annotatedMethods .get (lookupKey );
79- }
80-
8161 private static void analyzeClass (InputStream inputStream ) {
82- try {
83- ClassNode analysisResult = ma .analyzeClass (new ClassReader (inputStream ));
84- inputStream .close ();
85- if (analysisResult == null ) {
86- logger .error ("Null analysis result on this analysis" );
87- }
88- instrumentedClasses .put (analysisResult .name , analysisResult );
89- } catch (IOException e ) {
90- // TODO Auto-generated catch block
91- logger .error ("Error in analysis" , e );
92- }
62+
9363 }
9464
9565 private static void finishedPass () {
9666 switch (pass_number ) {
9767 case PASS_ANALYZE :
98- ma .doneSupplyingClasses ();
9968 break ;
10069 case PASS_OUTPUT :
10170 break ;
@@ -120,10 +89,6 @@ private static byte[] instrumentClass(InputStream is) {
12089 CallbackDuplicatingClassVisitor callbackDuplicator = new CallbackDuplicatingClassVisitor (cv );
12190
12291 cr .accept (callbackDuplicator , ClassReader .EXPAND_FRAMES );
123- if (methodCalls .containsKey (cv .getClassName ()))
124- methodCalls .get (cv .getClassName ()).addAll (cv .getLoggedMethodCalls ());
125- else
126- methodCalls .put (cv .getClassName (), cv .getLoggedMethodCalls ());
12792 lastInstrumentedClass = cv .getClassName ();
12893 byte [] out = cw .toByteArray ();
12994 try {
@@ -648,4 +613,63 @@ private static void processZip(File f, File outputDir) {
648613 }
649614
650615 }
616+
617+ public static boolean classIsCallback (String className , String superName , String [] interfaces ) {
618+ if (NonDeterministicLoggingClassVisitor .callbackClasses .contains (className ))
619+ return true ;
620+ if (className .equals ("java/lang/Object" ))
621+ return false ;
622+ if (interfaces != null )
623+ for (String s : interfaces ) {
624+ if (NonDeterministicLoggingClassVisitor .callbackClasses .contains ((s )))
625+ return true ;
626+ }
627+ if (superName != null )
628+ if (superName .equals (className ) || superName .equals ("java/lang/Object" ) || className .equals ("org/eclipse/jdt/core/compiler/BuildContext" ))
629+ return false ;
630+ try {
631+ Class <?> c = Instrumenter .loader .loadClass (className .replace ("/" , "." ));
632+ for (Class <?> i : c .getInterfaces ()) {
633+ if (NonDeterministicLoggingClassVisitor .callbackClasses .contains (Type .getInternalName (i )))
634+ return true ;
635+ }
636+ Class <?> superClass = c .getSuperclass ();
637+ if (superClass == null )
638+ return false ;
639+ return classIsCallback (Type .getInternalName (superClass ), null , null );
640+ } catch (ClassNotFoundException ex ) {
641+ return false ;
642+ }
643+ }
644+
645+ public static boolean methodIsCallback (String className , String name , String desc , String superName , String [] interfaces ) {
646+ String key = "." + name + ":" + desc ;
647+ if (NonDeterministicLoggingClassVisitor .callbackMethods .contains (className + key ))
648+ return true ;
649+ if (className .equals ("java/lang/Object" ))
650+ return false ;
651+ if (interfaces != null )
652+ for (String s : interfaces ) {
653+ if (NonDeterministicLoggingClassVisitor .callbackMethods .contains ((s + key )))
654+ return true ;
655+ }
656+ if (superName != null )
657+ if (superName .equals (className ) || superName .equals ("java/lang/Object" ) || className .equals ("org/eclipse/jdt/core/compiler/BuildContext" ))
658+ return false ;
659+ try {
660+ Class <?> c = Instrumenter .loader .loadClass (className .replace ("/" , "." ));
661+ for (Class <?> i : c .getInterfaces ()) {
662+ if (NonDeterministicLoggingClassVisitor .callbackMethods .contains (Type .getInternalName (i )+key ))
663+ return true ;
664+ }
665+ Class <?> superClass = c .getSuperclass ();
666+ if (superClass == null )
667+ return false ;
668+ return methodIsCallback (Type .getInternalName (superClass ), name , desc , null , null );
669+ } catch (ClassNotFoundException ex ) {
670+ return false ;
671+ }
672+ }
673+
674+
651675}
0 commit comments