From 1a07c186a6b0d66643415426ae84ca58ee29c26c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Enrico=20Schr=C3=B6dter?= Date: Fri, 16 Oct 2015 10:39:34 +0200 Subject: [PATCH] =?UTF-8?q?generateBytecode=20von=20Class=20gibt=20eine=20?= =?UTF-8?q?Menge=20an=20ByteCodeResults=20zur=C3=BCck,=20wird=20ben=C3=B6t?= =?UTF-8?q?igt=20um=20zus=C3=A4tzliche=20Klassen=20anzulegen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/de/dhbwstuttgart/core/MyCompiler.java | 4 +- src/de/dhbwstuttgart/core/MyCompilerAPI.java | 2 +- src/de/dhbwstuttgart/syntaxtree/Class.java | 389 ++---------------- .../dhbwstuttgart/syntaxtree/SourceFile.java | 4 +- .../syntaxtree/type/RefType.java | 12 +- .../typeinference/TypeinferenceResultSet.java | 2 +- test/bytecode/BytecodeTest.java | 6 +- test/bytecode/SingleClassTester.java | 18 +- test/bytecode/types/ExtendsVector.jav | 1 + test/bytecode/types/TypedVector.jav | 2 +- test/bytecode/types/TypedVectorTest.java | 4 +- 11 files changed, 61 insertions(+), 383 deletions(-) diff --git a/src/de/dhbwstuttgart/core/MyCompiler.java b/src/de/dhbwstuttgart/core/MyCompiler.java index 74099f38..7b72e79b 100755 --- a/src/de/dhbwstuttgart/core/MyCompiler.java +++ b/src/de/dhbwstuttgart/core/MyCompiler.java @@ -860,10 +860,10 @@ public class MyCompiler implements MyCompilerAPI } @Override - public Menge generateBytecode(TypeinferenceResultSet typeinferenceResult) { + public Menge> generateBytecode(TypeinferenceResultSet typeinferenceResult) { //SourceFile parsedFile = this.m_AbstractSyntaxTree.firstElement(); //Class parsedClass = parsedFile.KlassenVektor.firstElement(); - Menge ret = new Menge<>(); + Menge> ret = new Menge<>(); for(SourceFile sf : this.m_AbstractSyntaxTree){ ret.addAll(sf.generateBytecode(typeinferenceResult)); } diff --git a/src/de/dhbwstuttgart/core/MyCompilerAPI.java b/src/de/dhbwstuttgart/core/MyCompilerAPI.java index 9c5d2a57..78860de4 100755 --- a/src/de/dhbwstuttgart/core/MyCompilerAPI.java +++ b/src/de/dhbwstuttgart/core/MyCompilerAPI.java @@ -127,6 +127,6 @@ public interface MyCompilerAPI * Dafür müssen die Schritte Parsen und typeReconstruction ausgeführt werden. * @return */ - public Menge generateBytecode(TypeinferenceResultSet rs); + public Menge> generateBytecode(TypeinferenceResultSet rs); } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/Class.java b/src/de/dhbwstuttgart/syntaxtree/Class.java index 356e3298..b11ed15f 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Class.java +++ b/src/de/dhbwstuttgart/syntaxtree/Class.java @@ -15,7 +15,6 @@ import org.apache.commons.bcel6.generic.InstructionHandle; import org.apache.commons.bcel6.generic.InstructionList; import org.apache.commons.bcel6.generic.MethodGen; -import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.logger.Logger; import de.dhbwstuttgart.logger.Section; import de.dhbwstuttgart.logger.SectionLogger; @@ -75,11 +74,13 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I * @param resultSet - Fehlende Typen im Syntaxbaum werden nach diesem ResultSet aufgelöst * @return */ - public ByteCodeResult genByteCode(TypeinferenceResultSet resultSet) { + public Menge genByteCode(TypeinferenceResultSet resultSet) { InstructionFactory _factory; DHBWConstantPoolGen _cp; ClassGenerator _cg; + Menge results = new Menge(); + SectionLogger logger = Logger.getSectionLogger(this.getClass().getName(), Section.CODEGEN); logger.debug("Test"); @@ -112,10 +113,14 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I } ByteCodeResult code = new ByteCodeResult(_cg); - return code; + results.add(code); + + results.addAll(getGenericClasses(_cg)); + + return results; } - private Menge superif = new Menge(); + private Menge superif = new Menge(); public UsedId getPackageName() { @@ -593,112 +598,6 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I { return this.parahash; } - // ino.end - - - -/*static void string_rec(Hashtable ht){ - String record=""; - boolean isError=false; - record=record.concat("["); - for(Enumeration e=ht.elements(),k=ht.keys();e.hasMoreElements();){ - String s = (String)k.nextElement(); - Object o = e.nextElement(); - - record=record.concat(" "+s); - - if(o instanceof Type){ - record=record.concat(" = "+((Type)o).getName()); - } else if(o instanceof Hashtable){ - record=record.concat("= "); - string_rec((Hashtable)o); - if(e.hasMoreElements()) - record=record.concat(", "); - } else if(o instanceof String){ - record=record.concat(" = "+o); - if(e.hasMoreElements()) - record=record.concat(", "); - } - else { - record=("[FEHLER: string_rec: unbekannter Typ!!!!!!"); - isError=true; - } - } - record=record.concat("]"); - if(isError){ - parserlog.error(record); - }else{ - parserlog.debug(record); - } - }*/ - - /*static void string_rec(Menge v){ - String record=("{"); - for(Enumeration e=v.elements();e.hasMoreElements();){ - Type t = (Type)e.nextElement(); - record=record.concat(" "+t.getName()); - - if(e.hasMoreElements()) - record=record.concat(","); - } - record=record.concat("}"); - parserlog.debug(record); - }*/ - /*static void string_rec(String st, Hashtable ht){ - String record=(st); - boolean isError=false; - record=record.concat("["); - for(Enumeration e=ht.elements(),k=ht.keys();e.hasMoreElements();){ - String s = (String)k.nextElement(); - Object o = e.nextElement(); - - record=record.concat(" "+s); - - if(o instanceof Type){ - record=record.concat(" = "+((Type)o).getName()); - } - - else if(o instanceof Hashtable){ - record=record.concat("= "); - string_rec((Hashtable)o); - if(e.hasMoreElements()) - record=record.concat(", "); - } - else if(o instanceof String){ - record=record.concat(" = "+o); - if(e.hasMoreElements()) - record=record.concat(", "); - } - else { - record=("[FEHLER: string_rec: unbekannter Typ!!!!!! " +o); - isError = true; - } - } - record=record.concat("]"); - if(isError){ - parserlog.error(record); - }else{ - parserlog.debug(record); - } - }*/ - - /*static void string_rec(String st,Menge v) - { - String record=(st); - record=record.concat("{"); - for(Enumeration e=v.elements();e.hasMoreElements();) - { - Type t = (Type)e.nextElement(); - record=record.concat(" "+t.getName()); - if(e.hasMoreElements()) - { - record=record.concat(", "); - } - } - record=record.concat("}"); - parserlog.debug(record); - }*/ - ///////////////////////////////////////////////////////////////////////// // TypeReconstructionAlgorithmus @@ -771,165 +670,7 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I typinferenzLog.debug("Erstellte Constraints: "+oderConstraints, Section.TYPEINFERENCE); return oderConstraints; - - - /* - CReconstructionTupleSet retTupleSet = this.TRStart(methodList, V, V_fields_methods, supportData); - inferencelog.debug("Bin aus TRStart() zur�ck in TRProg()."); - ////////////////////////////// - // Neu Ergebnismenge A aller - // Typannahmen erzeugen: - ////////////////////////////// - inferencelog.debug("Erstelle Ergebnismenge..."); - Menge newA = new Menge(); - - // Alle bisherigen M�glichkeiten an Typkombinationen durchgehen: - Menge oldA = supportData.getA(); - for(int i=0; i retTupleIt = retTupleSet.getIterator(); - while(retTupleIt.hasNext()){ - CReconstructionTuple possibleTuple = retTupleIt.next(); - this.clear(possibleTuple.getAssumSet(), rememberLocals); - - // Neue Typinformationen mit alten Typinformationen vereinigen: - CTypeReconstructionResult newReconResult = oneReconResult.shallowCopy(); - newReconResult.addDataFromTupel(possibleTuple); - - - //PL 05-08-02 eingefuegt - //Fuegt Klassen und GenericTypeVars zu A hinzu - newReconResult.addClassName(this.getName()); - Menge genericsList = new Menge(); - for(int ii =0; ii getMethodList() { - - - if(this.methodList != null) return this.methodList; - //TODO: Unnötige Berechnungen im folgenden Code rauskürzen: - ////////////////////////////// - // Die Eingabedaten bauen: - ////////////////////////////// - inferencelog.debug("Baue Eingabedaten..."); - TypeAssumptions V_fields_methods = new TypeAssumptions(this.getName()); - Menge methodList = new Menge(); - Menge V = new Menge(); - Menge rememberLocals = new Menge(); - - ////////////////////////////// - // Alle Felder durchgehen: - // Zuerst alle Attribute, dann Methoden - // ge�ndert: hoth 06.04.2006 - - ////////////////////////////// - for(Field field : this.getFields()) - { - ////////////////////////////// - // Attribut: - ////////////////////////////// - - } - - for(Field field : this.getFields()) - { - ////////////////////////////// - // Methode: - ////////////////////////////// - if(field instanceof Method){ - Method method = (Method)field; - //if(method.get_Method_Name().equals(this.getName()) && ((method.getReturnType().equals(new mycompiler.mytype.Void(0))) || method.getReturnType() instanceof TypePlaceholder)){ - if(method.get_Method_Name().equals(this.getName()) ){ - method.set_Method_Name(""); - } - //hoth: 06.04.2006 - //durchlaufe Block und suche nach Objektvariablen fuer Offset-Markierung - Iterator fieldVarIterator = V_fields_methods.iterator(); - while (fieldVarIterator.hasNext()) - { - //Wenn ObjektVariable - CTypeAssumption dieAssum = fieldVarIterator.next(); - if(dieAssum instanceof CInstVarTypeAssumption) - { - Class.isFirstLocalVarDecl=false; - if(method.get_Block() != null) - method.get_Block().addOffsetsToAssumption(dieAssum,dieAssum.getIdentifier(),true); - } - } - - methodList.addElement(method); - - // F�r V_fields_methods: - CMethodTypeAssumption methodAssum = new CMethodTypeAssumption(this.getType(), method.get_Method_Name(), method.getReturnType(), method.getParameterCount(),method.getLineNumber(),method.getOffset(),new Menge(),method.getGenericMethodParameters()); // Typannahme bauen... - - - // Methode in V_Fields_methods ablegen - // Dabei wird die OverloadedMethodID ermittelt !! - // => Method setzenuct - - - V_fields_methods.add(methodAssum); - method.setOverloadedID(methodAssum.getHashSetKey().getOverloadedMethodID()); - - - // F�r die V_i: - CTypeAssumptionSet localAssum = new CTypeAssumptionSet(); - - // Bauen... - ParameterList parameterList = method.getParameterList(); - if(parameterList!=null){ - for(int i=0; i()); - //fuege Offsets fuer Parameter hinzu, hoth: 06.04.2006 - Class.isFirstLocalVarDecl=false; - - if(method.get_Block() != null) - method.get_Block().addOffsetsToAssumption(paraAssum,paraAssum.getIdentifier(),true); - - methodAssum.addParaAssumption(paraAssum); - - - - - // F�r die V_i: - CLocalVarTypeAssumption varAssum = new CLocalVarTypeAssumption(this.getName(), method.get_Method_Name(), method.getParameterCount(), method.getOverloadedID(),"1", para.getIdentifier(),para.getType(), para.getLineNumber(),para.getOffset(),new Menge()); - localAssum.addElement(varAssum); - rememberLocals.addElement(varAssum); - } - } - // ...und hinzuf�gen: - - V.addElement(localAssum); - } - } - - this.methodList = methodList; - return methodList; - - } -*/ /** * Ermittelt alle privaten Felder und Methoden der Klasse und Erstellt eine Assumption für diese. @@ -957,49 +698,8 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I this.typeAssumptions = assumptions; //Diese müssen anschließend nicht wieder generiert werden. return assumptions; -} - /* - public ConstraintsSet TYPE(Menge methodList, Menge fielddeclarationList, TypeAssumptions assumptions){ - ConstraintsSet ret = new ConstraintsSet(); - // Die Felddeklarationen werden zu den Assumptions hinzugefügt und gelten danach für jede Methode. - //TypeAssumptions assumptionsPlusFieldAssumptions = new TypeAssumptions(assumptions); - for(Expr expr : fielddeclarationList){ - //ret.add(expr.TYPEStmt(assumptionsPlusFieldAssumptions)); - ret.add(expr.TYPEStmt(assumptions)); - } - for(Method methode : methodList){ - //ret.add(methode.TYPE(assumptionsPlusFieldAssumptions)); - ret.add(methode.TYPE(assumptions)); - } - return ret; - } - */ + } - - // ino.method.RetType.23119.defdescription type=javadoc - /** - * Liefert den berechneten R�ckgabetyp f�r die �bergebene Methode zur�ck.
- * (siehe Algorithmus RetType, Martin Pl�micke) - *
Author: J�rg B�uerle - * @param me - * @param V - * @return - - // ino.end - // ino.method.RetType.23119.definition - private Type RetType(Method me, CTypeAssumptionSet V) - // ino.end - // ino.method.RetType.23119.body - { - CTypeAssumption assum = V.getElement(new CMethodKey(this.getName(), me.get_Method_Name(), me.getParameterCount(),me.getOverloadedID())); - if(assum instanceof CMethodTypeAssumption){ - return ((CMethodTypeAssumption)assum).getAssumedType(); - } - else return null; - } - // ino.end - - */ // ino.method.toString.23125.defdescription type=javadoc /** *
Author: Martin Pl�micke @@ -1037,48 +737,8 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I for(Field f : this.getFields()){ //f.wandleRefTypeAttributes2GenericAttributes(paralist); } - /* - Menge fieldsAndMethods=this.getFields(); - - // Alle Methoden und Instanzvariablen durchgehen - for(int i=0;i enumer = V_last.getHashtable().keys(); -// while(enumer.hasMoreElements()){ -// CTypeAssumption currentAssum = V_last.getElement(enumer.nextElement()); -// if(currentAssum instanceof CLocalVarTypeAssumption){ -// V_i.removeElement(currentAssum); -// } -// } -// -// } - - - // ino.method.getSimpleName.23140.defdescription type=javadoc /** * HOTI * Liefert bei Klassen die fullyQualified angegeben wurden @@ -1115,18 +775,6 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I */ public String printJavaCode(TypeinferenceResultSet reconstructionResult){ JavaCodeResult ret = new JavaCodeResult("class "); - - - - - //Generiere JavaCode der extends-Typen: - /* - String containedTypesJavaCode = ""; - for(Type containedType : containedTypes){ - containedTypesJavaCode += containedType.printJavaCode(resultSet)+ ", "; - } - if(containedTypesJavaCode.length()>1)containedTypesJavaCode = containedTypesJavaCode.substring(0, containedTypesJavaCode.length() -2); - */ JavaCodeResult classBodyCode = new JavaCodeResult(); if(this.modifiers!=null)classBodyCode.attach(this.modifiers.printJavaCode(reconstructionResult.getUnifiedConstraints())).attach(" "); @@ -1382,5 +1030,22 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I public boolean isInterface(){ return false; } + + private Collection getGenericClasses(ClassGenerator _cg) { + Collection results = new Menge<>(); + + //Super Klasse + String name = "java/util/Vectorjava/lang/String"; //getParentClass().getType().getBytecodeSignature(_cg); + + Type superClass = new Class("java/util/Vector",-1).getType(); + + _cg = new ClassGenerator(name, superClass, name + ".java", Constants.ACC_PUBLIC , new String[] { }, new TypeinferenceResultSet(null, null, null)); + + ByteCodeResult code = new ByteCodeResult(_cg); + + results.add(code); + + return results; + } } // ino.end diff --git a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java index f96cc32e..22c45fd7 100755 --- a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java +++ b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java @@ -1834,8 +1834,8 @@ public class SourceFile * Bisher wird nur der Bytecode der Klassen generiert. Nicht der Interfaces. * @return */ - public Collection generateBytecode(TypeinferenceResultSet rs) { - Menge ret = new Menge<>(); + public Menge> generateBytecode(TypeinferenceResultSet rs) { + Menge> ret = new Menge<>(); for(Class cl : this.KlassenVektor){ ret.add(cl.genByteCode(rs)); } diff --git a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java index ac0577da..4f2e045d 100755 --- a/src/de/dhbwstuttgart/syntaxtree/type/RefType.java +++ b/src/de/dhbwstuttgart/syntaxtree/type/RefType.java @@ -814,11 +814,12 @@ public class RefType extends ObjectType implements IMatchable } public org.apache.commons.bcel6.generic.Type getBytecodeType(ClassGenerator cg) { - return new org.apache.commons.bcel6.generic.ObjectType(this.getBytecodeSignature(cg)); + return new org.apache.commons.bcel6.generic.ObjectType(this.get_Name()); } @Override public String getBytecodeSignature(ClassGenerator cg) { + /* //Bsp.: Ljava/util/Vector; StringBuilder sb = new StringBuilder(); @@ -826,12 +827,14 @@ public class RefType extends ObjectType implements IMatchable if(parameter != null){ for(Type type: parameter){ - sb.append("%"); + sb.append(""); //TODO: einen geeignete Delemiter suchen sb.append(type.getBytecodeSignature(cg)); } } - /* + return sb.toString(); + */ + String paramString = ""; if(this.parameter != null && this.parameter.size()>0){ paramString+="<"; @@ -847,9 +850,6 @@ public class RefType extends ObjectType implements IMatchable String typeSignature = this.getBytecodeType(cg).getSignature(); typeSignature = typeSignature.substring(0, typeSignature.length()-1); return typeSignature+paramString+";"; - */ - - return sb.toString(); } } diff --git a/src/de/dhbwstuttgart/typeinference/TypeinferenceResultSet.java b/src/de/dhbwstuttgart/typeinference/TypeinferenceResultSet.java index 9a38d298..819d310b 100755 --- a/src/de/dhbwstuttgart/typeinference/TypeinferenceResultSet.java +++ b/src/de/dhbwstuttgart/typeinference/TypeinferenceResultSet.java @@ -119,7 +119,7 @@ public class TypeinferenceResultSet * Dabei wird die codegen-Methode der inferierten Klasse mit diesem ResultSet aufgerufen. */ public ByteCodeResult codegen(){ - ByteCodeResult res = this.ownerOfResultSet.genByteCode(this); + ByteCodeResult res = this.ownerOfResultSet.genByteCode(this).firstElement(); return res; } diff --git a/test/bytecode/BytecodeTest.java b/test/bytecode/BytecodeTest.java index eb1c2aae..35b8dc33 100644 --- a/test/bytecode/BytecodeTest.java +++ b/test/bytecode/BytecodeTest.java @@ -16,7 +16,7 @@ import org.junit.Test; public abstract class BytecodeTest extends TestCase{ public String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/"; public String testFile; - public String outputFile; + public String outputDirectory; protected String testName; @@ -26,9 +26,9 @@ public abstract class BytecodeTest extends TestCase{ if(testName != null){ testFile = testName+".jav"; - outputFile = testName+".class"; + outputDirectory = ""; - SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputFile); + SingleClassTester.compileToBytecode(rootDirectory+testFile, rootDirectory+outputDirectory); }else{ throw new RuntimeException("rootDirectory, testFile or outputFile is null."); } diff --git a/test/bytecode/SingleClassTester.java b/test/bytecode/SingleClassTester.java index 323aaf53..a5d958f0 100644 --- a/test/bytecode/SingleClassTester.java +++ b/test/bytecode/SingleClassTester.java @@ -3,6 +3,8 @@ package bytecode; import java.io.File; import java.io.IOException; +import org.apache.commons.bcel6.classfile.JavaClass; + import com.google.common.io.Files; import junit.framework.TestCase; @@ -18,20 +20,28 @@ import de.dhbwstuttgart.typeinference.Menge; public class SingleClassTester { - public static void compileToBytecode(String inputFile, String outputFile){ + public static void compileToBytecode(String inputFile, String outputDirectory){ LoggerConfiguration logConfig = new LoggerConfiguration().setOutput(Section.PARSER, System.out); MyCompilerAPI compiler = MyCompiler.getAPI(logConfig); try { compiler.parse(new File(inputFile)); - Menge bytecode = compiler.generateBytecode(compiler.typeReconstruction().firstElement()); + Menge> bytecode = compiler.generateBytecode(compiler.typeReconstruction().firstElement()); //System.out.println(bytecode); - bytecode.firstElement().getByteCode().getJavaClass().dump(new File(outputFile)); + + for(ByteCodeResult result: bytecode.firstElement()){ + JavaClass javaClass = result.getByteCode().getJavaClass(); + + Logger.getLogger("SingleClassTester").error(result.getByteCode().getJavaClass().toString(), Section.CODEGEN); + + javaClass.dump(new File(outputDirectory+javaClass.getClassName()+".class")); + } + } catch (IOException | yyException e) { Logger.getLogger("SingleClassTester").error(e.toString(), Section.CODEGEN); e.printStackTrace(); TestCase.fail(); }finally{ - writeLog(outputFile+".log"); + writeLog(outputDirectory+".log"); } } diff --git a/test/bytecode/types/ExtendsVector.jav b/test/bytecode/types/ExtendsVector.jav index efd0240f..fed1dd07 100644 --- a/test/bytecode/types/ExtendsVector.jav +++ b/test/bytecode/types/ExtendsVector.jav @@ -1,4 +1,5 @@ import java.util.Vector; class ExtendsVector extends Vector{ + } \ No newline at end of file diff --git a/test/bytecode/types/TypedVector.jav b/test/bytecode/types/TypedVector.jav index a19b45bd..d64e4f5f 100644 --- a/test/bytecode/types/TypedVector.jav +++ b/test/bytecode/types/TypedVector.jav @@ -1,4 +1,4 @@ -import java.util.Stack; +import java.util.Vector; class TypedVector{ public void method(Vector v) { diff --git a/test/bytecode/types/TypedVectorTest.java b/test/bytecode/types/TypedVectorTest.java index 5383b5b9..ef32180b 100644 --- a/test/bytecode/types/TypedVectorTest.java +++ b/test/bytecode/types/TypedVectorTest.java @@ -9,6 +9,8 @@ import java.util.Vector; import org.junit.Test; import bytecode.BytecodeTest; +import de.dhbwstuttgart.logger.Logger; +import de.dhbwstuttgart.logger.Section; public class TypedVectorTest extends BytecodeTest{ @Override @@ -32,7 +34,7 @@ public class TypedVectorTest extends BytecodeTest{ method.invoke(obj, stringVector); assertTrue(true); }catch(Exception e){ - e.printStackTrace(); + Logger.getLogger("SingleClassTester").error(e.toString(), Section.CODEGEN); fail(); } }