All Downloads are FREE. Search and download functionalities are using the official Maven repository.

mockit.internal.SuperConstructorCollector Maven / Gradle / Ivy

Go to download

JMockit is a Java toolkit for automated developer testing. It contains mocking/faking APIs and a code coverage tool, supporting both JUnit and TestNG. The mocking APIs allow all kinds of Java code, without testability restrictions, to be tested in isolation from selected dependencies.

There is a newer version: 1.49
Show newest version
/*
 * Copyright (c) 2006 Rogério Liesenfeld
 * This file is subject to the terms of the MIT license (see LICENSE.txt).
 */
package mockit.internal;

import java.lang.reflect.*;
import java.util.*;

import javax.annotation.*;

import mockit.external.asm.*;
import mockit.internal.util.*;
import static mockit.external.asm.ClassReader.*;

@SuppressWarnings("FieldAccessedSynchronizedAndUnsynchronized")
final class SuperConstructorCollector extends ClassVisitor
{
   @Nonnull static final SuperConstructorCollector INSTANCE = new SuperConstructorCollector();

   @Nonnull private final Map cache = new HashMap();
   @Nullable private String constructorDesc;
   private boolean samePackage;

   private SuperConstructorCollector() {}

   @Nonnull
   synchronized String findConstructor(@Nonnull String classDesc, @Nonnull String superClassDesc)
   {
      constructorDesc = cache.get(superClassDesc);

      if (constructorDesc != null) {
         return constructorDesc;
      }

      findIfBothClassesAreInSamePackage(classDesc, superClassDesc);

      ClassReader cr = ClassFile.readFromFile(superClassDesc);
      try { cr.accept(this, SKIP_DEBUG); } catch (VisitInterruptedException ignore) {}

      cache.put(superClassDesc, constructorDesc);
      
      return constructorDesc;
   }

   private void findIfBothClassesAreInSamePackage(@Nonnull String classDesc, @Nonnull String superClassDesc)
   {
      int p1 = classDesc.lastIndexOf('/');
      int p2 = superClassDesc.lastIndexOf('/');
      samePackage = p1 == p2 && (p1 < 0 || classDesc.substring(0, p1).equals(superClassDesc.substring(0, p2)));
   }

   @Override @Nullable
   public MethodVisitor visitMethod(
      int access, @Nonnull String name, @Nonnull String desc, @Nullable String signature, @Nullable String[] exceptions)
   {
      if (isAccessible(access) && "".equals(name)) {
         constructorDesc = desc;
         throw VisitInterruptedException.INSTANCE;
      }

      return null;
   }

   private boolean isAccessible(int access) { return access != Modifier.PRIVATE && (access != 0 || samePackage); }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy