/* * Copyright (c) 2006-2011 Rogério Liesenfeld * This file is subject to the terms of the MIT license (see LICENSE.txt). */ package mockit.internal.util; import java.io.*; import java.util.*; import mockit.external.asm.*; import mockit.external.asm.commons.*; import mockit.internal.*; public final class SuperConstructorCollector extends EmptyVisitor { public static final SuperConstructorCollector INSTANCE = new SuperConstructorCollector(); private final Map<String, String> cache = new HashMap<String, String>(); @SuppressWarnings({"FieldAccessedSynchronizedAndUnsynchronized"}) private String constructorDesc; private SuperConstructorCollector() {} public synchronized String findConstructor(String className) { constructorDesc = cache.get(className); if (constructorDesc != null) { return constructorDesc; } ClassReader cr = createClassReader(className); try { cr.accept(this, true); } catch (VisitInterruptedException ignore) {} cache.put(className, constructorDesc); return constructorDesc; } private ClassReader createClassReader(String className) { try { return ClassFile.readClass(className); } catch (IOException e) { throw new RuntimeException("Failed to read class file for " + className, e); } } @Override public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { if ("<init>".equals(name)) { constructorDesc = desc; throw VisitInterruptedException.INSTANCE; } return null; } @Override public FieldVisitor visitField(int access, String name, String desc, String signature, Object value) { return null; } }