View Javadoc
1   /*
2    * MIT License
3    * Copyright (c) 2006-2025 JMockit developers
4    * See LICENSE file for full license text.
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  }