This commit is contained in:
JanUlrich 2016-10-07 14:12:18 +02:00
parent a33ce04734
commit e60e6b622c
16 changed files with 86 additions and 40 deletions

View File

@ -33,7 +33,7 @@ public class ClassGenerator extends ClassGen{
private DHBWConstantPoolGen cp; private DHBWConstantPoolGen cp;
private DHBWInstructionFactory factory; private DHBWInstructionFactory factory;
private TypeinferenceResults tiResult; //private TypeinferenceResults tiResult;
private int lambdaMethodeNr = 0; private int lambdaMethodeNr = 0;
private Type superClass; private Type superClass;
@ -43,9 +43,9 @@ public class ClassGenerator extends ClassGen{
private List<String> methodsNamesAndTypes = new LinkedList<>(); private List<String> methodsNamesAndTypes = new LinkedList<>();
private MethodGenerator methodGenerator; private MethodGenerator methodGenerator;
public ClassGenerator(String name, Type superClass, String string, short accessflags, String[] strings, TypeinferenceResults typeinferenceResults) { public ClassGenerator(String name, Type superClass, String string, short accessflags, String[] strings) {
super(name,superClass.get_Name(),string,accessflags,strings, new DHBWConstantPoolGen()); super(name,superClass.get_Name(),string,accessflags,strings, new DHBWConstantPoolGen());
this.tiResult = typeinferenceResults; //this.tiResult = typeinferenceResultSet;
this.superClass = superClass; this.superClass = superClass;
cp = (DHBWConstantPoolGen) super.getConstantPool(); cp = (DHBWConstantPoolGen) super.getConstantPool();
@ -62,7 +62,7 @@ public class ClassGenerator extends ClassGen{
* Versucht einen Type zu finden von dem dieser TPH ein Subtyp sein muss. * Versucht einen Type zu finden von dem dieser TPH ein Subtyp sein muss.
* @param toTPH * @param toTPH
* @return Es gilt dann "toTPH extends Type" * @return Es gilt dann "toTPH extends Type"
*/
public org.apache.bcel.generic.Type getNearestUsedType(Type t, Menge<TypePlaceholder> usedTypes){ public org.apache.bcel.generic.Type getNearestUsedType(Type t, Menge<TypePlaceholder> usedTypes){
if(t == null){ if(t == null){
return this.getInstructionFactory().createObjectType(); return this.getInstructionFactory().createObjectType();
@ -70,13 +70,13 @@ public class ClassGenerator extends ClassGen{
//return getNearestType((TypePlaceholder) t); //return getNearestType((TypePlaceholder) t);
return new TypePlaceholderType((TypePlaceholder) t); return new TypePlaceholderType((TypePlaceholder) t);
}else{ }else{
return t.getBytecodeType(this, getTypeinferenceResults().getTypeReconstructions().get(0)); return t.getBytecodeType(this, getTypeinferenceResultSet().getTypeReconstructions().get(0));
} }
} }
public org.apache.bcel.generic.Type getNearestUsedType(TypePlaceholder toTPH){ public org.apache.bcel.generic.Type getNearestUsedType(TypePlaceholder toTPH){
return this.getNearestUsedType(toTPH, null); return this.getNearestUsedType(toTPH, null);
} }
*/
public String createLambdaMethodName() { public String createLambdaMethodName() {
return "lambda$methode$"+(lambdaMethodeNr++); return "lambda$methode$"+(lambdaMethodeNr++);
} }
@ -185,7 +185,7 @@ public class ClassGenerator extends ClassGen{
TypePlaceholder tph = it.next(); TypePlaceholder tph = it.next();
//ret += tph.getBytecodeMethodSignature(this); //ret += tph.getBytecodeMethodSignature(this);
//ret += ":"; //ret += ":";
ret += tph.getClassSignature(this, getTypeinferenceResults().getTypeReconstructions().get(0)); ret += tph.getClassSignature(this, null); //Es wird null übergeben. Die ClassSignaturen dürfen von keinem ResultSet abhängen.
} }
ret += ">"; ret += ">";
} }
@ -199,10 +199,11 @@ public class ClassGenerator extends ClassGen{
public Map<String, ClassGenerator> getExtraClasses() { public Map<String, ClassGenerator> getExtraClasses() {
return extraClasses; return extraClasses;
} }
/*
public TypeinferenceResults getTypeinferenceResults() { public TypeinferenceResults getTypeinferenceResultSet() {
return tiResult; return tiResult;
} }
*/
@Override @Override
public void addMethod(Method m) { public void addMethod(Method m) {
@ -225,4 +226,5 @@ public class ClassGenerator extends ClassGen{
return methodGenerator; return methodGenerator;
} }
} }

View File

@ -91,7 +91,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
if(pkgName != null)throw new NotImplementedException(); if(pkgName != null)throw new NotImplementedException();
short constants = Constants.ACC_PUBLIC; //Per Definition ist jede Methode public short constants = Constants.ACC_PUBLIC; //Per Definition ist jede Methode public
_cg = new ClassGenerator(name, this.getSuperClass(), name + ".java", constants , new String[] { }, typeinferenceResults); //letzter Parameter sind implementierte Interfaces _cg = new ClassGenerator(name, this.getSuperClass(), name + ".java", constants , new String[] { }); //letzter Parameter sind implementierte Interfaces
_cp = _cg.getConstantPool(); _cp = _cg.getConstantPool();
_factory = new DHBWInstructionFactory(_cg, _cp); _factory = new DHBWInstructionFactory(_cg, _cp);
@ -107,10 +107,11 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
} }
//Zuerst die Methoden und Felder abarbeiten: //Zuerst die Methoden und Felder abarbeiten:
for(Method m : methods){ for(Method m : methods){
m.genByteCode(_cg, this); m.genByteCode(_cg, this, typeinferenceResults);
} }
InstructionList fieldInitializations = new InstructionList(); InstructionList fieldInitializations = new InstructionList();
for(FieldDeclaration f : fieldDeclarations){ for(FieldDeclaration f : fieldDeclarations){
//Die Felder können noch nicht überladen werden. Hier ist nur die erste der Lösungen möglich:
fieldInitializations.append(f.genByteCode(_cg, typeinferenceResults.getTypeReconstructions().get(0))); fieldInitializations.append(f.genByteCode(_cg, typeinferenceResults.getTypeReconstructions().get(0)));
} }
//Die Konstruktoren müssen die Feld initialisierungswerte beinhalten: //Die Konstruktoren müssen die Feld initialisierungswerte beinhalten:
@ -1011,7 +1012,6 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I
public boolean isInterface(){ public boolean isInterface(){
return false; return false;
} }
/* /*
private Collection<? extends ByteCodeResult> getGenericClasses() { private Collection<? extends ByteCodeResult> getGenericClasses() {
Collection<ByteCodeResult> results = new Menge<>(); Collection<ByteCodeResult> results = new Menge<>();

View File

@ -28,6 +28,7 @@ import de.dhbwstuttgart.typeinference.ConstraintsSet;
import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResults;
import de.dhbwstuttgart.typeinference.assumptions.ConstructorAssumption; import de.dhbwstuttgart.typeinference.assumptions.ConstructorAssumption;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption; import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption;
@ -96,7 +97,7 @@ public class Constructor extends Method {
} }
@Override @Override
public void genByteCode(ClassGenerator cg, Class classObj) { public void genByteCode(ClassGenerator cg, Class classObj, TypeinferenceResults resultSets) {
this.genByteCode(cg, new InstructionList()); this.genByteCode(cg, new InstructionList());
} }
// super statement muss drin sein // super statement muss drin sein

View File

@ -191,10 +191,4 @@ public class FieldDeclaration extends Field{
return il; return il;
} }
/*@Override
public void genByteCode(ClassGen cg) {
// TODO Auto-generated method stub
}*/
} }

