1
2
3
4
5
6 package mockit.internal;
7
8 import edu.umd.cs.findbugs.annotations.NonNull;
9 import edu.umd.cs.findbugs.annotations.Nullable;
10
11 import java.lang.reflect.Constructor;
12 import java.lang.reflect.Member;
13 import java.lang.reflect.Method;
14
15 import mockit.Invocation;
16 import mockit.internal.reflection.MethodReflection;
17
18 import org.checkerframework.checker.index.qual.NonNegative;
19
20
21
22
23
24 public abstract class BaseInvocation extends Invocation {
25 @Nullable
26 private Member realMember;
27 @Nullable
28 private BaseInvocation previousInvocation;
29
30 protected BaseInvocation(@Nullable Object invokedInstance, @NonNull Object[] invokedArguments,
31 @NonNegative int invocationCount) {
32 super(invokedInstance, invokedArguments, invocationCount);
33 }
34
35 @NonNull
36 public final Member getRealMember() {
37 if (realMember == null) {
38 realMember = findRealMember();
39 }
40
41 return realMember;
42 }
43
44 @NonNull
45 protected abstract Member findRealMember();
46
47 @Nullable
48 public final <T> T doProceed(@Nullable Object[] replacementArguments) {
49 Member memberToInvoke = getRealMember();
50
51 if (memberToInvoke instanceof Constructor) {
52 prepareToProceed();
53 return null;
54 }
55
56 prepareToProceed();
57
58 Method realMethod = (Method) memberToInvoke;
59 Object[] actualArgs = getInvokedArguments();
60
61 if (replacementArguments != null && replacementArguments.length > 0) {
62 actualArgs = replacementArguments;
63 }
64
65 try {
66 return MethodReflection.invoke(getInvokedInstance(), realMethod, actualArgs);
67 } finally {
68 cleanUpAfterProceed();
69 }
70 }
71
72 public abstract void prepareToProceed();
73
74 protected abstract void cleanUpAfterProceed();
75
76 @Nullable
77 public final BaseInvocation getPrevious() {
78 return previousInvocation;
79 }
80
81 public final void setPrevious(@NonNull BaseInvocation previous) {
82 previousInvocation = previous;
83 }
84
85 public final boolean isMethodInSuperclass(@Nullable Object mock, @NonNull String classDesc) {
86 if (mock != null && mock == getInvokedInstance() && getInvokedMember() instanceof Method) {
87 Method methodToInvoke = getInvokedMember();
88 String invokedClassDesc = methodToInvoke.getDeclaringClass().getName().replace('.', '/');
89 return !invokedClassDesc.equals(classDesc);
90 }
91
92 return previousInvocation != null && previousInvocation.isMethodInSuperclass(mock, classDesc);
93 }
94 }