
org.restler.spring.mvc.asm.LocalVariableTableVisitor Maven / Gradle / Ivy
package org.restler.spring.mvc.asm;
import org.objectweb.asm.AnnotationVisitor;
import org.objectweb.asm.Attribute;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.restler.client.RestlerException;
import java.lang.reflect.Member;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
public class LocalVariableTableVisitor implements MethodVisitor {
private static final String CONSTRUCTOR = "";
private final Class> clazz;
private final String name;
private final List arguments;
private Map map;
private boolean isStatic;
private final int[] lvtSlotIndex;
private boolean hasLocalVariableTableInfo;
private final String[] parameterNames;
public LocalVariableTableVisitor(Class> clazz, String name, String desc, Map map, boolean isStatic) {
this.clazz = clazz;
this.name = name;
this.arguments = getArgumentsTypeNames(desc);
this.map = map;
this.isStatic = isStatic;
lvtSlotIndex = computeLvtSlotIndices(isStatic, arguments);
this.parameterNames = new String[arguments.size()];
}
@Override
public AnnotationVisitor visitAnnotationDefault() {
return null;
}
@Override
public AnnotationVisitor visitAnnotation(String s, boolean b) {
return null;
}
@Override
public AnnotationVisitor visitParameterAnnotation(int i, String s, boolean b) {
return null;
}
@Override
public void visitAttribute(Attribute attribute) {
}
@Override
public void visitCode() {
}
@Override
public void visitFrame(int i, int i1, Object[] objects, int i2, Object[] objects1) {
}
@Override
public void visitInsn(int i) {
}
@Override
public void visitIntInsn(int i, int i1) {
}
@Override
public void visitVarInsn(int i, int i1) {
}
@Override
public void visitTypeInsn(int i, String s) {
}
@Override
public void visitFieldInsn(int i, String s, String s1, String s2) {
}
@Override
public void visitMethodInsn(int i, String s, String s1, String s2) {
}
@Override
public void visitJumpInsn(int i, Label label) {
}
@Override
public void visitLabel(Label label) {
}
@Override
public void visitLdcInsn(Object o) {
}
@Override
public void visitIincInsn(int i, int i1) {
}
@Override
public void visitTableSwitchInsn(int i, int i1, Label label, Label[] labels) {
}
@Override
public void visitLookupSwitchInsn(Label label, int[] ints, Label[] labels) {
}
@Override
public void visitMultiANewArrayInsn(String s, int i) {
}
@Override
public void visitTryCatchBlock(Label label, Label label1, Label label2, String s) {
}
@Override
public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
hasLocalVariableTableInfo = true;
for (int i = 0; i < lvtSlotIndex.length; i++) {
if (lvtSlotIndex[i] == index) {
parameterNames[i] = name;
}
}
}
@Override
public void visitLineNumber(int i, Label label) {
}
@Override
public void visitMaxs(int i, int i1) {
}
@Override
public void visitEnd() {
if (hasLocalVariableTableInfo || (isStatic && parameterNames.length == 0)) {
map.put(resolveMember(), parameterNames);
}
}
private Member resolveMember() {
ClassLoader loader = clazz.getClassLoader();
Class>[] argTypes = new Class>[arguments.size()];
for (int i = 0; i < arguments.size(); i++) {
argTypes[i] = ClassUtils.resolveClassName(arguments.get(i), loader);
}
try {
if (CONSTRUCTOR.equals(name)) {
return clazz.getDeclaredConstructor(argTypes);
}
return clazz.getDeclaredMethod(name, argTypes);
}
catch (NoSuchMethodException e) {
throw new RestlerException("Can't resolve method in the class object.", e);
}
}
private int[] computeLvtSlotIndices(boolean isStatic, List paramTypes) {
int[] lvtIndex = new int[paramTypes.size()];
int nextIndex = (isStatic ? 0 : 1);
for (int i = 0; i < paramTypes.size(); i++) {
lvtIndex[i] = nextIndex;
if (isWideType(paramTypes.get(i))) {
nextIndex += 2;
}
else {
nextIndex++;
}
}
return lvtIndex;
}
private boolean isWideType(String typeName) {
// long or double type
return (typeName.equals("J") || typeName.equals("D"));
}
private List getArgumentsTypeNames(String desc) {
List result = new ArrayList<>();
for(int i = 0; i < desc.length(); ) {
if(desc.charAt(i) == '(' || desc.charAt(i) == ';') {
i++;
continue;
} else if(desc.charAt(i) == ')') {
break;
} else if(desc.charAt(i) == '[') {
String typeName = getArrayClassName(desc, i);
result.add(typeName);
i += typeName.length();
} else if(desc.charAt(i) == 'L') {
String typeName = getObjectClassName(desc, i);
result.add(typeName);
i += typeName.length();
} else if(ClassUtils.isPrimitiveType(""+desc.charAt(i))) {
result.add(""+desc.charAt(i));
i++;
}
}
return result;
}
private String getArrayClassName(String desc, int i) {
i += 1;
if(i < desc.length() && ClassUtils.isPrimitiveType("" + desc.charAt(i))) {
return "[" + desc.charAt(i);
}
return "["+getObjectClassName(desc, i);
}
private String getObjectClassName(String desc, int i) {
String typeName = "";
for(; i < desc.length(); ++i) {
if(desc.charAt(i) == ')' || desc.charAt(i) == ';') {
break;
}
typeName += desc.charAt(i);
}
return typeName;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy