Start working on signature parsing
This commit is contained in:
parent
02c8dd9804
commit
39bde24df7
@ -1000,7 +1000,7 @@ public class Codegen {
|
|||||||
private void generateConstructor(TargetConstructor constructor) {
|
private void generateConstructor(TargetConstructor constructor) {
|
||||||
MethodVisitor mv = cw.visitMethod(constructor.access() | ACC_PUBLIC, "<init>", constructor.getDescriptor(), constructor.getSignature(), null);
|
MethodVisitor mv = cw.visitMethod(constructor.access() | ACC_PUBLIC, "<init>", constructor.getDescriptor(), constructor.getSignature(), null);
|
||||||
if (constructor.txGenerics() != null)
|
if (constructor.txGenerics() != null)
|
||||||
mv.visitAttribute(new JavaTXSignatureAttribute(cw.newConst(constructor.getTXSignature())));
|
mv.visitAttribute(new JavaTXSignatureAttribute(constructor.getTXSignature()));
|
||||||
|
|
||||||
mv.visitCode();
|
mv.visitCode();
|
||||||
var state = new State(null, mv, 1);
|
var state = new State(null, mv, 1);
|
||||||
@ -1027,7 +1027,7 @@ public class Codegen {
|
|||||||
// TODO The older codegen has set ACC_PUBLIC for all methods, good for testing but bad for everything else
|
// TODO The older codegen has set ACC_PUBLIC for all methods, good for testing but bad for everything else
|
||||||
MethodVisitor mv = cw.visitMethod(method.access() | ACC_PUBLIC, method.name(), method.getDescriptor(), method.getSignature(), null);
|
MethodVisitor mv = cw.visitMethod(method.access() | ACC_PUBLIC, method.name(), method.getDescriptor(), method.getSignature(), null);
|
||||||
if (method.txSignature() != null) {
|
if (method.txSignature() != null) {
|
||||||
mv.visitAttribute(new JavaTXSignatureAttribute(cw.newConst(method.getTXSignature())));
|
mv.visitAttribute(new JavaTXSignatureAttribute(method.getTXSignature()));
|
||||||
}
|
}
|
||||||
|
|
||||||
System.out.println(method.getDescriptor());
|
System.out.println(method.getDescriptor());
|
||||||
@ -1060,7 +1060,7 @@ public class Codegen {
|
|||||||
clazz.implementingInterfaces().stream().map(TargetType::toSignature).toArray(String[]::new)
|
clazz.implementingInterfaces().stream().map(TargetType::toSignature).toArray(String[]::new)
|
||||||
);
|
);
|
||||||
if (clazz.txGenerics() != null)
|
if (clazz.txGenerics() != null)
|
||||||
cw.visitAttribute(new JavaTXSignatureAttribute(cw.newConst(generateSignature(clazz, clazz.txGenerics()))));
|
cw.visitAttribute(new JavaTXSignatureAttribute(generateSignature(clazz, clazz.txGenerics())));
|
||||||
|
|
||||||
clazz.fields().forEach(this::generateField);
|
clazz.fields().forEach(this::generateField);
|
||||||
clazz.constructors().forEach(this::generateConstructor);
|
clazz.constructors().forEach(this::generateConstructor);
|
||||||
|
@ -3,10 +3,13 @@ package de.dhbwstuttgart.bytecode;
|
|||||||
import org.objectweb.asm.*;
|
import org.objectweb.asm.*;
|
||||||
|
|
||||||
public class JavaTXSignatureAttribute extends Attribute {
|
public class JavaTXSignatureAttribute extends Attribute {
|
||||||
final int signature;
|
public String signature;
|
||||||
|
|
||||||
protected JavaTXSignatureAttribute(int signature) {
|
public JavaTXSignatureAttribute() {
|
||||||
super("JavaTXSignature");
|
super("JavaTXSignature");
|
||||||
|
}
|
||||||
|
protected JavaTXSignatureAttribute(String signature) {
|
||||||
|
this();
|
||||||
this.signature = signature;
|
this.signature = signature;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -14,13 +17,14 @@ public class JavaTXSignatureAttribute extends Attribute {
|
|||||||
protected Attribute read(ClassReader classReader, int offset, int length, char[] charBuffer, int codeAttributeOffset, Label[] labels) {
|
protected Attribute read(ClassReader classReader, int offset, int length, char[] charBuffer, int codeAttributeOffset, Label[] labels) {
|
||||||
var data = new byte[length];
|
var data = new byte[length];
|
||||||
System.arraycopy(classReader.b, offset, data, 0, length);
|
System.arraycopy(classReader.b, offset, data, 0, length);
|
||||||
return new JavaTXSignatureAttribute(data[0] << 8 | data[1]);
|
var constantPoolOffset = data[0] << 8 | data[1];
|
||||||
|
return new JavaTXSignatureAttribute((String) classReader.readConst(constantPoolOffset, charBuffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected ByteVector write(ClassWriter classWriter, byte[] code, int codeLength, int maxStack, int maxLocals) {
|
protected ByteVector write(ClassWriter classWriter, byte[] code, int codeLength, int maxStack, int maxLocals) {
|
||||||
var data = new ByteVector();
|
var data = new ByteVector();
|
||||||
data.putShort(this.signature);
|
data.putShort(classWriter.newConst(this.signature));
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,16 @@
|
|||||||
package de.dhbwstuttgart.syntaxtree.factory;
|
package de.dhbwstuttgart.syntaxtree.factory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
import java.lang.reflect.*;
|
import java.lang.reflect.*;
|
||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.util.ArrayList;
|
import java.lang.reflect.Type;
|
||||||
import java.util.Arrays;
|
import java.nio.file.Files;
|
||||||
import java.util.HashSet;
|
import java.nio.file.Path;
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.bytecode.JavaTXSignatureAttribute;
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericContext;
|
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.Field;
|
import de.dhbwstuttgart.syntaxtree.Field;
|
||||||
import de.dhbwstuttgart.syntaxtree.Method;
|
import de.dhbwstuttgart.syntaxtree.Method;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||||
@ -21,8 +18,11 @@ import de.dhbwstuttgart.syntaxtree.type.Void;
|
|||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
||||||
import de.dhbwstuttgart.syntaxtree.type.WildcardType;
|
import de.dhbwstuttgart.util.Pair;
|
||||||
import org.antlr.v4.runtime.Token;
|
import org.antlr.v4.runtime.Token;
|
||||||
|
import org.objectweb.asm.*;
|
||||||
|
import org.objectweb.asm.signature.SignatureReader;
|
||||||
|
import org.objectweb.asm.signature.SignatureVisitor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Anmerkung:
|
* Anmerkung:
|
||||||
@ -32,21 +32,73 @@ import org.antlr.v4.runtime.Token;
|
|||||||
public class ASTFactory {
|
public class ASTFactory {
|
||||||
|
|
||||||
public static ClassOrInterface createClass(java.lang.Class jreClass){
|
public static ClassOrInterface createClass(java.lang.Class jreClass){
|
||||||
|
|
||||||
|
// TODO Inner classes
|
||||||
|
|
||||||
|
var methodSignatures = new HashMap<Pair<String, String>, String>();
|
||||||
|
String classSignature = null;
|
||||||
|
|
||||||
|
// Load class with asm to figure out if there's a JavaTX signature
|
||||||
|
try {
|
||||||
|
var bytes = Files.readAllBytes(Path.of(jreClass.getProtectionDomain().getCodeSource().getLocation().getPath()));
|
||||||
|
var classReader = new ClassReader(bytes);
|
||||||
|
|
||||||
|
var classVisitor = new ClassVisitor(Opcodes.ASM7) {
|
||||||
|
String classSignature;
|
||||||
|
@Override
|
||||||
|
public void visitAttribute(Attribute attribute) {
|
||||||
|
if (attribute.type.equals("JavaTXSignature")) {
|
||||||
|
classSignature = ((JavaTXSignatureAttribute) attribute).signature;
|
||||||
|
}
|
||||||
|
super.visitAttribute(attribute);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
|
||||||
|
classSignature = signature;
|
||||||
|
super.visit(version, access, name, signature, superName, interfaces);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public MethodVisitor visitMethod(int access, String name, String descriptor, String signature, String[] exceptions) {
|
||||||
|
|
||||||
|
methodSignatures.put(new Pair<>(name, descriptor), signature);
|
||||||
|
return new MethodVisitor(Opcodes.ASM7) {
|
||||||
|
@Override
|
||||||
|
public void visitAttribute(Attribute attribute) {
|
||||||
|
if (attribute.type.equals("JavaTXSignature")) {
|
||||||
|
methodSignatures.put(new Pair<>(name, descriptor), ((JavaTXSignatureAttribute) attribute).signature);
|
||||||
|
}
|
||||||
|
super.visitAttribute(attribute);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
classReader.accept(classVisitor, new Attribute[]{new JavaTXSignatureAttribute()}, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
|
||||||
|
classSignature = classVisitor.classSignature;
|
||||||
|
} catch (IOException e) {
|
||||||
|
// Skip
|
||||||
|
}
|
||||||
|
|
||||||
JavaClassName name = new JavaClassName(jreClass.getName());
|
JavaClassName name = new JavaClassName(jreClass.getName());
|
||||||
List<Method> methoden = new ArrayList<>();
|
List<Method> methoden = new ArrayList<>();
|
||||||
List<de.dhbwstuttgart.syntaxtree.Constructor> konstruktoren = new ArrayList<>();
|
List<de.dhbwstuttgart.syntaxtree.Constructor> konstruktoren = new ArrayList<>();
|
||||||
for(java.lang.reflect.Constructor constructor : jreClass.getConstructors()){
|
for(java.lang.reflect.Constructor constructor : jreClass.getConstructors()){
|
||||||
createConstructor(constructor, jreClass).map(c -> konstruktoren.add(c));
|
var signature = methodSignatures.get(new Pair<>(constructor.getName(), org.objectweb.asm.Type.getConstructorDescriptor(constructor)));
|
||||||
|
createConstructor(constructor, signature, jreClass).map(c -> konstruktoren.add(c));
|
||||||
}
|
}
|
||||||
Set<java.lang.reflect.Method> allMethods = new HashSet<>(Arrays.asList(jreClass.getMethods()));
|
Set<java.lang.reflect.Method> allMethods = new HashSet<>(Arrays.asList(jreClass.getMethods()));
|
||||||
Set<java.lang.reflect.Method> allDeclaredMethods = new HashSet<>(Arrays.asList(jreClass.getDeclaredMethods()));
|
Set<java.lang.reflect.Method> allDeclaredMethods = new HashSet<>(Arrays.asList(jreClass.getDeclaredMethods()));
|
||||||
Set<java.lang.reflect.Method> allInheritedMethods = new HashSet<>(allMethods);
|
Set<java.lang.reflect.Method> allInheritedMethods = new HashSet<>(allMethods);
|
||||||
allInheritedMethods.removeAll(allDeclaredMethods);
|
allInheritedMethods.removeAll(allDeclaredMethods);
|
||||||
for(java.lang.reflect.Method method : allDeclaredMethods){
|
for(java.lang.reflect.Method method : allDeclaredMethods){
|
||||||
methoden.add(createMethod(method, jreClass, false));
|
var signature = methodSignatures.get(new Pair<>(method.getName(), org.objectweb.asm.Type.getMethodDescriptor(method)));
|
||||||
|
methoden.add(createMethod(method, signature, jreClass, false));
|
||||||
}
|
}
|
||||||
for(java.lang.reflect.Method method : allInheritedMethods){
|
for(java.lang.reflect.Method method : allInheritedMethods){
|
||||||
methoden.add(createMethod(method, jreClass, true));
|
var signature = methodSignatures.get(new Pair<>(method.getName(), org.objectweb.asm.Type.getMethodDescriptor(method)));
|
||||||
|
methoden.add(createMethod(method, signature, jreClass, true));
|
||||||
}
|
}
|
||||||
List<Field> felder = new ArrayList<>();
|
List<Field> felder = new ArrayList<>();
|
||||||
for(java.lang.reflect.Field field : jreClass.getDeclaredFields()){
|
for(java.lang.reflect.Field field : jreClass.getDeclaredFields()){
|
||||||
@ -72,7 +124,8 @@ public class ASTFactory {
|
|||||||
for(Type jreInterface : jreClass.getGenericInterfaces()){
|
for(Type jreInterface : jreClass.getGenericInterfaces()){
|
||||||
implementedInterfaces.add((RefType) createType(jreInterface));
|
implementedInterfaces.add((RefType) createType(jreInterface));
|
||||||
}
|
}
|
||||||
GenericDeclarationList genericDeclarationList = createGenerics(jreClass.getTypeParameters(), jreClass, null);
|
|
||||||
|
GenericDeclarationList genericDeclarationList = createGenerics(classSignature, jreClass, null);
|
||||||
|
|
||||||
Token offset = new NullToken(); //Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde
|
Token offset = new NullToken(); //Braucht keinen Offset, da diese Klasse nicht aus einem Quellcode geparst wurde
|
||||||
|
|
||||||
@ -87,7 +140,7 @@ public class ASTFactory {
|
|||||||
// return createClass(classType).getType();
|
// return createClass(classType).getType();
|
||||||
//}
|
//}
|
||||||
|
|
||||||
private static Optional<de.dhbwstuttgart.syntaxtree.Constructor> createConstructor(Constructor constructor, Class inClass) {
|
private static Optional<de.dhbwstuttgart.syntaxtree.Constructor> createConstructor(Constructor constructor, String signature, Class inClass) {
|
||||||
String name = constructor.getName();
|
String name = constructor.getName();
|
||||||
RefTypeOrTPHOrWildcardOrGeneric returnType = createType(inClass);
|
RefTypeOrTPHOrWildcardOrGeneric returnType = createType(inClass);
|
||||||
Parameter[] jreParams = constructor.getParameters();
|
Parameter[] jreParams = constructor.getParameters();
|
||||||
@ -101,7 +154,7 @@ public class ASTFactory {
|
|||||||
}
|
}
|
||||||
ParameterList parameterList = new ParameterList(params, new NullToken());
|
ParameterList parameterList = new ParameterList(params, new NullToken());
|
||||||
Block block = new Block(new ArrayList<Statement>(), new NullToken());
|
Block block = new Block(new ArrayList<Statement>(), new NullToken());
|
||||||
GenericDeclarationList gtvDeclarations = createGenerics(constructor.getTypeParameters(), inClass, constructor.getName());
|
GenericDeclarationList gtvDeclarations = createGenerics(signature, inClass, constructor.getName());
|
||||||
Token offset = new NullToken();
|
Token offset = new NullToken();
|
||||||
int modifier = constructor.getModifiers();
|
int modifier = constructor.getModifiers();
|
||||||
|
|
||||||
@ -112,7 +165,7 @@ public class ASTFactory {
|
|||||||
return Optional.of(new de.dhbwstuttgart.syntaxtree.Constructor(modifier, name,returnType, parameterList, block, gtvDeclarations, offset /*, new ArrayList<>() geloescht PL 2018-11-24 */));
|
return Optional.of(new de.dhbwstuttgart.syntaxtree.Constructor(modifier, name,returnType, parameterList, block, gtvDeclarations, offset /*, new ArrayList<>() geloescht PL 2018-11-24 */));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass, Boolean isInherited){
|
public static Method createMethod(java.lang.reflect.Method jreMethod, String signature, java.lang.Class inClass, Boolean isInherited){
|
||||||
String name = jreMethod.getName();
|
String name = jreMethod.getName();
|
||||||
RefTypeOrTPHOrWildcardOrGeneric returnType;
|
RefTypeOrTPHOrWildcardOrGeneric returnType;
|
||||||
Type jreRetType;
|
Type jreRetType;
|
||||||
@ -133,18 +186,53 @@ public class ASTFactory {
|
|||||||
}
|
}
|
||||||
ParameterList parameterList = new ParameterList(params, new NullToken());
|
ParameterList parameterList = new ParameterList(params, new NullToken());
|
||||||
Block block = new Block(new ArrayList<Statement>(), new NullToken());
|
Block block = new Block(new ArrayList<Statement>(), new NullToken());
|
||||||
GenericDeclarationList gtvDeclarations = createGenerics(jreMethod.getTypeParameters(), inClass, jreMethod.getName());
|
GenericDeclarationList gtvDeclarations = createGenerics(signature, inClass, jreMethod.getName());
|
||||||
Token offset = new NullToken();
|
Token offset = new NullToken();
|
||||||
|
|
||||||
return new Method(jreMethod.getModifiers(), name,returnType, parameterList, block, gtvDeclarations, offset, isInherited);
|
return new Method(jreMethod.getModifiers(), name,returnType, parameterList, block, gtvDeclarations, offset, isInherited);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GenericDeclarationList createGenerics(TypeVariable[] typeParameters, Class context, String methodName){
|
public static GenericDeclarationList createGenerics(String signature, Class context, String methodName){
|
||||||
List<de.dhbwstuttgart.syntaxtree.GenericTypeVar> gtvs = new ArrayList<>();
|
var gtvs = new ArrayList<GenericTypeVar>();
|
||||||
for(TypeVariable jreTV : typeParameters){
|
var signatureVisitor = new SignatureVisitor(Opcodes.ASM7) {
|
||||||
de.dhbwstuttgart.syntaxtree.GenericTypeVar gtv = createGeneric(jreTV, jreTV.getName(), context, methodName);
|
List<RefTypeOrTPHOrWildcardOrGeneric> bounds = new ArrayList<>();
|
||||||
gtvs.add(gtv);
|
Stack<RefTypeOrTPHOrWildcardOrGeneric> bound = new Stack<>();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitFormalTypeParameter(String name) {
|
||||||
|
bounds = new ArrayList<>();
|
||||||
|
gtvs.add(new GenericTypeVar(name, bounds, new NullToken(), new NullToken()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitTypeVariable(String name) {
|
||||||
|
((RefType) bound.peek()).getParaList().add(new GenericRefType(name, new NullToken()));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitClassType(String name) {
|
||||||
|
var currentBound = new RefType(new JavaClassName(name), new ArrayList<>(), new NullToken());
|
||||||
|
bound.push(currentBound);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public SignatureVisitor visitTypeArgument(char wildcard) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitEnd() {
|
||||||
|
var last = bound.pop();
|
||||||
|
if (bound.empty()) bounds.add(last);
|
||||||
|
else {
|
||||||
|
((RefType) bound.peek()).getParaList().add(last);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
var sr = new SignatureReader(signature);
|
||||||
|
sr.accept(signatureVisitor);
|
||||||
|
|
||||||
return new GenericDeclarationList(gtvs,new NullToken());
|
return new GenericDeclarationList(gtvs,new NullToken());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ import de.dhbwstuttgart.target.tree.expression.TargetExpression;
|
|||||||
import de.dhbwstuttgart.target.tree.type.*;
|
import de.dhbwstuttgart.target.tree.type.*;
|
||||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||||
import de.dhbwstuttgart.typeinference.result.*;
|
import de.dhbwstuttgart.typeinference.result.*;
|
||||||
|
import org.objectweb.asm.Attribute;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
Loading…
Reference in New Issue
Block a user