@@ -44,10 +44,11 @@ public Instrumenter newInstrumenter(Class<?> clazz, Map<MethodKey, CheckMethod>
4444 return InstrumenterImpl .create (clazz , methods );
4545 }
4646
47- @ Override
48- public Map < MethodKey , CheckMethod > lookupMethods (Class <?> checkerClass ) throws IOException {
49- Map < MethodKey , CheckMethod > methodsToInstrument = new HashMap <>();
47+ private interface CheckerMethodVisitor {
48+ void visit (Class <?> currentClass , int access , String checkerMethodName , String checkerMethodDescriptor );
49+ }
5050
51+ private void visitClassAndSupers (Class <?> checkerClass , CheckerMethodVisitor checkerMethodVisitor ) throws ClassNotFoundException {
5152 Set <Class <?>> visitedClasses = new HashSet <>();
5253 ArrayDeque <Class <?>> classesToVisit = new ArrayDeque <>(Collections .singleton (checkerClass ));
5354 while (classesToVisit .isEmpty () == false ) {
@@ -57,67 +58,76 @@ public Map<MethodKey, CheckMethod> lookupMethods(Class<?> checkerClass) throws I
5758 }
5859 visitedClasses .add (currentClass );
5960
60- var classFileInfo = InstrumenterImpl .getClassFileInfo (currentClass );
61- ClassReader reader = new ClassReader (classFileInfo .bytecodes ());
62- ClassVisitor visitor = new ClassVisitor (Opcodes .ASM9 ) {
61+ try {
62+ var classFileInfo = InstrumenterImpl .getClassFileInfo (currentClass );
63+ ClassReader reader = new ClassReader (classFileInfo .bytecodes ());
64+ ClassVisitor visitor = new ClassVisitor (Opcodes .ASM9 ) {
6365
64- @ Override
65- public void visit (int version , int access , String name , String signature , String superName , String [] interfaces ) {
66- super .visit (version , access , name , signature , superName , interfaces );
67- try {
68- if (OBJECT_INTERNAL_NAME .equals (superName ) == false ) {
69- classesToVisit .add (Class .forName (Type .getObjectType (superName ).getClassName ()));
66+ @ Override
67+ public void visit (int version , int access , String name , String signature , String superName , String [] interfaces ) {
68+ super .visit (version , access , name , signature , superName , interfaces );
69+ try {
70+ if (OBJECT_INTERNAL_NAME .equals (superName ) == false ) {
71+ classesToVisit .add (Class .forName (Type .getObjectType (superName ).getClassName ()));
72+ }
73+ for (var interfaceName : interfaces ) {
74+ classesToVisit .add (Class .forName (Type .getObjectType (interfaceName ).getClassName ()));
75+ }
76+ } catch (ClassNotFoundException e ) {
77+ throw new IllegalArgumentException ("Cannot inspect checker class " + currentClass .getName (), e );
7078 }
71- for (var interfaceName : interfaces ) {
72- classesToVisit .add (Class .forName (Type .getObjectType (interfaceName ).getClassName ()));
73- }
74- } catch (ClassNotFoundException e ) {
75- throw new IllegalArgumentException ("Cannot inspect checker class " + checkerClass .getName (), e );
7679 }
77- }
7880
79- @ Override
80- public MethodVisitor visitMethod (
81- int access ,
82- String checkerMethodName ,
83- String checkerMethodDescriptor ,
84- String signature ,
85- String [] exceptions
86- ) {
87- var mv = super .visitMethod (access , checkerMethodName , checkerMethodDescriptor , signature , exceptions );
88- if (checkerMethodName .startsWith (InstrumentationService .CHECK_METHOD_PREFIX )) {
89- var checkerMethodArgumentTypes = Type .getArgumentTypes (checkerMethodDescriptor );
90- var methodToInstrument = parseCheckerMethodSignature (checkerMethodName , checkerMethodArgumentTypes );
91-
92- var checkerParameterDescriptors = Arrays .stream (checkerMethodArgumentTypes ).map (Type ::getDescriptor ).toList ();
93- var checkMethod = new CheckMethod (
94- Type .getInternalName (currentClass ),
95- checkerMethodName ,
96- checkerParameterDescriptors
97- );
98-
99- methodsToInstrument .putIfAbsent (methodToInstrument , checkMethod );
81+ @ Override
82+ public MethodVisitor visitMethod (
83+ int access ,
84+ String checkerMethodName ,
85+ String checkerMethodDescriptor ,
86+ String signature ,
87+ String [] exceptions
88+ ) {
89+ var mv = super .visitMethod (access , checkerMethodName , checkerMethodDescriptor , signature , exceptions );
90+ checkerMethodVisitor .visit (currentClass , access , checkerMethodName , checkerMethodDescriptor );
91+ return mv ;
10092 }
101- return mv ;
102- }
103- };
104- reader .accept (visitor , 0 );
93+ };
94+ reader .accept (visitor , 0 );
95+ } catch (IOException e ) {
96+ throw new ClassNotFoundException ("Cannot find a definition for class [" + checkerClass .getName () + "]" , e );
97+ }
10598 }
99+ }
100+
101+ @ Override
102+ public Map <MethodKey , CheckMethod > lookupMethods (Class <?> checkerClass ) throws ClassNotFoundException {
103+ Map <MethodKey , CheckMethod > methodsToInstrument = new HashMap <>();
104+
105+ visitClassAndSupers (checkerClass , (currentClass , access , checkerMethodName , checkerMethodDescriptor ) -> {
106+ if (checkerMethodName .startsWith (InstrumentationService .CHECK_METHOD_PREFIX )) {
107+ var checkerMethodArgumentTypes = Type .getArgumentTypes (checkerMethodDescriptor );
108+ var methodToInstrument = parseCheckerMethodSignature (checkerMethodName , checkerMethodArgumentTypes );
109+
110+ var checkerParameterDescriptors = Arrays .stream (checkerMethodArgumentTypes ).map (Type ::getDescriptor ).toList ();
111+ var checkMethod = new CheckMethod (Type .getInternalName (currentClass ), checkerMethodName , checkerParameterDescriptors );
112+ methodsToInstrument .putIfAbsent (methodToInstrument , checkMethod );
113+ }
114+ });
115+
106116 return methodsToInstrument ;
107117 }
108118
109119 @ SuppressForbidden (reason = "Need access to abstract methods (protected/package internal) in base class" )
110120 @ Override
111121 public InstrumentationInfo lookupImplementationMethod (
112122 Class <?> targetSuperclass ,
113- String methodName ,
123+ String targetMethodName ,
114124 Class <?> implementationClass ,
115125 Class <?> checkerClass ,
116126 String checkMethodName ,
117127 Class <?>... parameterTypes
118128 ) throws NoSuchMethodException , ClassNotFoundException {
119129
120- var targetMethod = targetSuperclass .getDeclaredMethod (methodName , parameterTypes );
130+ var targetMethod = targetSuperclass .getDeclaredMethod (targetMethodName , parameterTypes );
121131 var implementationMethod = implementationClass .getMethod (targetMethod .getName (), targetMethod .getParameterTypes ());
122132 validateTargetMethod (implementationClass , targetMethod , implementationMethod );
123133
@@ -128,33 +138,15 @@ public InstrumentationInfo lookupImplementationMethod(
128138
129139 CheckMethod [] checkMethod = new CheckMethod [1 ];
130140
131- try {
132- InstrumenterImpl .ClassFileInfo classFileInfo = InstrumenterImpl .getClassFileInfo (checkerClass );
133- ClassReader reader = new ClassReader (classFileInfo .bytecodes ());
134- ClassVisitor visitor = new ClassVisitor (Opcodes .ASM9 ) {
135- @ Override
136- public MethodVisitor visitMethod (
137- int access ,
138- String methodName ,
139- String methodDescriptor ,
140- String signature ,
141- String [] exceptions
142- ) {
143- var mv = super .visitMethod (access , methodName , methodDescriptor , signature , exceptions );
144- if (methodName .equals (checkMethodName )) {
145- var methodArgumentTypes = Type .getArgumentTypes (methodDescriptor );
146- if (Arrays .equals (methodArgumentTypes , checkMethodArgumentTypes )) {
147- var checkerParameterDescriptors = Arrays .stream (methodArgumentTypes ).map (Type ::getDescriptor ).toList ();
148- checkMethod [0 ] = new CheckMethod (Type .getInternalName (checkerClass ), methodName , checkerParameterDescriptors );
149- }
150- }
151- return mv ;
141+ visitClassAndSupers (checkerClass , (currentClass , access , methodName , methodDescriptor ) -> {
142+ if (methodName .equals (checkMethodName )) {
143+ var methodArgumentTypes = Type .getArgumentTypes (methodDescriptor );
144+ if (Arrays .equals (methodArgumentTypes , checkMethodArgumentTypes )) {
145+ var checkerParameterDescriptors = Arrays .stream (methodArgumentTypes ).map (Type ::getDescriptor ).toList ();
146+ checkMethod [0 ] = new CheckMethod (Type .getInternalName (currentClass ), methodName , checkerParameterDescriptors );
152147 }
153- };
154- reader .accept (visitor , 0 );
155- } catch (IOException e ) {
156- throw new ClassNotFoundException ("Cannot find a definition for class [" + checkerClass .getName () + "]" , e );
157- }
148+ }
149+ });
158150
159151 if (checkMethod [0 ] == null ) {
160152 throw new NoSuchMethodException (
0 commit comments