View File

@ -44,6 +44,7 @@ import de.dhbwstuttgart.typeinference.JavaCodeResult;
import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.ResultSet;
import de.dhbwstuttgart.typeinference.TypeInsertable; import de.dhbwstuttgart.typeinference.TypeInsertable;
import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet;
import de.dhbwstuttgart.typeinference.TypeinferenceResults;
import de.dhbwstuttgart.typeinference.UndConstraint; import de.dhbwstuttgart.typeinference.UndConstraint;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption; import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption;
@ -396,8 +397,8 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable
return super.equals(obj); return super.equals(obj);
} }
public void genByteCode(ClassGenerator cg, Class classObj) { public void genByteCode(ClassGenerator cg, Class classObj, TypeinferenceResults resultSets) {
List<TypeinferenceResultSet> typeInterferenceResults = cg.getTypeinferenceResults().getTypeReconstructions(this, cg); List<TypeinferenceResultSet> typeInterferenceResults = resultSets.getTypeReconstructions(this, cg);
DHBWInstructionFactory _factory = cg.getInstructionFactory(); DHBWInstructionFactory _factory = cg.getInstructionFactory();
for(TypeinferenceResultSet t: typeInterferenceResults){ for(TypeinferenceResultSet t: typeInterferenceResults){

View File

@ -1065,7 +1065,7 @@ public class SourceFile
} }
/** /**
* Bisher wird nur der Bytecode der Klassen generiert. Nicht der Interfaces. * Bytecode generieren für das resultSet
* @return * @return
*/ */
public Menge<ByteCodeResult> generateBytecode(TypeinferenceResults results) { public Menge<ByteCodeResult> generateBytecode(TypeinferenceResults results) {
@ -1073,6 +1073,18 @@ public class SourceFile
for(Class cl : this.KlassenVektor){ for(Class cl : this.KlassenVektor){
ret.add(cl.genByteCode(results)); ret.add(cl.genByteCode(results));
} }
/*
//Add all FunN Interfaces
for(Pair ucons : results.getUnifiedConstraints()){
for(Type t : ucons.getTypes()){
List<Class> xClasses = t.isClassFromJavaX();
for(Class xClass : xClasses){
ByteCodeResult bC = xClass.genByteCode(results);
if(! ret.contains(bC))ret.add(bC);
}
}
}
*/
return ret; return ret;
} }

View File

@ -66,6 +66,11 @@ public class ASTFactory {
return generatedClass; return generatedClass;
} }
public static Class createInterface(String className, RefType type){
//Class generatedClass = new Class(className, )
return null;
}
public static Class createObjectClass() { public static Class createObjectClass() {
Class generatedClass = new Class("java.lang.Object", 0); Class generatedClass = new Class("java.lang.Object", 0);

View File

@ -307,7 +307,7 @@ public class LambdaExpression extends Expr{
String interfaceMethodName = "apply"; //Das ist ein Hack, funktioniert momentan, da nur FunN Interfaces für LambdaAusdrücke funktionieren String interfaceMethodName = "apply"; //Das ist ein Hack, funktioniert momentan, da nur FunN Interfaces für LambdaAusdrücke funktionieren
//String invokeDynamicType = org.apache.bcel.generic.Type.getMethodSignature(lambdaType.getBytecodeType(cg, rs), additionalParameters); //String invokeDynamicType = org.apache.bcel.generic.Type.getMethodSignature(lambdaType.getBytecodeType(cg, rs), additionalParameters);
String invokeDynamicType = org.apache.bcel.generic.Type.getMethodSignature(new org.apache.bcel.generic.ObjectType(lambdaType.get_Name()), additionalParameters); String invokeDynamicType = org.apache.bcel.generic.Type.getMethodSignature(lambdaType.getBytecodeType(cg, rs), additionalParameters);
il.append(cg.getInstructionFactory().createInvokeDynamic(interfaceMethodName,invokeDynamicType, bMethod)); il.append(cg.getInstructionFactory().createInvokeDynamic(interfaceMethodName,invokeDynamicType, bMethod));
return il; return il;

View File

@ -160,10 +160,11 @@ public class LocalOrFieldVarOrClassname extends Expr
public InstructionList genByteCode(ClassGenerator cg, TypeinferenceResultSet rs) { public InstructionList genByteCode(ClassGenerator cg, TypeinferenceResultSet rs) {
InstructionList il = new InstructionList(); InstructionList il = new InstructionList();
if(this.isFieldAccess){ if(this.isFieldAccess){
il.append(new This(this).genByteCode(cg, rs));
il.append(cg.getInstructionFactory().createFieldAccess(this.getParentClass().getName().toString(), this.get_Name(), this.getType().getBytecodeType(cg, rs), Constants.GETFIELD)); il.append(cg.getInstructionFactory().createFieldAccess(this.getParentClass().getName().toString(), this.get_Name(), this.getType().getBytecodeType(cg, rs), Constants.GETFIELD));
} }else{
il.append(createLoad(cg, rs)); il.append(createLoad(cg, rs));
}
return il; return il;
} }

View File

@ -4,6 +4,7 @@ package de.dhbwstuttgart.syntaxtree.statement;
// ino.module.MethodCall.8639.import // ino.module.MethodCall.8639.import
import java.util.Hashtable; import java.util.Hashtable;
import org.apache.bcel.Const;
import org.apache.bcel.Constants; import org.apache.bcel.Constants;
import org.apache.bcel.generic.ClassGen; import org.apache.bcel.generic.ClassGen;
import org.apache.bcel.generic.InstructionFactory; import org.apache.bcel.generic.InstructionFactory;
@ -333,9 +334,9 @@ public class MethodCall extends Expr
de.dhbwstuttgart.syntaxtree.Class receiverClass = this.receiver.getReceiverClass(cg, rs); de.dhbwstuttgart.syntaxtree.Class receiverClass = this.receiver.getReceiverClass(cg, rs);
short kind = 0; short kind = 0;
if(receiverClass.isInterface()){ if(receiverClass.isInterface()){
kind = Constants.INVOKEINTERFACE; kind = Const.INVOKEINTERFACE;
}else{//Ansonsten muss es eine Klasse sein: }else{//Ansonsten muss es eine Klasse sein:
kind = Constants.INVOKEVIRTUAL; kind = Const.INVOKEVIRTUAL;
} }
org.apache.bcel.generic.Type[] argumentTypen = org.apache.bcel.generic.Type.NO_ARGS; org.apache.bcel.generic.Type[] argumentTypen = org.apache.bcel.generic.Type.NO_ARGS;
@ -353,7 +354,10 @@ public class MethodCall extends Expr
} }
org.apache.bcel.generic.Type returnType = this.getType().getBytecodeType(cg, rs); org.apache.bcel.generic.Type returnType = this.getType().getBytecodeType(cg, rs);
il.append(_factory.createInvoke(receiver.getReceiverClass(cg, rs).getName().toString(), this.get_Name(), returnType , argumentTypen, kind)); il.append(_factory.createInvoke(
receiver.get_Expr().getType().getBytecodeType(cg, rs).toString(),
//receiver.getReceiverClass(cg, rs).getBytecodeType(cg, rs).toString(),
this.get_Name(), returnType , argumentTypen, kind));
return il; return il;
} }

