Esempio n. 1
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;
  }