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