Пример #1
0
  private MethodVisitor generateCallToHandlerThroughMockingBridge(
      int access,
      String name,
      String desc,
      String genericSignature,
      String[] exceptions,
      String internalClassName,
      int executionMode) {
    generateCodeToObtainInstanceOfMockingBridge(MockedBridge.class.getName());

    // First and second "invoke" arguments:
    boolean isStatic = generateCodeToPassThisOrNullIfStaticMethod(access);
    mw.visitInsn(ACONST_NULL);

    // Create array for call arguments (third "invoke" argument):
    Type[] argTypes = Type.getArgumentTypes(desc);
    generateCodeToCreateArrayOfObject(7 + argTypes.length);

    int i = 0;
    generateCodeToFillArrayElement(i++, access);
    generateCodeToFillArrayElement(i++, internalClassName);
    generateCodeToFillArrayElement(i++, name);
    generateCodeToFillArrayElement(i++, desc);
    generateCodeToFillArrayElement(i++, genericSignature);
    generateCodeToFillArrayElement(i++, getListOfExceptionsAsSingleString(exceptions));
    generateCodeToFillArrayElement(i++, executionMode);

    generateCodeToPassMethodArgumentsAsVarargs(argTypes, i, isStatic ? 0 : 1);
    generateCallToInvocationHandler();

    generateDecisionBetweenReturningOrContinuingToRealImplementation(desc);

    // Copies the entire original implementation even for a constructor, in which case the complete
    // bytecode inside
    // the constructor fails the strict verification activated by "-Xfuture". However, this is
    // necessary to allow the
    // full execution of a JRE constructor when the call was not meant to be mocked.
    return copyOriginalImplementationCode(access, desc);
  }
Пример #2
0
  @Override
  public MethodVisitor visitMethod(
      int access, String name, String desc, String signature, String[] exceptions) {
    boolean syntheticOrAbstractMethod = (access & METHOD_ACCESS_MASK) != 0;

    if (syntheticOrAbstractMethod
        || isProxy && isConstructorOrSystemMethodNotToBeMocked(name, desc)) {
      return unmodifiedBytecode(access, name, desc, signature, exceptions);
    }

    boolean noFiltersToMatch = mockingCfg == null;
    boolean matchesFilters = noFiltersToMatch || mockingCfg.matchesFilters(name, desc);

    if ("<clinit>".equals(name)) {
      return stubOutClassInitializationIfApplicable(access, noFiltersToMatch, matchesFilters);
    } else if (stubOutFinalizeMethod(access, name, desc)) {
      return null;
    }

    if (!matchesFilters
        || isMethodFromCapturedClassNotToBeMocked(access)
        || noFiltersToMatch && isMethodOrConstructorNotToBeMocked(access, name)) {
      return unmodifiedBytecode(access, name, desc, signature, exceptions);
    }

    // Otherwise, replace original implementation with redirect to JMockit.
    validateModificationOfNativeMethod(access, name);
    startModifiedMethodVersion(access, name, desc, signature, exceptions);

    boolean visitingConstructor = "<init>".equals(name);

    if (visitingConstructor && superClassName != null) {
      generateCallToSuperConstructor();
    }

    String internalClassName = className;

    if (!visitingConstructor && baseClassNameForCapturedInstanceMethods != null) {
      internalClassName = baseClassNameForCapturedInstanceMethods;
    }

    int actualExecutionMode = determineAppropriateExecutionMode(access, visitingConstructor);

    if (useMockingBridge) {
      return generateCallToHandlerThroughMockingBridge(
          access, name, desc, signature, exceptions, internalClassName, actualExecutionMode);
    }

    generateDirectCallToHandler(
        internalClassName, access, name, desc, signature, exceptions, actualExecutionMode);

    if (actualExecutionMode > 0) {
      generateDecisionBetweenReturningOrContinuingToRealImplementation(desc);

      // Constructors of non-JRE classes can't be modified (unless running with "-noverify") in a
      // way that
      // "super(...)/this(...)" get called twice, so we disregard such calls when copying the
      // original bytecode.
      return visitingConstructor
          ? new DynamicConstructorModifier()
          : copyOriginalImplementationCode(access, desc);
    }

    generateReturnWithObjectAtTopOfTheStack(desc);
    mw.visitMaxs(1, 0);
    return methodAnnotationsVisitor;
  }