private void generateCallToClassHandler(MutableClass mutableClass, MethodNode originalMethod,
      String originalMethodName, RobolectricGeneratorAdapter generator) {
    decorator.decorateMethodPreClassHandler(mutableClass, originalMethod, originalMethodName, generator);

    int planLocalVar = generator.newLocal(PLAN_TYPE);
    int exceptionLocalVar = generator.newLocal(THROWABLE_TYPE);
    Label directCall = new Label();
    Label doReturn = new Label();

    // prepare for call to classHandler.methodInvoked(String signature, boolean isStatic)
    generator.push(mutableClass.classType.getInternalName() + "/" + originalMethodName + originalMethod.desc);
    generator.push(generator.isStatic());
    generator.push(mutableClass.classType);                                         // my class
    generator.invokeStatic(ROBOLECTRIC_INTERNALS_TYPE, METHOD_INVOKED_METHOD);
    generator.storeLocal(planLocalVar);

    generator.loadLocal(planLocalVar); // plan
    generator.ifNull(directCall);

    // prepare for call to plan.run(Object instance, Object[] params)
    TryCatch tryCatchForHandler = generator.tryStart(THROWABLE_TYPE);
    generator.loadLocal(planLocalVar); // plan
    generator.loadThisOrNull();        // instance
    generator.loadArgArray();          // params
    generator.invokeInterface(PLAN_TYPE, PLAN_RUN_METHOD);

    Type returnType = generator.getReturnType();
    int sort = returnType.getSort();
    switch (sort) {
      case VOID:
        generator.pop();
        break;
      case OBJECT:
        /* falls through */
      case ARRAY:
        generator.checkCast(returnType);
        break;
      default:
        int unboxLocalVar = generator.newLocal(OBJECT_TYPE);
        generator.storeLocal(unboxLocalVar);
        generator.loadLocal(unboxLocalVar);
        Label notNull = generator.newLabel();
        Label afterward = generator.newLabel();
        generator.ifNonNull(notNull);
        generator.pushDefaultReturnValueToStack(returnType); // return zero, false, whatever
        generator.goTo(afterward);

        generator.mark(notNull);
        generator.loadLocal(unboxLocalVar);
        generator.unbox(returnType);
        generator.mark(afterward);
        break;
    }
    tryCatchForHandler.end();
    generator.goTo(doReturn);

    // catch(Throwable)
    tryCatchForHandler.handler();
    generator.storeLocal(exceptionLocalVar);
    generator.loadLocal(exceptionLocalVar);
    generator.invokeStatic(ROBOLECTRIC_INTERNALS_TYPE, HANDLE_EXCEPTION_METHOD);
    generator.throwException();


    if (!originalMethod.name.equals("<init>")) {
      generator.mark(directCall);
      TryCatch tryCatchForDirect = generator.tryStart(THROWABLE_TYPE);
      generator.invokeMethod(mutableClass.classType.getInternalName(), originalMethod.name, originalMethod.desc);
      tryCatchForDirect.end();
      generator.returnValue();

      // catch(Throwable)
      tryCatchForDirect.handler();
      generator.storeLocal(exceptionLocalVar);
      generator.loadLocal(exceptionLocalVar);
      generator.invokeStatic(ROBOLECTRIC_INTERNALS_TYPE, HANDLE_EXCEPTION_METHOD);
      generator.throwException();
    }

    generator.mark(doReturn);
    generator.returnValue();
  }
private void generateCallToClassHandler(MutableClass mutableClass, MethodNode originalMethod,
      String originalMethodName, RobolectricGeneratorAdapter generator) {
    decorator.decorateMethodPreClassHandler(mutableClass, originalMethod, originalMethodName, generator);

    int planLocalVar = generator.newLocal(PLAN_TYPE);
    int exceptionLocalVar = generator.newLocal(THROWABLE_TYPE);
    Label directCall = new Label();
    Label doReturn = new Label();

    
    generator.push(mutableClass.classType.getInternalName() + "/" + originalMethodName + originalMethod.desc);
    generator.push(generator.isStatic());
    generator.push(mutableClass.classType);                                         
    generator.invokeStatic(ROBOLECTRIC_INTERNALS_TYPE, METHOD_INVOKED_METHOD);
    generator.storeLocal(planLocalVar);

    generator.loadLocal(planLocalVar); 
    generator.ifNull(directCall);

    
    TryCatch tryCatchForHandler = generator.tryStart(THROWABLE_TYPE);
    generator.loadLocal(planLocalVar); 
    generator.loadThisOrNull();        
    generator.loadArgArray();          
    generator.invokeInterface(PLAN_TYPE, PLAN_RUN_METHOD);

    Type returnType = generator.getReturnType();
    int sort = returnType.getSort();
    switch (sort) {
      case VOID:
        generator.pop();
        break;
      case OBJECT:
        
      case ARRAY:
        generator.checkCast(returnType);
        break;
      default:
        int unboxLocalVar = generator.newLocal(OBJECT_TYPE);
        generator.storeLocal(unboxLocalVar);
        generator.loadLocal(unboxLocalVar);
        Label notNull = generator.newLabel();
        Label afterward = generator.newLabel();
        generator.ifNonNull(notNull);
        generator.pushDefaultReturnValueToStack(returnType); 
        generator.goTo(afterward);

        generator.mark(notNull);
        generator.loadLocal(unboxLocalVar);
        generator.unbox(returnType);
        generator.mark(afterward);
        break;
    }
    tryCatchForHandler.end();
    generator.goTo(doReturn);

    
    tryCatchForHandler.handler();
    generator.storeLocal(exceptionLocalVar);
    generator.loadLocal(exceptionLocalVar);
    generator.invokeStatic(ROBOLECTRIC_INTERNALS_TYPE, HANDLE_EXCEPTION_METHOD);
    generator.throwException();


    if (!originalMethod.name.equals("<init>")) {
      generator.mark(directCall);
      TryCatch tryCatchForDirect = generator.tryStart(THROWABLE_TYPE);
      generator.invokeMethod(mutableClass.classType.getInternalName(), originalMethod.name, originalMethod.desc);
      tryCatchForDirect.end();
      generator.returnValue();

      
      tryCatchForDirect.handler();
      generator.storeLocal(exceptionLocalVar);
      generator.loadLocal(exceptionLocalVar);
      generator.invokeStatic(ROBOLECTRIC_INTERNALS_TYPE, HANDLE_EXCEPTION_METHOD);
      generator.throwException();
    }

    generator.mark(doReturn);
    generator.returnValue();
  }
