forked from JavaTX/JavaCompilerCore
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) {
|
||||
MethodVisitor mv = cw.visitMethod(constructor.access() | ACC_PUBLIC, "<init>", constructor.getDescriptor(), constructor.getSignature(), null);
|
||||
if (constructor.txGenerics() != null)
|
||||
mv.visitAttribute(new JavaTXSignatureAttribute(cw.newConst(constructor.getTXSignature())));
|
||||
mv.visitAttribute(new JavaTXSignatureAttribute(constructor.getTXSignature()));
|
||||
|
||||
mv.visitCode();
|
||||
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
|
||||
MethodVisitor mv = cw.visitMethod(method.access() | ACC_PUBLIC, method.name(), method.getDescriptor(), method.getSignature(), null);
|
||||
if (method.txSignature() != null) {
|
||||
mv.visitAttribute(new JavaTXSignatureAttribute(cw.newConst(method.getTXSignature())));
|
||||
mv.visitAttribute(new JavaTXSignatureAttribute(method.getTXSignature()));
|
||||
}
|
||||
|
||||
System.out.println(method.getDescriptor());
|
||||
@ -1060,7 +1060,7 @@ public class Codegen {
|
||||
clazz.implementingInterfaces().stream().map(TargetType::toSignature).toArray(String[]::new)
|
||||
);
|
||||
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.constructors().forEach(this::generateConstructor);
|
||||
|
@ -3,10 +3,13 @@ package de.dhbwstuttgart.bytecode;
|
||||
import org.objectweb.asm.*;
|
||||
|
||||
public class JavaTXSignatureAttribute extends Attribute {
|
||||
final int signature;
|
||||
public String signature;
|
||||
|
||||
protected JavaTXSignatureAttribute(int signature) {
|
||||
public JavaTXSignatureAttribute() {
|
||||
super("JavaTXSignature");
|
||||
}
|
||||
protected JavaTXSignatureAttribute(String signature) {
|
||||
this();
|
||||
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) {
|
||||
var data = new byte[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
|
||||
protected ByteVector write(ClassWriter classWriter, byte[] code, int codeLength, int maxStack, int maxLocals) {
|
||||
var data = new ByteVector();
|
||||
data.putShort(this.signature);
|
||||
data.putShort(classWriter.newConst(this.signature));
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
@ -1,19 +1,16 @@
|
||||
package de.dhbwstuttgart.syntaxtree.factory;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.*;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.Set;
|
||||
import java.lang.reflect.Type;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.*;
|
||||
|
||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||
import de.dhbwstuttgart.bytecode.JavaTXSignatureAttribute;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericContext;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
|
||||
import de.dhbwstuttgart.syntaxtree.Field;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
@ -21,8 +18,11 @@ import de.dhbwstuttgart.syntaxtree.type.Void;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.Block;
|
||||
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.objectweb.asm.*;
|
||||
import org.objectweb.asm.signature.SignatureReader;
|
||||
import org.objectweb.asm.signature.SignatureVisitor;
|
||||
|
||||
/**
|
||||
* Anmerkung:
|
||||
@ -32,21 +32,73 @@ import org.antlr.v4.runtime.Token;
|
||||
public class ASTFactory {
|
||||
|
||||
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());
|
||||
List<Method> methoden = new ArrayList<>();
|
||||
List<de.dhbwstuttgart.syntaxtree.Constructor> konstruktoren = new ArrayList<>();
|
||||
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> allDeclaredMethods = new HashSet<>(Arrays.asList(jreClass.getDeclaredMethods()));
|
||||
Set<java.lang.reflect.Method> allInheritedMethods = new HashSet<>(allMethods);
|
||||
allInheritedMethods.removeAll(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){
|
||||
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<>();
|
||||
for(java.lang.reflect.Field field : jreClass.getDeclaredFields()){
|
||||
@ -72,7 +124,8 @@ public class ASTFactory {
|
||||
for(Type jreInterface : jreClass.getGenericInterfaces()){
|
||||
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
|
||||
|
||||
@ -87,7 +140,7 @@ public class ASTFactory {
|
||||
// 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();
|
||||
RefTypeOrTPHOrWildcardOrGeneric returnType = createType(inClass);
|
||||
Parameter[] jreParams = constructor.getParameters();
|
||||
@ -101,7 +154,7 @@ public class ASTFactory {
|
||||
}
|
||||
ParameterList parameterList = new ParameterList(params, 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();
|
||||
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 */));
|
||||
}
|
||||
|
||||
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();
|
||||
RefTypeOrTPHOrWildcardOrGeneric returnType;
|
||||
Type jreRetType;
|
||||
@ -133,18 +186,53 @@ public class ASTFactory {
|
||||
}
|
||||
ParameterList parameterList = new ParameterList(params, 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();
|
||||
|
||||
return new Method(jreMethod.getModifiers(), name,returnType, parameterList, block, gtvDeclarations, offset, isInherited);
|
||||
}
|
||||
|
||||
public static GenericDeclarationList createGenerics(TypeVariable[] typeParameters, Class context, String methodName){
|
||||
List<de.dhbwstuttgart.syntaxtree.GenericTypeVar> gtvs = new ArrayList<>();
|
||||
for(TypeVariable jreTV : typeParameters){
|
||||
de.dhbwstuttgart.syntaxtree.GenericTypeVar gtv = createGeneric(jreTV, jreTV.getName(), context, methodName);
|
||||
gtvs.add(gtv);
|
||||
}
|
||||
public static GenericDeclarationList createGenerics(String signature, Class context, String methodName){
|
||||
var gtvs = new ArrayList<GenericTypeVar>();
|
||||
var signatureVisitor = new SignatureVisitor(Opcodes.ASM7) {
|
||||
List<RefTypeOrTPHOrWildcardOrGeneric> bounds = new ArrayList<>();
|
||||
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());
|
||||
}
|
||||
|
||||
|
@ -16,6 +16,7 @@ import de.dhbwstuttgart.target.tree.expression.TargetExpression;
|
||||
import de.dhbwstuttgart.target.tree.type.*;
|
||||
import de.dhbwstuttgart.typeinference.constraints.Pair;
|
||||
import de.dhbwstuttgart.typeinference.result.*;
|
||||
import org.objectweb.asm.Attribute;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
Loading…
Reference in New Issue
Block a user