View File

@ -122,5 +122,6 @@ public class Receiver
public JavaCodeResult printJavaCode(ResultSet resultSet) { public JavaCodeResult printJavaCode(ResultSet resultSet) {
return new JavaCodeResult().attach(this.get_Expr().printJavaCode(resultSet)); return new JavaCodeResult().attach(this.get_Expr().printJavaCode(resultSet));
} }
} }
// ino.end // ino.end

View File

@ -579,12 +579,9 @@ public class RefType extends ObjectType implements IMatchable
@Override @Override
public String getBytecodeSignature(ClassGenerator cg, TypeinferenceResultSet rs) { public String getBytecodeSignature(ClassGenerator cg, TypeinferenceResultSet rs) {
String combinedType = getCombinedType(cg, rs); String combinedType = getCombinedType(cg, rs);
if(!combinedType.equals(getName().toString())){ /*
getSuperWildcardTypes();
Class generatedClass = ASTFactory.createClass(getCombinedType(cg, rs), getGenericClassType(), null, null, new SourceFile());
cg.addExtraClass(generatedClass.genByteCode(new TypeinferenceResults()).getByteCode()); */
}
String ret = new org.apache.bcel.generic.ObjectType(combinedType).getSignature(); String ret = new org.apache.bcel.generic.ObjectType(combinedType).getSignature();
return ret; return ret;
} }
@ -611,8 +608,14 @@ public class RefType extends ObjectType implements IMatchable
} }
return sb.toString(); return sb.toString();
} }
String ret = sb.append(this.getName().toString()).toString();
if(!ret.equals(getName().toString())){
//getSuperWildcardTypes();
Class generatedClass = ASTFactory.createClass(getCombinedType(cg, rs), getGenericClassType(), null, null, new SourceFile());
return sb.append(this.getName().toString()).toString(); cg.addExtraClass(generatedClass.genByteCode(new TypeinferenceResults()).getByteCode());
}
return ret;
} }
public GenericClassType getGenericClassType(){ public GenericClassType getGenericClassType(){

View File

@ -3,6 +3,7 @@ package de.dhbwstuttgart.syntaxtree.type;
// ino.end // ino.end
// ino.module.Type.8677.import // ino.module.Type.8677.import
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List;
import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.typeinference.Menge;
import de.dhbwstuttgart.bytecode.ClassGenerator; import de.dhbwstuttgart.bytecode.ClassGenerator;
@ -328,5 +329,15 @@ public abstract class Type extends SyntaxTreeNode implements IItemWithOffset
public String getClassSignature(ClassGenerator cg, TypeinferenceResultSet rs){ public String getClassSignature(ClassGenerator cg, TypeinferenceResultSet rs){
return this.getBytecodeSignature(cg, rs); return this.getBytecodeSignature(cg, rs);
} }
/**
* Wird beim Bytecode gebraucht.
* Einige Klassen werden vom Compiler als gegeben angenommen,
* obwohl sie sich nicht in der Java Standard Library befinden.
* Diese müssen beim generieren von Bytecode als zusätzliche Klassen generiert werden.
*
* @return - Eine Liste der Klassen, welche bei Verwendung dieses Typs zusätzlich gebraucht werden.
*/
//public abstract List<de.dhbwstuttgart.syntaxtree.Class> isClassFromJavaX();
} }
// ino.end // ino.end

