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