1
2
3
4
5
6 package mockit.internal.faking;
7
8 import static mockit.internal.util.Utilities.getClassType;
9
10 import edu.umd.cs.findbugs.annotations.NonNull;
11 import edu.umd.cs.findbugs.annotations.Nullable;
12
13 import java.lang.reflect.Type;
14
15 import mockit.MockUp;
16 import mockit.asm.classes.ClassReader;
17 import mockit.internal.BaseClassModifier;
18 import mockit.internal.capturing.CaptureOfImplementations;
19
20 public final class CaptureOfFakedImplementations extends CaptureOfImplementations<Void> {
21 private final FakeClassSetup fakeClassSetup;
22
23 public CaptureOfFakedImplementations(@NonNull MockUp<?> fake, @NonNull Type baseType) {
24 Class<?> baseClassType = getClassType(baseType);
25 fakeClassSetup = new FakeClassSetup(baseClassType, baseType, fake, null);
26 }
27
28 @NonNull
29 @Override
30 protected BaseClassModifier createModifier(@Nullable ClassLoader cl, @NonNull ClassReader cr,
31 @NonNull Class<?> baseType, Void typeMetadata) {
32 return fakeClassSetup.createClassModifier(cr);
33 }
34
35 @Override
36 protected void redefineClass(@NonNull Class<?> realClass, @NonNull byte[] modifiedClass) {
37 fakeClassSetup.applyClassModifications(realClass, modifiedClass);
38 }
39
40 @Nullable
41 public <T> Class<T> apply() {
42 @SuppressWarnings("unchecked")
43 Class<T> baseType = (Class<T>) fakeClassSetup.realClass;
44 Class<T> baseClassType = baseType;
45 Class<T> fakedClass = null;
46
47 if (baseType.isInterface()) {
48 fakedClass = new FakedImplementationClass<T>(fakeClassSetup.fake).createImplementation(baseType);
49 baseClassType = fakedClass;
50 }
51
52 if (baseClassType != Object.class) {
53 redefineClass(baseClassType, baseType, null);
54 }
55
56 makeSureAllSubtypesAreModified(baseType, false, null);
57 return fakedClass;
58 }
59 }