private void generateCallToClassHandler ( MutableClass mutableClass , MethodNode originalMethod , String originalMethodName , RobolectricGeneratorAdapter generator ) { decorator . decorateMethodPreClassHandler ( mutableClass , originalMethod , originalMethodName , generator ) ; int planLocalVar = generator . newLocal ( PLAN_TYPE ) ; int exceptionLocalVar = generator . newLocal ( THROWABLE_TYPE ) ; Label directCall = new Label ( ) ; Label doReturn = new Label ( ) ; // prepare for call to classHandler.methodInvoked(String signature, boolean isStatic) generator . push ( mutableClass . classType . getInternalName ( ) + "/" + originalMethodName + originalMethod . desc ) ; generator . push ( generator . isStatic ( ) ) ; generator . push ( mutableClass . classType ) ; // my class generator . invokeStatic ( ROBOLECTRIC_INTERNALS_TYPE , METHOD_INVOKED_METHOD ) ; generator . storeLocal ( planLocalVar ) ; generator . loadLocal ( planLocalVar ) ; // plan generator . ifNull ( directCall ) ; // prepare for call to plan.run(Object instance, Object[] params) TryCatch tryCatchForHandler = generator . tryStart ( THROWABLE_TYPE ) ; generator . loadLocal ( planLocalVar ) ; // plan generator . loadThisOrNull ( ) ; // instance generator . loadArgArray ( ) ; // params generator . invokeInterface ( PLAN_TYPE , PLAN_RUN_METHOD ) ; Type returnType = generator . getReturnType ( ) ; int sort = returnType . getSort ( ) ; switch ( sort ) { case VOID : generator . pop ( ) ; break ; case OBJECT : /* falls through */ case ARRAY : generator . checkCast ( returnType ) ; break ; default : int unboxLocalVar = generator . newLocal ( OBJECT_TYPE ) ; generator . storeLocal ( unboxLocalVar ) ; generator . loadLocal ( unboxLocalVar ) ; Label notNull = generator . newLabel ( ) ; Label afterward = generator . newLabel ( ) ; generator . ifNonNull ( notNull ) ; generator . pushDefaultReturnValueToStack ( returnType ) ; // return zero, false, whatever generator . goTo ( afterward ) ; generator . mark ( notNull ) ; generator . loadLocal ( unboxLocalVar ) ; generator . unbox ( returnType ) ; generator . mark ( afterward ) ; break ; } tryCatchForHandler . end ( ) ; generator . goTo ( doReturn ) ; // catch(Throwable) tryCatchForHandler . handler ( ) ; generator . storeLocal ( exceptionLocalVar ) ; generator . loadLocal ( exceptionLocalVar ) ; generator . invokeStatic ( ROBOLECTRIC_INTERNALS_TYPE , HANDLE_EXCEPTION_METHOD ) ; generator . throwException ( ) ; if ( ! originalMethod . name . equals ( "<init>" ) ) { generator . mark ( directCall ) ; TryCatch tryCatchForDirect = generator . tryStart ( THROWABLE_TYPE ) ; generator . invokeMethod ( mutableClass . classType . getInternalName ( ) , originalMethod . name , originalMethod . desc ) ; tryCatchForDirect . end ( ) ; generator . returnValue ( ) ; // catch(Throwable) tryCatchForDirect . handler ( ) ; generator . storeLocal ( exceptionLocalVar ) ; generator . loadLocal ( exceptionLocalVar ) ; generator . invokeStatic ( ROBOLECTRIC_INTERNALS_TYPE , HANDLE_EXCEPTION_METHOD ) ; generator . throwException ( ) ; } generator . mark ( doReturn ) ; generator . returnValue ( ) ; }
Generates codelike this:
```java
// decorator-specific code...

Plan plan = RobolectricInternals.methodInvoked(
"pkg/ThisClass/thisMethod(Ljava/lang/String;Z)V", isStatic, ThisClass.class);
if (plan != null) {
try {
return plan.run(this, args);
} catch (Throwable t) {
throw RobolectricInternals.cleanStackTrace(t);
}
} else {
return $$robo$$thisMethod(*args);
}
```
Generates codelike this : java // decorator - specific code ...