wip
This commit is contained in:
1 parent
b805eed622
commit
74a8f56ab5
7 files changed
+681
-212
No files matched your search
@@ -54,7 +54,7 @@ class ClassAnalyzerVisitor extends ClassVisitor {
|
||||
var type = Type.getMethodType(descriptor);
|
||||
var returnClassName = type.getReturnType().getClassName();
|
||||
var parameterClassNames = Arrays.stream(type.getArgumentTypes()).map(Type::getClassName).toArray(String[]::new);
|
||||
return new MethodAnalyzerVisitor(Opcodes.ASM9, className, name, returnClassName, parameterClassNames, entityAccess -> {
|
||||
return new MethodAnalyzerVisitor(Opcodes.ASM9, className, name, access, returnClassName, parameterClassNames, entityAccess -> {
|
||||
declaredConstructor.addAll(entityAccess.getDeclaredConstructors());
|
||||
declaredGetters.addAll(entityAccess.getDeclaredGetters());
|
||||
declaredSetters.addAll(entityAccess.getDeclaredSetters());
|
||||
|
||||
@@ -6,6 +6,7 @@ import jef.asm.access.model.ConstructorParameterDescription;
|
||||
import jef.asm.access.model.GetterDescription;
|
||||
import jef.asm.access.model.SetterDescription;
|
||||
import jef.asm.access.model.SuperConstructorParameterDescription;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import org.objectweb.asm.Handle;
|
||||
import org.objectweb.asm.Label;
|
||||
@@ -14,6 +15,7 @@ import org.objectweb.asm.Opcodes;
|
||||
import org.objectweb.asm.Type;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.Stack;
|
||||
@@ -22,14 +24,15 @@ import java.util.function.Consumer;
|
||||
@Getter
|
||||
public class MethodAnalyzerVisitor extends MethodVisitor {//TODO verify param count
|
||||
private final Consumer<ClassDescription> callback;
|
||||
private final String methodClassName;
|
||||
private final String declaringClassName;
|
||||
private final String methodName;
|
||||
private final int access;
|
||||
private final String returnClassName;
|
||||
private final String[] parameterClassNames;
|
||||
private final String[] parameterClassNames;
|
||||
|
||||
private List<ConstructorParameterDescription> constructorParameterDescriptions = new ArrayList<>();
|
||||
private List<SuperConstructorParameterDescription> superConstructorParameterDescriptions = new ArrayList<>();
|
||||
private Stack<Integer> varIndexStack = new Stack<>();
|
||||
private Stack<Var> varStack = new Stack<>();
|
||||
private String fieldDeclaringClassName = null;
|
||||
private String fieldName = null;
|
||||
|
||||
@@ -69,12 +72,19 @@ public class MethodAnalyzerVisitor extends MethodVisitor {//TODO verify param co
|
||||
INVALID
|
||||
}
|
||||
|
||||
protected MethodAnalyzerVisitor(int api, String methodClassName, String methodName, String returnClassName, String[] parameterClassNames, Consumer<ClassDescription> callback) {
|
||||
protected MethodAnalyzerVisitor(int api, String declaringClassName, String methodName, int access, String returnClassName, String[] parameterClassNames, Consumer<ClassDescription> callback) {
|
||||
super(api);
|
||||
this.methodClassName = methodClassName;
|
||||
this.declaringClassName = declaringClassName;
|
||||
this.methodName = methodName;
|
||||
this.access = access;
|
||||
this.returnClassName = returnClassName;
|
||||
this.parameterClassNames = parameterClassNames;
|
||||
if (hasThis()) {
|
||||
this.parameterClassNames = new String[parameterClassNames.length + 1];
|
||||
System.arraycopy(parameterClassNames, 0, this.parameterClassNames, 1, parameterClassNames.length);
|
||||
this.parameterClassNames[0] = declaringClassName;
|
||||
} else {
|
||||
this.parameterClassNames = parameterClassNames;
|
||||
}
|
||||
this.callback = callback;
|
||||
}
|
||||
|
||||
@@ -122,7 +132,11 @@ public class MethodAnalyzerVisitor extends MethodVisitor {//TODO verify param co
|
||||
@Override
|
||||
public void visitVarInsn(int opcode, int varIndex) {
|
||||
if (Set.of(Opcodes.ILOAD, Opcodes.LLOAD, Opcodes.FLOAD, Opcodes.DLOAD, Opcodes.ALOAD).contains(opcode)) {
|
||||
varIndexStack.push(varIndex);
|
||||
System.out.println(methodName + ": load_" + varIndex + ": " + (varIndex < parameterClassNames.length ? parameterClassNames[varIndex] : null));
|
||||
if (varIndex == 5) {
|
||||
int x = 0;
|
||||
}
|
||||
varStack.push(new Var(varIndex < parameterClassNames.length ? parameterClassNames[varIndex] : null, varIndex));
|
||||
}
|
||||
if (opcode == Opcodes.ALOAD && varIndex == 0) {
|
||||
if (constructorStep == ConstructorSteps.CODE) {
|
||||
@@ -160,6 +174,10 @@ public class MethodAnalyzerVisitor extends MethodVisitor {//TODO verify param co
|
||||
super.visitVarInsn(opcode, varIndex);
|
||||
}
|
||||
|
||||
private boolean hasThis() {
|
||||
return (access & Opcodes.ACC_STATIC) == 0;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitTypeInsn(int opcode, String type) {
|
||||
constructorStep = ConstructorSteps.INVALID;
|
||||
@@ -170,15 +188,15 @@ public class MethodAnalyzerVisitor extends MethodVisitor {//TODO verify param co
|
||||
|
||||
@Override
|
||||
public void visitFieldInsn(int opcode, String owner, String name, String descriptor) {
|
||||
var lastLoadedVarIndex = -1;
|
||||
Var lastLoadedVar = null;
|
||||
if (opcode == Opcodes.PUTFIELD) {
|
||||
lastLoadedVarIndex = varIndexStack.pop();
|
||||
varIndexStack.pop();
|
||||
lastLoadedVar = varStack.pop();
|
||||
varStack.pop();
|
||||
constructorStep = constructorStep == ConstructorSteps.VAR_LOAD ? ConstructorSteps.PUT_FIELD : ConstructorSteps.INVALID;
|
||||
getterStep = GetterSteps.INVALID;
|
||||
setterStep = setterStep == SetterSteps.VAR_LOAD ? SetterSteps.PUT_FIELD : SetterSteps.INVALID;
|
||||
} else if (opcode == Opcodes.GETFIELD) {
|
||||
lastLoadedVarIndex = varIndexStack.pop();
|
||||
lastLoadedVar = varStack.pop();
|
||||
constructorStep = ConstructorSteps.INVALID;
|
||||
getterStep = getterStep == GetterSteps.ALOAD_0 ? GetterSteps.GET_FIELD : GetterSteps.INVALID;
|
||||
setterStep = SetterSteps.INVALID;
|
||||
@@ -189,21 +207,21 @@ public class MethodAnalyzerVisitor extends MethodVisitor {//TODO verify param co
|
||||
}
|
||||
this.fieldDeclaringClassName = owner.replace("/", ".");
|
||||
this.fieldName = name;
|
||||
this.constructorParameterDescriptions.add(new ConstructorParameterDescription(lastLoadedVarIndex - 1, this.fieldDeclaringClassName, this.fieldName)); //lastLoadedVarIndex - 1 because arg 0 of an instance function is always this
|
||||
this.constructorParameterDescriptions.add(new ConstructorParameterDescription(lastLoadedVar.getIndex() - 1, lastLoadedVar.getClassName(), this.fieldDeclaringClassName, this.fieldName)); //lastLoadedVar - 1 because arg 0 of an instance function is always this
|
||||
super.visitFieldInsn(opcode, owner, name, descriptor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitMethodInsn(int opcode, String owner, String name, String descriptor, boolean isInterface) {
|
||||
var argIndexes = new ArrayList<Integer>();
|
||||
var args = new ArrayList<Var>();
|
||||
for (var i = 0; i < Type.getArgumentTypes(descriptor).length; i++) {
|
||||
argIndexes.add(0, varIndexStack.pop());
|
||||
args.add(0, varStack.pop());
|
||||
}
|
||||
varIndexStack.pop(); // also pop ALOAD0
|
||||
varStack.pop(); // also pop ALOAD0
|
||||
if (opcode == Opcodes.INVOKESPECIAL && name.equals("<init>") //TODO does it have to be called '<init>' or is this just convention
|
||||
&& Set.of(ConstructorSteps.PRE_SUPER_INIT_ALOAD_0, ConstructorSteps.PRE_SUPER_INIT_VAR_LOAD).contains(constructorStep)) {
|
||||
for (int i = 0; i < argIndexes.size(); i++) {
|
||||
superConstructorParameterDescriptions.add(new SuperConstructorParameterDescription(argIndexes.get(i), i));
|
||||
&& Set.of(ConstructorSteps.PRE_SUPER_INIT_ALOAD_0, ConstructorSteps.PRE_SUPER_INIT_VAR_LOAD).contains(constructorStep)) {
|
||||
for (int i = 0; i < args.size(); i++) {
|
||||
superConstructorParameterDescriptions.add(new SuperConstructorParameterDescription(args.get(i).getIndex(), i));
|
||||
}
|
||||
constructorStep = ConstructorSteps.SUPER_INIT;
|
||||
} else {
|
||||
@@ -232,9 +250,6 @@ public class MethodAnalyzerVisitor extends MethodVisitor {//TODO verify param co
|
||||
|
||||
@Override
|
||||
public void visitLabel(Label label) {
|
||||
// constructorStep = ConstructorSteps.INVALID;
|
||||
// getterStep = GetterSteps.INVALID;
|
||||
// setterStep = SetterSteps.INVALID;
|
||||
super.visitLabel(label);
|
||||
}
|
||||
|
||||
@@ -300,9 +315,16 @@ public class MethodAnalyzerVisitor extends MethodVisitor {//TODO verify param co
|
||||
public void visitEnd() {
|
||||
super.visitEnd();
|
||||
List<ConstructorDescription> constructors = constructorStep == ConstructorSteps.RETURN ? List.of(new ConstructorDescription(constructorParameterDescriptions, superConstructorParameterDescriptions)) : List.of();
|
||||
List<GetterDescription> getters = getterStep == GetterSteps.RETURN ? List.of(new GetterDescription(methodClassName, methodName, returnClassName, parameterClassNames, fieldDeclaringClassName, fieldName)) : List.of();
|
||||
List<SetterDescription> setters = setterStep == SetterSteps.RETURN ? List.of(new SetterDescription(methodClassName, methodName, returnClassName, parameterClassNames, fieldDeclaringClassName, fieldName)) : List.of();
|
||||
List<GetterDescription> getters = getterStep == GetterSteps.RETURN ? List.of(new GetterDescription(declaringClassName, methodName, returnClassName, Arrays.stream(parameterClassNames).skip(hasThis() ? 1 : 0).toArray(String[]::new), fieldDeclaringClassName, fieldName)) : List.of();
|
||||
List<SetterDescription> setters = setterStep == SetterSteps.RETURN ? List.of(new SetterDescription(declaringClassName, methodName, returnClassName, Arrays.stream(parameterClassNames).skip(hasThis() ? 1 : 0).toArray(String[]::new), fieldDeclaringClassName, fieldName)) : List.of();
|
||||
var access = new ClassDescription(null, null, null, constructors, getters, setters);
|
||||
callback.accept(access);
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
private static class Var {
|
||||
private final String className;
|
||||
private final int index;
|
||||
}
|
||||
}
|
||||
@@ -9,6 +9,7 @@ import lombok.ToString;
|
||||
@ToString
|
||||
public class ConstructorParameterDescription {
|
||||
private final int parameterIndex;
|
||||
private final String parameterClassName;
|
||||
private final String declaringClassName;
|
||||
private final String fieldName;
|
||||
}
|
||||
@@ -15,7 +15,7 @@ public @interface Generated {
|
||||
enum Type {
|
||||
NONE,//no value is generated
|
||||
IDENTITY,//value is generated on insert
|
||||
// COMPUTED,//value is generated on insert and update
|
||||
COMPUTED,//value is generated on insert and update
|
||||
;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user