View Javadoc
1   /*
2    * Copyright (c) 2006 JMockit developers
3    * This file is subject to the terms of the MIT license (see LICENSE.txt).
4    */
5   package mockit.internal.faking;
6   
7   import static mockit.internal.util.Utilities.NO_ARGS;
8   
9   import edu.umd.cs.findbugs.annotations.NonNull;
10  import edu.umd.cs.findbugs.annotations.Nullable;
11  
12  import java.lang.reflect.Constructor;
13  import java.lang.reflect.Member;
14  
15  import mockit.internal.BaseInvocation;
16  import mockit.internal.state.TestRun;
17  
18  import org.checkerframework.checker.index.qual.NonNegative;
19  
20  /**
21   * An invocation to a {@linkplain mockit.Mock fake} method.
22   */
23  public final class FakeInvocation extends BaseInvocation {
24      @NonNull
25      private final FakeState fakeState;
26      @NonNull
27      private final String fakedClassDesc;
28      @NonNull
29      private final String fakedMethodName;
30      @NonNull
31      private final String fakedMethodDesc;
32      boolean proceeding;
33  
34      @NonNull // called by generated bytecode
35      public static FakeInvocation create(@Nullable Object invokedInstance, @Nullable Object[] invokedArguments,
36              @NonNull String fakeClassDesc, @NonNegative int fakeStateIndex, @NonNull String fakedClassDesc,
37              @NonNull String fakedMethodName, @NonNull String fakedMethodDesc) {
38          Object fake = TestRun.getFake(fakeClassDesc, invokedInstance);
39          assert fake != null;
40          FakeState fakeState = TestRun.getFakeStates().getFakeState(fake, fakeStateIndex);
41          Object[] args = invokedArguments == null ? NO_ARGS : invokedArguments;
42          return new FakeInvocation(invokedInstance, args, fakeState, fakedClassDesc, fakedMethodName, fakedMethodDesc);
43      }
44  
45      FakeInvocation(@Nullable Object invokedInstance, @NonNull Object[] invokedArguments, @NonNull FakeState fakeState,
46              @NonNull String fakedClassDesc, @NonNull String fakedMethodName, @NonNull String fakedMethodDesc) {
47          super(invokedInstance, invokedArguments, fakeState.getTimesInvoked());
48          this.fakeState = fakeState;
49          this.fakedClassDesc = fakedClassDesc;
50          this.fakedMethodName = fakedMethodName;
51          this.fakedMethodDesc = fakedMethodDesc;
52      }
53  
54      @NonNull
55      @Override
56      protected Member findRealMember() {
57          Object invokedInstance = getInvokedInstance();
58  
59          if (invokedInstance != null) {
60              Class<?> mockedClass = invokedInstance.getClass();
61              return fakeState.getRealMethodOrConstructor(mockedClass, fakedMethodName, fakedMethodDesc);
62          }
63  
64          return fakeState.getRealMethodOrConstructor(fakedClassDesc, fakedMethodName, fakedMethodDesc);
65      }
66  
67      @SuppressWarnings("WeakerAccess") // called from generated bytecode
68      public boolean shouldProceedIntoConstructor() {
69          if (proceeding && getInvokedMember() instanceof Constructor) {
70              fakeState.clearProceedIndicator();
71              return true;
72          }
73  
74          return false;
75      }
76  
77      @Override
78      public void prepareToProceed() {
79          fakeState.prepareToProceed(this);
80          proceeding = true;
81      }
82  
83      public void prepareToProceedFromNonRecursiveMock() {
84          fakeState.prepareToProceedFromNonRecursiveFake(this);
85          proceeding = true;
86      }
87  
88      @Override
89      public void cleanUpAfterProceed() {
90          fakeState.clearProceedIndicator();
91      }
92  }