public class ShadowWrangler extends java.lang.Object implements ClassHandler
ClassHandler.Plan
Modifier and Type | Field and Description |
---|---|
static java.lang.reflect.Method |
CALL_REAL_CODE |
static ClassHandler.Plan |
CALL_REAL_CODE_PLAN |
static java.lang.invoke.MethodHandle |
DO_NOTHING |
static Function<java.lang.Object,java.lang.Object> |
DO_NOTHING_HANDLER |
static java.lang.reflect.Method |
DO_NOTHING_METHOD |
static ClassHandler.Plan |
DO_NOTHING_PLAN |
static Implementation |
IMPLEMENTATION_DEFAULTS |
Constructor and Description |
---|
ShadowWrangler(ShadowMap shadowMap,
int apiLevel,
Interceptors interceptors) |
Modifier and Type | Method and Description |
---|---|
void |
classInitializing(java.lang.Class clazz)
Called by Robolectric when an instrumented class is first loaded into a sandbox and is ready to be statically initialized.
|
java.lang.invoke.MethodHandle |
findShadowMethodHandle(java.lang.Class<?> definingClass,
java.lang.String name,
java.lang.invoke.MethodType methodType,
boolean isStatic)
Called by Robolectric when an instrumented method is invoked.
|
java.lang.invoke.MethodHandle |
getShadowCreator(java.lang.Class<?> theClass)
Called by Robolectric to determine how to create and initialize a shadow object when a new instance of an instrumented class has been instantiated.
|
java.lang.Object |
initializing(java.lang.Object instance)
Called by Robolectric when a new instance of an instrumented class has been created and is ready to be initialized (but only on JVMs which don’t support the
invokedynamic instruction). |
java.lang.Object |
intercept(java.lang.String signature,
java.lang.Object instance,
java.lang.Object[] params,
java.lang.Class theClass)
Called by Robolectric when an intercepted method is invoked.
|
static java.lang.Class<?> |
loadClass(java.lang.String paramType,
java.lang.ClassLoader classLoader) |
ClassHandler.Plan |
methodInvoked(java.lang.String signature,
boolean isStatic,
java.lang.Class<?> theClass)
Called by Robolectric when an instrumented method is invoked.
|
protected java.lang.reflect.Method |
pickShadowMethod(java.lang.Class<?> definingClass,
java.lang.String name,
java.lang.Class<?>[] paramTypes) |
<T extends java.lang.Throwable> |
stripStackTrace(T throwable)
Removes Robolectric noise from stack traces.
|
public static final Function<java.lang.Object,java.lang.Object> DO_NOTHING_HANDLER
public static final ClassHandler.Plan DO_NOTHING_PLAN
public static final ClassHandler.Plan CALL_REAL_CODE_PLAN
public static final java.lang.reflect.Method CALL_REAL_CODE
public static final java.lang.invoke.MethodHandle DO_NOTHING
public static final java.lang.reflect.Method DO_NOTHING_METHOD
public static final Implementation IMPLEMENTATION_DEFAULTS
public ShadowWrangler(ShadowMap shadowMap, int apiLevel, Interceptors interceptors)
public static java.lang.Class<?> loadClass(java.lang.String paramType, java.lang.ClassLoader classLoader)
public void classInitializing(java.lang.Class clazz)
ClassHandler
Called by Robolectric when an instrumented class is first loaded into a sandbox and is ready to be statically initialized.
This happens in place of any static initialization that may be performed by the class being loaded. The class will have a method named __staticInitializer__
which may be invoked to perform its normal initialization from <clinit>
.
classInitializing
in interface ClassHandler
clazz
- the class being loadedpublic java.lang.Object initializing(java.lang.Object instance)
ClassHandler
Called by Robolectric when a new instance of an instrumented class has been created and is ready to be initialized (but only on JVMs which don’t support the invokedynamic
instruction).
This happens before constructor code executes on the new instance.
Implementations may return an object which will be associated with the new instance and passed along on future calls to ClassHandler.methodInvoked(String, boolean, Class)
.
initializing
in interface ClassHandler
instance
- the newly-created instancefor newer JVMs
public ClassHandler.Plan methodInvoked(java.lang.String signature, boolean isStatic, java.lang.Class<?> theClass)
ClassHandler
Called by Robolectric when an instrumented method is invoked.
Implementations should return an ClassHandler.Plan
, which will be invoked with details about the current instance and parameters.
Implementations may also return null
, in which case the method’s original code will be executed.
methodInvoked
in interface ClassHandler
signature
- the JVM internal-format signature of the method being invoked (e.g. android/view/View/measure(II)V
)isStatic
- true if the method is statictheClass
- the class on which the method is declarednull
if the original method’s code should be executedfor newer JVMs
public java.lang.invoke.MethodHandle findShadowMethodHandle(java.lang.Class<?> definingClass, java.lang.String name, java.lang.invoke.MethodType methodType, boolean isStatic) throws java.lang.IllegalAccessException
ClassHandler
Called by Robolectric when an instrumented method is invoked.
Implementations should return an MethodHandle
, which will be invoked with details about the current instance and parameters.
Implementations may also return null
, in which case the method’s original code will be executed.
findShadowMethodHandle
in interface ClassHandler
definingClass
- the class on which the method is declaredname
- the name of the methodmethodType
- the method typeisStatic
- true if the method is staticnull
if the original method’s code should be executedjava.lang.IllegalAccessException
for older JVMs
,
for invalidating the returned {@link MethodHandle}
protected java.lang.reflect.Method pickShadowMethod(java.lang.Class<?> definingClass, java.lang.String name, java.lang.Class<?>[] paramTypes)
public java.lang.Object intercept(java.lang.String signature, java.lang.Object instance, java.lang.Object[] params, java.lang.Class theClass) throws java.lang.Throwable
ClassHandler
Called by Robolectric when an intercepted method is invoked.
Unlike instrumented methods, calls to intercepted methods are modified in place by Robolectric in the calling code. This is useful when the method about to be invoked doesn’t exist in the current JVM (e.g. because of Android differences).
intercept
in interface ClassHandler
signature
- the JVM internal-format signature of the method being invoked (e.g. android/view/View/measure(II)V
)instance
- the instance on which the method would have been invokedparams
- the parameters to the methodtheClass
- the class on which the method is declaredjava.lang.Throwable
- if anything bad happenspublic <T extends java.lang.Throwable> T stripStackTrace(T throwable)
ClassHandler
Removes Robolectric noise from stack traces.
stripStackTrace
in interface ClassHandler
T
- the type of exceptionthrowable
- the exception to be strippedpublic java.lang.invoke.MethodHandle getShadowCreator(java.lang.Class<?> theClass)
ClassHandler
Called by Robolectric to determine how to create and initialize a shadow object when a new instance of an instrumented class has been instantiated. (but only on JVMs which support the invokedynamic
instruction).
The returned MethodHandle
will be invoked after the new object has been allocated but before its constructor code is executed.
Note that this is not directly analogous to ClassHandler.initializing(Object)
; the return value from this method will be cached and used again for other instantiations of instances of the same class.
getShadowCreator
in interface ClassHandler
theClass
- the instrumented classfor older JVMs
,
for invalidating the returned {@link MethodHandle}