package com.sebastian_daschner.jaxrs_analyzer.analysis.classes;
import com.sebastian_daschner.jaxrs_analyzer.LogProvider;
import com.sebastian_daschner.jaxrs_analyzer.model.Types;
import com.sebastian_daschner.jaxrs_analyzer.model.methods.MethodIdentifier;
import com.sebastian_daschner.jaxrs_analyzer.model.results.MethodResult;
import org.objectweb.asm.ClassReader;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import java.io.IOException;
import static org.objectweb.asm.Opcodes.*;
/**
* @author Sebastian Daschner
*/
public class ProjectMethodClassVisitor extends ClassVisitor {
private final MethodResult methodResult;
private final MethodIdentifier identifier;
private boolean methodFound;
private String superName;
public ProjectMethodClassVisitor(final MethodResult methodResult, final MethodIdentifier identifier) {
super(ASM5);
this.methodResult = methodResult;
this.identifier = identifier;
}
@Override
public void visit(final int version, final int access, final String name, final String signature, final String superName, final String[] interfaces) {
this.superName = superName;
}
@Override
public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
// TODO allow abstract?
final boolean legalModifiers = (access & ACC_ABSTRACT | access & ACC_NATIVE) == 0;
final String methodSignature = identifier.getSignature();
if (legalModifiers && identifier.getMethodName().equals(name) && (methodSignature.equals(desc) || methodSignature.equals(signature))) {
methodFound = true;
return new ProjectMethodVisitor(methodResult, identifier.getContainingClass());
}
return null;
}
@Override
public void visitEnd() {
// if method hasn't been found it may be on a super class (invoke_virtual)
if (!methodFound && !superName.equals(Types.CLASS_OBJECT)) {
try {
final ClassReader classReader = new ContextClassReader(superName);
final ClassVisitor visitor = new ProjectMethodClassVisitor(methodResult, identifier);
classReader.accept(visitor, ClassReader.EXPAND_FRAMES);
} catch (IOException e) {
LogProvider.error("Could not analyze project method " + superName + "#" + identifier.getMethodName());
LogProvider.debug(e);
}
}
}
}