diff --git a/src/de/dhbwstuttgart/bytecode/ClassGenerator.java b/src/de/dhbwstuttgart/bytecode/ClassGenerator.java index 14c12a85..4da51404 100644 --- a/src/de/dhbwstuttgart/bytecode/ClassGenerator.java +++ b/src/de/dhbwstuttgart/bytecode/ClassGenerator.java @@ -33,7 +33,7 @@ public class ClassGenerator extends ClassGen{ private DHBWConstantPoolGen cp; private DHBWInstructionFactory factory; - private TypeinferenceResults tiResult; + //private TypeinferenceResults tiResult; private int lambdaMethodeNr = 0; private Type superClass; @@ -43,9 +43,9 @@ public class ClassGenerator extends ClassGen{ private List methodsNamesAndTypes = new LinkedList<>(); 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()); - this.tiResult = typeinferenceResults; + //this.tiResult = typeinferenceResultSet; this.superClass = superClass; 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. * @param toTPH * @return Es gilt dann "toTPH extends Type" - */ + public org.apache.bcel.generic.Type getNearestUsedType(Type t, Menge usedTypes){ if(t == null){ return this.getInstructionFactory().createObjectType(); @@ -70,13 +70,13 @@ public class ClassGenerator extends ClassGen{ //return getNearestType((TypePlaceholder) t); return new TypePlaceholderType((TypePlaceholder) t); }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){ return this.getNearestUsedType(toTPH, null); } - + */ public String createLambdaMethodName() { return "lambda$methode$"+(lambdaMethodeNr++); } @@ -185,7 +185,7 @@ public class ClassGenerator extends ClassGen{ TypePlaceholder tph = it.next(); //ret += tph.getBytecodeMethodSignature(this); //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 += ">"; } @@ -199,11 +199,12 @@ public class ClassGenerator extends ClassGen{ public Map getExtraClasses() { return extraClasses; } - - public TypeinferenceResults getTypeinferenceResults() { + /* + public TypeinferenceResults getTypeinferenceResultSet() { return tiResult; } - + */ + @Override public void addMethod(Method m) { //TODO: Die Prüfung, ob Methode bereits vorhanden vor die Bytecodegenerierung verlegen (Beispielsweise in Method) @@ -225,4 +226,5 @@ public class ClassGenerator extends ClassGen{ return methodGenerator; } + } diff --git a/src/de/dhbwstuttgart/syntaxtree/Class.java b/src/de/dhbwstuttgart/syntaxtree/Class.java index f5cbb6c9..753ac838 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Class.java +++ b/src/de/dhbwstuttgart/syntaxtree/Class.java @@ -91,7 +91,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I if(pkgName != null)throw new NotImplementedException(); 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(); _factory = new DHBWInstructionFactory(_cg, _cp); @@ -107,10 +107,11 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I } //Zuerst die Methoden und Felder abarbeiten: for(Method m : methods){ - m.genByteCode(_cg, this); + m.genByteCode(_cg, this, typeinferenceResults); } InstructionList fieldInitializations = new InstructionList(); 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))); } //Die Konstruktoren müssen die Feld initialisierungswerte beinhalten: @@ -1011,7 +1012,6 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I public boolean isInterface(){ return false; } - /* private Collection getGenericClasses() { Collection results = new Menge<>(); diff --git a/src/de/dhbwstuttgart/syntaxtree/Constructor.java b/src/de/dhbwstuttgart/syntaxtree/Constructor.java index cf82752c..c72158e8 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Constructor.java +++ b/src/de/dhbwstuttgart/syntaxtree/Constructor.java @@ -28,6 +28,7 @@ import de.dhbwstuttgart.typeinference.ConstraintsSet; import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; +import de.dhbwstuttgart.typeinference.TypeinferenceResults; import de.dhbwstuttgart.typeinference.assumptions.ConstructorAssumption; import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption; @@ -96,7 +97,7 @@ public class Constructor extends Method { } @Override - public void genByteCode(ClassGenerator cg, Class classObj) { + public void genByteCode(ClassGenerator cg, Class classObj, TypeinferenceResults resultSets) { this.genByteCode(cg, new InstructionList()); } // super statement muss drin sein diff --git a/src/de/dhbwstuttgart/syntaxtree/FieldDeclaration.java b/src/de/dhbwstuttgart/syntaxtree/FieldDeclaration.java index fe48efcd..245efed0 100644 --- a/src/de/dhbwstuttgart/syntaxtree/FieldDeclaration.java +++ b/src/de/dhbwstuttgart/syntaxtree/FieldDeclaration.java @@ -190,11 +190,5 @@ public class FieldDeclaration extends Field{ il.append(putFieldInstruction ); return il; } - - /*@Override - public void genByteCode(ClassGen cg) { - // TODO Auto-generated method stub - - }*/ } diff --git a/src/de/dhbwstuttgart/syntaxtree/Method.java b/src/de/dhbwstuttgart/syntaxtree/Method.java index d4f269a8..7df79dbe 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Method.java +++ b/src/de/dhbwstuttgart/syntaxtree/Method.java @@ -44,6 +44,7 @@ import de.dhbwstuttgart.typeinference.JavaCodeResult; import de.dhbwstuttgart.typeinference.ResultSet; import de.dhbwstuttgart.typeinference.TypeInsertable; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; +import de.dhbwstuttgart.typeinference.TypeinferenceResults; import de.dhbwstuttgart.typeinference.UndConstraint; import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.ParameterAssumption; @@ -396,8 +397,8 @@ public class Method extends Field implements IItemWithOffset, TypeInsertable return super.equals(obj); } - public void genByteCode(ClassGenerator cg, Class classObj) { - List typeInterferenceResults = cg.getTypeinferenceResults().getTypeReconstructions(this, cg); + public void genByteCode(ClassGenerator cg, Class classObj, TypeinferenceResults resultSets) { + List typeInterferenceResults = resultSets.getTypeReconstructions(this, cg); DHBWInstructionFactory _factory = cg.getInstructionFactory(); for(TypeinferenceResultSet t: typeInterferenceResults){ diff --git a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java index 175639d7..91468ae4 100755 --- a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java +++ b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java @@ -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 */ public Menge generateBytecode(TypeinferenceResults results) { @@ -1073,6 +1073,18 @@ public class SourceFile for(Class cl : this.KlassenVektor){ ret.add(cl.genByteCode(results)); } + /* + //Add all FunN Interfaces + for(Pair ucons : results.getUnifiedConstraints()){ + for(Type t : ucons.getTypes()){ + List xClasses = t.isClassFromJavaX(); + for(Class xClass : xClasses){ + ByteCodeResult bC = xClass.genByteCode(results); + if(! ret.contains(bC))ret.add(bC); + } + } + } + */ return ret; } diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java index c02ed64f..384e03fa 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/ASTFactory.java @@ -66,6 +66,11 @@ public class ASTFactory { return generatedClass; } + public static Class createInterface(String className, RefType type){ + //Class generatedClass = new Class(className, ) + return null; + } + public static Class createObjectClass() { Class generatedClass = new Class("java.lang.Object", 0); diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java b/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java index 39a5e8eb..220517e2 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java @@ -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 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)); return il; diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/LocalOrFieldVarOrClassname.java b/src/de/dhbwstuttgart/syntaxtree/statement/LocalOrFieldVarOrClassname.java index bb0992e8..c4f75ad4 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/LocalOrFieldVarOrClassname.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/LocalOrFieldVarOrClassname.java @@ -160,11 +160,12 @@ public class LocalOrFieldVarOrClassname extends Expr public InstructionList genByteCode(ClassGenerator cg, TypeinferenceResultSet rs) { InstructionList il = new InstructionList(); 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)); + }else{ + il.append(createLoad(cg, rs)); } - il.append(createLoad(cg, rs)); - return il; } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java index 97cdc19c..c47a4442 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java @@ -4,6 +4,7 @@ package de.dhbwstuttgart.syntaxtree.statement; // ino.module.MethodCall.8639.import import java.util.Hashtable; +import org.apache.bcel.Const; import org.apache.bcel.Constants; import org.apache.bcel.generic.ClassGen; 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); short kind = 0; if(receiverClass.isInterface()){ - kind = Constants.INVOKEINTERFACE; + kind = Const.INVOKEINTERFACE; }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; @@ -353,7 +354,10 @@ public class MethodCall extends Expr } 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; } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/Receiver.java b/src/de/dhbwstuttgart/syntaxtree/statement/Receiver.java index 5c1d2bbd..2b0dbb0d 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/Receiver.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/Receiver.java @@ -122,5 +122,6 @@ public class Receiver public JavaCodeResult printJavaCode(ResultSet resultSet) { return new JavaCodeResult().attach(this.get_Expr().printJavaCode(resultSet)); } + } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java index 27443bb4..16ca7b46 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java @@ -579,12 +579,9 @@ public class RefType extends ObjectType implements IMatchable @Override public String getBytecodeSignature(ClassGenerator cg, TypeinferenceResultSet 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(); return ret; } @@ -611,8 +608,14 @@ public class RefType extends ObjectType implements IMatchable } return sb.toString(); } - - return sb.append(this.getName().toString()).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()); + + cg.addExtraClass(generatedClass.genByteCode(new TypeinferenceResults()).getByteCode()); + } + return ret; } public GenericClassType getGenericClassType(){ diff --git a/src/de/dhbwstuttgart/syntaxtree/type/Type.java b/src/de/dhbwstuttgart/syntaxtree/type/Type.java index 603258ea..812a0350 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/Type.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/Type.java @@ -3,6 +3,7 @@ package de.dhbwstuttgart.syntaxtree.type; // ino.end // ino.module.Type.8677.import import java.util.ArrayList; +import java.util.List; import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.bytecode.ClassGenerator; @@ -328,5 +329,15 @@ public abstract class Type extends SyntaxTreeNode implements IItemWithOffset public String getClassSignature(ClassGenerator cg, TypeinferenceResultSet 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 isClassFromJavaX(); } // ino.end diff --git a/test/bytecode/IdTest.java b/test/bytecode/IdTest.java index f5da1ab2..e7185ca5 100644 --- a/test/bytecode/IdTest.java +++ b/test/bytecode/IdTest.java @@ -18,4 +18,4 @@ public class IdTest extends SourceFileBytecodeTest{ Object obj = cls.newInstance(); assertTrue(true); } -} \ No newline at end of file +} diff --git a/test/bytecode/SingleClassTester.java b/test/bytecode/SingleClassTester.java index 2f731e5c..312416ab 100644 --- a/test/bytecode/SingleClassTester.java +++ b/test/bytecode/SingleClassTester.java @@ -41,12 +41,12 @@ public class SingleClassTester { for(ByteCodeResult result: bytecode){ JavaClass javaClass = result.getByteCode().getJavaClass(); javaClass.dump(new File(outputDirectory+javaClass.getClassName()+".class")); - + /* for(ClassGenerator cg: result.getByteCode().getExtraClasses().values()){ JavaClass jc = cg.getJavaClass(); jc.dump(new File(outputDirectory+jc.getClassName()+".class")); } - + */ Logger.getLogger("SingleClassTester").error(result.getByteCode().getJavaClass().toString(), Section.CODEGEN); } diff --git a/test/bytecode/SourceFileBytecodeTest.java b/test/bytecode/SourceFileBytecodeTest.java index 3cf8ce2a..d975c0c1 100644 --- a/test/bytecode/SourceFileBytecodeTest.java +++ b/test/bytecode/SourceFileBytecodeTest.java @@ -4,6 +4,8 @@ import static org.junit.Assert.*; import java.io.File; import java.io.IOException; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.net.MalformedURLException; import java.net.URL; import java.net.URLClassLoader; @@ -60,4 +62,13 @@ public abstract class SourceFileBytecodeTest extends TestCase{ 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]); + } + } + } }