Class ClassInstrumentor

  • Direct Known Subclasses:
    InvokeDynamicClassInstrumentor

    public class ClassInstrumentor
    extends Object
    Instruments (i.e. modifies the bytecode) of classes to place the scaffolding necessary to use Robolectric's shadows.
    • Field Detail

      • OBJECT_TYPE

        protected static final org.objectweb.asm.Type OBJECT_TYPE
    • Constructor Detail

      • ClassInstrumentor

        public ClassInstrumentor()
    • Method Detail

      • instrument

        public void instrument​(MutableClass mutableClass)
      • addCallToRoboInit

        protected void addCallToRoboInit​(MutableClass mutableClass,
                                         org.objectweb.asm.tree.MethodNode ctor)
        Adds a call $$robo$init, which instantiates a shadow object if required. This is to support custom shadows for Jacoco-instrumented classes (except cnstructor shadows).
      • instrumentConstructor

        protected void instrumentConstructor​(MutableClass mutableClass,
                                             org.objectweb.asm.tree.MethodNode method)
        Constructors are instrumented as follows:
        • The original constructor will be stripped of its instructions leading up to, and including, the call to super() or this(). It is also renamed to $$robo$$__constructor__
        • A method called __constructor__ is created and its job is to call $$robo$$__constructor__. The __constructor__ method is what gets shadowed if a Shadow wants to shadow a constructor.
        • A new constructor is created and contains the stripped instructions of the original constructor leading up to, and including, the call to super() or this(). Then, it has a call to $$robo$init to initialize the Class' Shadow Object. Then, it uses invokedynamic to call __constructor__. Finally, it contains any instructions that might occur after the return statement in the original constructor.
        Parameters:
        method - the constructor to instrument
      • instrumentNormalMethod

        protected void instrumentNormalMethod​(MutableClass mutableClass,
                                              org.objectweb.asm.tree.MethodNode method)
        Instruments a normal method
        • Rename the method from methodName to $$robo$$methodName.
        • Make it private so we can invoke it directly without subclass overrides taking precedence.
        • Remove final modifiers, if present.
        • Create a delegator method named methodName which delegates to the ClassHandler.
      • instrumentNativeMethod

        protected void instrumentNativeMethod​(MutableClass mutableClass,
                                              org.objectweb.asm.tree.MethodNode method)
        Creates native stub which returns the default return value.
        Parameters:
        mutableClass - Class to be instrumented
        method - Method to be instrumented, must be native
      • exceptionArray

        protected String[] exceptionArray​(org.objectweb.asm.tree.MethodNode method)
      • interceptInvokeVirtualMethod

        protected void interceptInvokeVirtualMethod​(MutableClass mutableClass,
                                                    ListIterator<org.objectweb.asm.tree.AbstractInsnNode> instructions,
                                                    org.objectweb.asm.tree.MethodInsnNode targetMethod)
        Decides to call through the appropriate method to intercept the method with an INVOKEVIRTUAL Opcode, depending if the invokedynamic bytecode instruction is available (Java 7+).
      • makeMethodPrivate

        protected void makeMethodPrivate​(org.objectweb.asm.tree.MethodNode method)
        Replaces protected and public class modifiers with private.
      • setAndroidJarSDKVersion

        public void setAndroidJarSDKVersion​(int androidJarSDKVersion)
      • getAndroidJarSDKVersion

        protected int getAndroidJarSDKVersion()