Support @ClassName
This commit is contained in:
@@ -45,6 +45,7 @@ Whatever the type of the field, if it has methods named by the convention define
|
||||
If any of the methods above, except for ```dump.*```, have parameters, they are treated as follows:
|
||||
* *no annotation* - this parameter receives the respective parameter of the instrumented method
|
||||
* ```@This``` - this parameter receives the ```this``` of the instrumented method, or ```null``` if there's no ```this```
|
||||
* ```@ClassName``` - this parameter receives the name of the class containing the instrumented method, must be a ```String```
|
||||
* ```@MethodName``` - this parameter receives the name of the instrumented method, must be a ```String```
|
||||
* ```@MethodDesc``` - this parameter receives the JVM descriptor of the instrumented method, like ```(ILjava/lang/Object;)V```, must be a ```String```
|
||||
* ```@AllArgs``` - this parameter receives an array of all arguments of the instrumented method, must be of type ```Object[]```
|
||||
|
||||
+3
-2
@@ -17,6 +17,7 @@
|
||||
package org.jetbrains.jet.preloading;
|
||||
|
||||
import org.jetbrains.jet.preloading.instrumentation.InterceptionInstrumenterAdaptor;
|
||||
import org.jetbrains.jet.preloading.instrumentation.annotations.ClassName;
|
||||
import org.jetbrains.jet.preloading.instrumentation.annotations.MethodDesc;
|
||||
import org.jetbrains.jet.preloading.instrumentation.annotations.MethodInterceptor;
|
||||
import org.jetbrains.jet.preloading.instrumentation.annotations.MethodName;
|
||||
@@ -104,8 +105,8 @@ public class ProfilingInstrumenterExample extends InterceptionInstrumenterAdapto
|
||||
public static class MethodCollector {
|
||||
private final Collection<String> l = new LinkedHashSet<String>();
|
||||
|
||||
public void enter(@MethodName String name, @MethodDesc String desc) {//long l, Object arg) {
|
||||
l.add(name + desc);
|
||||
public void enter(@ClassName String className, @MethodName String name, @MethodDesc String desc) {
|
||||
l.add(className + "." + name + desc);
|
||||
}
|
||||
|
||||
public void dump(PrintStream out) {
|
||||
|
||||
+15
-3
@@ -166,6 +166,7 @@ public class InterceptionInstrumenter {
|
||||
private static MethodData getMethodData(FieldData interceptorField, Method method) {
|
||||
Annotation[][] parameterAnnotations = method.getParameterAnnotations();
|
||||
int thisParameterIndex = -1;
|
||||
int classNameParameterIndex = -1;
|
||||
int methodNameParameterIndex = -1;
|
||||
int methodDescParameterIndex = -1;
|
||||
int allArgsParameterIndex = -1;
|
||||
@@ -177,6 +178,12 @@ public class InterceptionInstrumenter {
|
||||
}
|
||||
thisParameterIndex = i;
|
||||
}
|
||||
else if (annotation instanceof ClassName) {
|
||||
if (classNameParameterIndex > -1) {
|
||||
throw new IllegalArgumentException("Multiple @ClassName parameters in " + method);
|
||||
}
|
||||
classNameParameterIndex = i;
|
||||
}
|
||||
else if (annotation instanceof MethodName) {
|
||||
if (methodNameParameterIndex > -1) {
|
||||
throw new IllegalArgumentException("Multiple @MethodName parameters in " + method);
|
||||
@@ -203,6 +210,7 @@ public class InterceptionInstrumenter {
|
||||
method.getName(),
|
||||
Type.getMethodDescriptor(method),
|
||||
thisParameterIndex,
|
||||
classNameParameterIndex,
|
||||
methodNameParameterIndex,
|
||||
methodDescParameterIndex,
|
||||
allArgsParameterIndex);
|
||||
@@ -338,7 +346,7 @@ public class InterceptionInstrumenter {
|
||||
for (MethodData methodData : enterData) {
|
||||
// At the very beginning of a constructor, i.e. before any super() call, 'this' is not available
|
||||
// It's too hard to detect a place right after the super() call, so we just put null instead of 'this' in such cases
|
||||
invokeMethod(access, name, desc, getInstructionAdapter(), methodData, isConstructor);
|
||||
invokeMethod(access, cr.getClassName(), name, desc, getInstructionAdapter(), methodData, isConstructor);
|
||||
}
|
||||
super.visitCode();
|
||||
}
|
||||
@@ -353,13 +361,13 @@ public class InterceptionInstrumenter {
|
||||
case DRETURN:
|
||||
case ARETURN:
|
||||
for (MethodData methodData : normalReturnData) {
|
||||
invokeMethod(access, name, desc, getInstructionAdapter(), methodData, false);
|
||||
invokeMethod(access, cr.getClassName(), name, desc, getInstructionAdapter(), methodData, false);
|
||||
}
|
||||
break;
|
||||
case ATHROW:
|
||||
for (MethodData methodData : exceptionData) {
|
||||
// A constructor may throw before calling super(), 'this' is not available in this case
|
||||
invokeMethod(access, name, desc, getInstructionAdapter(), methodData, isConstructor);
|
||||
invokeMethod(access, cr.getClassName(), name, desc, getInstructionAdapter(), methodData, isConstructor);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -445,6 +453,7 @@ public class InterceptionInstrumenter {
|
||||
|
||||
private static void invokeMethod(
|
||||
int instrumentedMethodAccess,
|
||||
String instrumentedClassName,
|
||||
String instrumentedMethodName,
|
||||
String instrumentedMethodDesc,
|
||||
InstructionAdapter ia,
|
||||
@@ -475,6 +484,9 @@ public class InterceptionInstrumenter {
|
||||
ia.load(0, OBJECT_TYPE);
|
||||
}
|
||||
}
|
||||
else if (i == methodData.getClassNameParameterIndex()) {
|
||||
ia.aconst(instrumentedClassName);
|
||||
}
|
||||
else if (i == methodData.getMethodNameParameterIndex()) {
|
||||
ia.aconst(instrumentedMethodName);
|
||||
}
|
||||
|
||||
+7
@@ -19,6 +19,7 @@ package org.jetbrains.jet.preloading.instrumentation;
|
||||
public class MethodData extends MemberData {
|
||||
private final FieldData ownerField;
|
||||
private final int thisParameterIndex;
|
||||
private final int classNameParameterIndex;
|
||||
private final int methodNameParameterIndex;
|
||||
private final int methodDescParameterIndex;
|
||||
private final int allArgsParameterIndex;
|
||||
@@ -29,6 +30,7 @@ public class MethodData extends MemberData {
|
||||
String name,
|
||||
String desc,
|
||||
int thisParameterIndex,
|
||||
int classNameParameterIndex,
|
||||
int methodNameParameterIndex,
|
||||
int methodDescParameterIndex,
|
||||
int allArgsParameterIndex
|
||||
@@ -36,6 +38,7 @@ public class MethodData extends MemberData {
|
||||
super(declaringClass, name, desc);
|
||||
this.ownerField = ownerField;
|
||||
this.thisParameterIndex = thisParameterIndex;
|
||||
this.classNameParameterIndex = classNameParameterIndex;
|
||||
this.methodNameParameterIndex = methodNameParameterIndex;
|
||||
this.methodDescParameterIndex = methodDescParameterIndex;
|
||||
this.allArgsParameterIndex = allArgsParameterIndex;
|
||||
@@ -49,6 +52,10 @@ public class MethodData extends MemberData {
|
||||
return thisParameterIndex;
|
||||
}
|
||||
|
||||
public int getClassNameParameterIndex() {
|
||||
return classNameParameterIndex;
|
||||
}
|
||||
|
||||
public int getMethodNameParameterIndex() {
|
||||
return methodNameParameterIndex;
|
||||
}
|
||||
|
||||
+27
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* Copyright 2010-2013 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.preloading.instrumentation.annotations;
|
||||
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
@Target(ElementType.PARAMETER)
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ClassName {
|
||||
}
|
||||
Reference in New Issue
Block a user