View File

@ -41,12 +41,12 @@ public class SingleClassTester {
for(ByteCodeResult result: bytecode){ for(ByteCodeResult result: bytecode){
JavaClass javaClass = result.getByteCode().getJavaClass(); JavaClass javaClass = result.getByteCode().getJavaClass();
javaClass.dump(new File(outputDirectory+javaClass.getClassName()+".class")); javaClass.dump(new File(outputDirectory+javaClass.getClassName()+".class"));
/*
for(ClassGenerator cg: result.getByteCode().getExtraClasses().values()){ for(ClassGenerator cg: result.getByteCode().getExtraClasses().values()){
JavaClass jc = cg.getJavaClass(); JavaClass jc = cg.getJavaClass();
jc.dump(new File(outputDirectory+jc.getClassName()+".class")); jc.dump(new File(outputDirectory+jc.getClassName()+".class"));
} }
*/
Logger.getLogger("SingleClassTester").error(result.getByteCode().getJavaClass().toString(), Section.CODEGEN); Logger.getLogger("SingleClassTester").error(result.getByteCode().getJavaClass().toString(), Section.CODEGEN);
} }

View File

@ -4,6 +4,8 @@ import static org.junit.Assert.*;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.MalformedURLException; import java.net.MalformedURLException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
@ -60,4 +62,13 @@ public abstract class SourceFileBytecodeTest extends TestCase{
return new URLClassLoader(urls); return new URLClassLoader(urls);
} }
protected void testMethod(String methodName) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException{
Class testClass = getClassToTest();
for(Method m : testClass.getMethods()){
if(m.getName().equals(methodName)){
m.invoke(testClass, new Object[0]);
}
}
}
} }