org.reflections.scanners.MemberUsageScanner Maven / Gradle / Ivy
Show all versions of swagger-all Show documentation
package org.reflections.scanners;
import com.google.common.base.Joiner;
import javassist.*;
import javassist.bytecode.MethodInfo;
import javassist.expr.*;
import org.reflections.ReflectionsException;
import org.reflections.util.ClasspathHelper;
/** scans methods/constructors/fields usage
* depends on {@link org.reflections.adapters.JavassistAdapter} configured */
@SuppressWarnings("unchecked")
public class MemberUsageScanner extends AbstractScanner {
private ClassPool classPool;
@Override
public void scan(Object cls) {
try {
CtClass ctClass = getClassPool().get(getMetadataAdapter().getClassName(cls));
for (CtBehavior member : ctClass.getDeclaredConstructors()) {
scanMember(member);
}
for (CtBehavior member : ctClass.getDeclaredMethods()) {
scanMember(member);
}
ctClass.detach();
} catch (Exception e) {
throw new ReflectionsException("Could not scan method usage for " + getMetadataAdapter().getClassName(cls), e);
}
}
void scanMember(CtBehavior member) throws CannotCompileException {
//key contains this$/val$ means local field/parameter closure
final String key = member.getDeclaringClass().getName() + "." + member.getMethodInfo().getName() +
"(" + parameterNames(member.getMethodInfo()) + ")"; //+ " #" + member.getMethodInfo().getLineNumber(0)
member.instrument(new ExprEditor() {
@Override
public void edit(NewExpr e) throws CannotCompileException {
try {
put(e.getConstructor().getDeclaringClass().getName() + "." + "" +
"(" + parameterNames(e.getConstructor().getMethodInfo()) + ")", e.getLineNumber(), key);
} catch (NotFoundException e1) {
throw new ReflectionsException("Could not find new instance usage in " + key, e1);
}
}
@Override
public void edit(MethodCall m) throws CannotCompileException {
try {
put(m.getMethod().getDeclaringClass().getName() + "." + m.getMethodName() +
"(" + parameterNames(m.getMethod().getMethodInfo()) + ")", m.getLineNumber(), key);
} catch (NotFoundException e) {
throw new ReflectionsException("Could not find member " + m.getClassName() + " in " + key, e);
}
}
@Override
public void edit(ConstructorCall c) throws CannotCompileException {
try {
put(c.getConstructor().getDeclaringClass().getName() + "." + "" +
"(" + parameterNames(c.getConstructor().getMethodInfo()) + ")", c.getLineNumber(), key);
} catch (NotFoundException e) {
throw new ReflectionsException("Could not find member " + c.getClassName() + " in " + key, e);
}
}
@Override
public void edit(FieldAccess f) throws CannotCompileException {
try {
put(f.getField().getDeclaringClass().getName() + "." + f.getFieldName(), f.getLineNumber(), key);
} catch (NotFoundException e) {
throw new ReflectionsException("Could not find member " + f.getFieldName() + " in " + key, e);
}
}
});
}
private void put(String key, int lineNumber, String value) {
if (acceptResult(key)) {
getStore().put(key, value + " #" + lineNumber);
}
}
String parameterNames(MethodInfo info) {
return Joiner.on(", ").join(getMetadataAdapter().getParameterNames(info));
}
private ClassPool getClassPool() {
if (classPool == null) {
synchronized (this) {
classPool = new ClassPool();
ClassLoader[] classLoaders = getConfiguration().getClassLoaders();
if (classLoaders == null) {
classLoaders = ClasspathHelper.classLoaders();
}
for (ClassLoader classLoader : classLoaders) {
classPool.appendClassPath(new LoaderClassPath(classLoader));
}
}
}
return classPool;
}
}