From 97cb020d45b46577504dabdcb1addb3939715e0c Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Tue, 14 Jul 2015 14:49:46 +0200 Subject: [PATCH 1/8] =?UTF-8?q?Bytecode=20Tests=20anf=C3=BCgen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/bytecode/Return.jav | 11 ++++++++++ test/bytecode/Return.java | 45 +++++++++++++++++++++++++++++++++++++++ test/bytecode/Test.java | 8 +++++++ 3 files changed, 64 insertions(+) create mode 100644 test/bytecode/Return.jav create mode 100644 test/bytecode/Return.java create mode 100644 test/bytecode/Test.java diff --git a/test/bytecode/Return.jav b/test/bytecode/Return.jav new file mode 100644 index 00000000..08c29792 --- /dev/null +++ b/test/bytecode/Return.jav @@ -0,0 +1,11 @@ +class Assign{ + +method() {a; + a = 20; + b; + b=59; + return a + b; + } + + +} \ No newline at end of file diff --git a/test/bytecode/Return.java b/test/bytecode/Return.java new file mode 100644 index 00000000..2d7c4803 --- /dev/null +++ b/test/bytecode/Return.java @@ -0,0 +1,45 @@ +package bytecode; + +import static org.junit.Assert.*; + +import java.io.File; +import java.io.IOException; + +import junit.framework.TestCase; + +import org.junit.Test; + +import plugindevelopment.TypeInsertTester; +import de.dhbwstuttgart.core.MyCompiler; +import de.dhbwstuttgart.core.MyCompilerAPI; +import de.dhbwstuttgart.logger.LoggerConfiguration; +import de.dhbwstuttgart.logger.Section; +import de.dhbwstuttgart.parser.JavaParser.yyException; +import de.dhbwstuttgart.typeinference.ByteCodeResult; +import de.dhbwstuttgart.typeinference.Menge; +import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; +import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertSet; + +public class Return { + + public final static String rootDirectory = System.getProperty("user.dir")+"/test/bytecode/"; + public final static String testFile = "Assign.jav"; + public final static String outputFile = "Assign.class"; + + @Test + public void test() { + LoggerConfiguration logConfig = new LoggerConfiguration().setOutput(Section.PARSER, System.out); + MyCompilerAPI compiler = MyCompiler.getAPI(logConfig); + try { + compiler.parse(new File(rootDirectory + testFile)); + compiler.typeReconstruction(); + ByteCodeResult bytecode = compiler.generateBytecode(); + System.out.println(bytecode); + bytecode.getByteCode().getJavaClass().dump(new File(rootDirectory + outputFile)); + } catch (IOException | yyException e) { + e.printStackTrace(); + TestCase.fail(); + } + } + +} diff --git a/test/bytecode/Test.java b/test/bytecode/Test.java new file mode 100644 index 00000000..e50bce6a --- /dev/null +++ b/test/bytecode/Test.java @@ -0,0 +1,8 @@ +/** + * Diese Klasse testet die generierte EmptyClass.class-Datei + */ +class Test{ +public static void main(String[] args){ + new EmptyClass(); +} +} From c7ffabe0f091cae85fd62cc7a0c5c56806915563 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Tue, 14 Jul 2015 18:43:54 +0200 Subject: [PATCH 2/8] Im Unify wird nur noch bei SUBST deepCopy angewendet. Timer implementiert zum ermitteln der Zeitaufwendungen der einzelnen Schritte im Algorithmus --- src/de/dhbwstuttgart/logger/Timestamp.java | 50 +++++++++++++ src/de/dhbwstuttgart/logger/Timewatch.java | 74 +++++++++++++++++++ src/de/dhbwstuttgart/typeinference/Pair.java | 25 ++++++- .../typeinference/unify/Unify.java | 31 ++++++-- .../MultipleTypesInsertTester.java | 20 +++-- 5 files changed, 186 insertions(+), 14 deletions(-) create mode 100644 src/de/dhbwstuttgart/logger/Timestamp.java create mode 100644 src/de/dhbwstuttgart/logger/Timewatch.java diff --git a/src/de/dhbwstuttgart/logger/Timestamp.java b/src/de/dhbwstuttgart/logger/Timestamp.java new file mode 100644 index 00000000..829ccbd8 --- /dev/null +++ b/src/de/dhbwstuttgart/logger/Timestamp.java @@ -0,0 +1,50 @@ +package de.dhbwstuttgart.logger; + +import java.util.Stack; + + +public class Timestamp{ + String name; + + Stack timestamps = new Stack<>(); + Long accumulatedTime = 0L; + + Timestamp(String name){ + this.name = name; + } + + public void start(){ + timestamps.push(System.currentTimeMillis()); + } + + public Long stop(){ + if(timestamps.isEmpty())return 0L; + Long timeStart = timestamps.pop(); + Long currentTime = getTime(); + Long difference = currentTime-timeStart; + accumulatedTime += difference; + return difference; + } + + public Long currentTime(){ + if(timestamps.isEmpty())return 0L; + Long timeStart = timestamps.peek(); + Long currentTime = getTime(); + return currentTime-timeStart; + } + + @Override + public boolean equals(Object obj) { + if(!(obj instanceof Timestamp))return false; + return this.name.equals(((Timestamp)obj).name); + } + + public String toString(){ + String ret = "Zeit für Aktivität "+this.name+": "+this.accumulatedTime; + return ret; + } + + private Long getTime(){ + return System.currentTimeMillis(); + } +} \ No newline at end of file diff --git a/src/de/dhbwstuttgart/logger/Timewatch.java b/src/de/dhbwstuttgart/logger/Timewatch.java new file mode 100644 index 00000000..26916fea --- /dev/null +++ b/src/de/dhbwstuttgart/logger/Timewatch.java @@ -0,0 +1,74 @@ +package de.dhbwstuttgart.logger; + +import java.util.HashMap; +import java.util.Stack; + +import de.dhbwstuttgart.typeinference.Menge; +import de.dhbwstuttgart.typeinference.exceptions.DebugException; + +public class Timewatch { + + private static final Timewatch time = new Timewatch(); + private final Timestamp startTime; + + private Timers timers = new Timers(); + + private Timewatch(){ + //Privater Konstruktor + startTime = new Timestamp("Timewatch Global"); + startTime.start(); + } + + public static Timewatch getTimewatch() { + return time; + } + + public String dumpTimeData(){ + String ret = "Momentan insgesamt verstrichene Zeit: "+this.startTime.currentTime() +"\n"; + ret += timers.toString(); + return ret; + } + + public Timestamp start(String name){ + if(!timers.contains(name)){ + Timestamp ret = new Timestamp(name); + timers.add(ret); + ret.start(); + return ret; + }else{ + //Timer läuft noch... einfach neue Instanz starten: + Timestamp ret = timers.get(name); + ret.start(); + return ret; + } + } + +} + +class Timers{ + private Menge timers = new Menge<>(); + + public Timestamp get(String name) { + for(Timestamp timer:timers){ + if(timer.name.equals(name))return timer; + } + throw new DebugException("Fehler in Timewatch: Der gesuchte Timer "+name+" ist nicht vorhanden."); + } + + public void add(Timestamp timer) { + timers.add(timer); + } + + public boolean contains(String name) { + return timers.contains(new Timestamp(name)); + } + + public String toString(){ + String ret =""; + for(Timestamp timer : timers){ + ret += timer.toString() + "\n"; + } + return ret; + } +} + diff --git a/src/de/dhbwstuttgart/typeinference/Pair.java b/src/de/dhbwstuttgart/typeinference/Pair.java index 863b3623..21f0e989 100755 --- a/src/de/dhbwstuttgart/typeinference/Pair.java +++ b/src/de/dhbwstuttgart/typeinference/Pair.java @@ -2,7 +2,14 @@ package de.dhbwstuttgart.typeinference; // ino.end // ino.module.Pair.8673.import +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.ObjectInputStream; +import java.io.ObjectOutputStream; +import java.io.Serializable; import java.util.Hashtable; + import de.dhbwstuttgart.typeinference.Menge; // ino.end @@ -24,7 +31,7 @@ import de.dhbwstuttgart.syntaxtree.type.WildcardType; // Klasse, die ein Paar in der Menge Eq speichern kann // ino.end // ino.class.Pair.26540.declaration -public class Pair +public class Pair implements Serializable // ino.end // ino.class.Pair.26540.body { @@ -405,5 +412,21 @@ public class Pair ret.add(this.TA2); return ret; } + + public Pair deepClone() { + try { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = new ObjectOutputStream(baos); + oos.writeObject(this); + + ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray()); + ObjectInputStream ois = new ObjectInputStream(bais); + return (Pair) ois.readObject(); + } catch (IOException e) { + return null; + } catch (ClassNotFoundException e) { + return null; + } + } } // ino.end diff --git a/src/de/dhbwstuttgart/typeinference/unify/Unify.java b/src/de/dhbwstuttgart/typeinference/unify/Unify.java index bd10be77..b7f21c23 100755 --- a/src/de/dhbwstuttgart/typeinference/unify/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/Unify.java @@ -20,6 +20,7 @@ import com.rits.cloning.Cloner; import de.dhbwstuttgart.logger.Logger; import de.dhbwstuttgart.logger.Section; import de.dhbwstuttgart.logger.SectionLogger; +import de.dhbwstuttgart.logger.Timewatch; import de.dhbwstuttgart.core.MyCompiler; import de.dhbwstuttgart.myexception.CTypeReconstructionException; import de.dhbwstuttgart.myexception.MatchException; @@ -664,14 +665,16 @@ public class Unify SectionLogger log = Logger.getSectionLogger(Unify.class.getName(), Section.UNIFY); if(filter){ - Cloner cloner = new Cloner(); + //Cloner cloner = new Cloner(); Menge>> temp = new Menge<>(); //hier werden gefilterte Constraints gesammelt Menge undMenge = new Menge(); //Die Menge von Pairs, welche in jedem Kartesischen Produkt enthalten sind. - undMenge.addAll(cloner.deepClone(Eq1)); + //undMenge.addAll(cloner.deepClone(Eq1)); + undMenge.addAll(Eq1); Menge>> oderConstraints = new Menge<>();//Die zu filternden Constraints for (Menge> vecvecpair : cartProduktSets){ if(vecvecpair.size() == 1){//gibt es nur eine UndMenge in diesem Set, dann kommt diese in jedem Karthesischen Produkt vor: - undMenge.addAll(cloner.deepClone(vecvecpair.firstElement())); + //undMenge.addAll(cloner.deepClone(vecvecpair.firstElement())); + undMenge.addAll(vecvecpair.firstElement()); temp.add(vecvecpair); }else{//gibt es mehrere Mengen, kann gefiltert werden: oderConstraints.add(vecvecpair); //die Menge zu den zu filternden OderConstraints anfügen @@ -682,8 +685,10 @@ public class Unify Menge> filteredOCons = new Menge<>(); //diese Menge sammelt nur Cons for(Menge pairs : oderConstraint){ Menge testMenge = new Menge(); - testMenge.addAll(cloner.deepClone(undMenge)); - testMenge.addAll(cloner.deepClone(pairs)); + //testMenge.addAll(cloner.deepClone(undMenge)); + //testMenge.addAll(cloner.deepClone(pairs)); + testMenge.addAll(undMenge); + testMenge.addAll(pairs); Menge> test = Unify.unifyFiltered(testMenge, fc_tto, false); if(test.size()>0){ filteredOCons.add(pairs); @@ -696,7 +701,7 @@ public class Unify } SetView>> difference = Sets.difference(cartProduktSets, temp); log.debug("Ausgelöschte Constraints: "+difference.toString()); - //cartProduktSets = temp; + cartProduktSets = temp; /* Unifier filterUnify = (pairs)->{ String pairsString = pairs.toString(); @@ -2462,6 +2467,18 @@ throws MatchException inferencelog.debug("TV: " + a.getName()); inferencelog.debug("Bedingung: " + bMitVorbedingung); + Cloner cloner = new Cloner(); + cloner.setDumpClonedClasses(true); + + SectionLogger log = Logger.getSectionLogger("Subst-Methode", Section.UNIFY); + Timewatch timer = Timewatch.getTimewatch(); + de.dhbwstuttgart.logger.Timestamp timestamp = timer.start("Unify-Subst"); + P = cloner.deepClone(P); + a = cloner.deepClone(a); + o = cloner.deepClone(o); + long time = timestamp.stop(); + log.debug("Benötigte Zeit für DeepClone: "+time); + // richtiger Typ aus Pair raussuchen Type T = null; if( nTypnrInPair == 1 ) @@ -2483,7 +2500,7 @@ throws MatchException { // Parameterliste durchgehen Menge vTemp = ((RefType)T).get_ParaList(); - Boolean ret = true; //EINGEFUEGT PL 14-01-16: Return darf erst am Ende zurückgegeben werden und nicht in den ifs + boolean ret = true; //EINGEFUEGT PL 14-01-16: Return darf erst am Ende zurückgegeben werden und nicht in den ifs //sonst werden nicht alle Elemente der Forschleife durchlaufen for( int i = 0; i < vTemp.size(); i++ ) { diff --git a/test/plugindevelopment/TypeInsertTests/MultipleTypesInsertTester.java b/test/plugindevelopment/TypeInsertTests/MultipleTypesInsertTester.java index 1dca7ed6..13e54315 100755 --- a/test/plugindevelopment/TypeInsertTests/MultipleTypesInsertTester.java +++ b/test/plugindevelopment/TypeInsertTests/MultipleTypesInsertTester.java @@ -12,6 +12,7 @@ import de.dhbwstuttgart.logger.Logger; import de.dhbwstuttgart.logger.LoggerConfiguration; import de.dhbwstuttgart.logger.Section; import de.dhbwstuttgart.logger.SectionLogger; +import de.dhbwstuttgart.logger.Timewatch; import de.dhbwstuttgart.parser.JavaParser.yyException; import de.dhbwstuttgart.typeinference.TypeinferenceResultSet; import de.dhbwstuttgart.typeinference.typedeployment.TypeInsertPoint; @@ -69,12 +70,7 @@ public class MultipleTypesInsertTester extends TypeInsertTester{ for(String containString : mustContain){ TestCase.assertTrue("\""+containString+"\" muss in den inferierten Lösungen vorkommen",gesamterSrc.contains(containString)); } - try { - Files.write(Logger.getWholeLog().getBytes(),new File(rootDirectory+sourceFileToInfere+".log")); - } catch (IOException e) { - e.printStackTrace(); - TestCase.fail(); - } + writeLog(sourceFileToInfere+".log"); } public static void testSingleInsert(String sourceFileToInfere, Menge mustContain){ @@ -106,5 +102,17 @@ public class MultipleTypesInsertTester extends TypeInsertTester{ for(String containString : mustContain){ TestCase.assertTrue("\""+containString+"\" muss in den inferierten Lösungen vorkommen",gesamterSrc.contains(containString)); } + writeLog(sourceFileToInfere+".log"); + } + + private static void writeLog(String toFile){ + String log = Logger.getWholeLog()+"\n"; + log+=Timewatch.getTimewatch().dumpTimeData(); + try { + Files.write(log.getBytes(),new File(rootDirectory+toFile)); + } catch (IOException e) { + e.printStackTrace(); + TestCase.fail(); + } } } From 6321f1308dee8650e91fc9819b5752f6427b0de7 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 15 Jul 2015 11:50:10 +0200 Subject: [PATCH 3/8] Nicht mehr im Subst, sondern vorm Subst klonen --- .../dhbwstuttgart/typeinference/unify/Unify.java | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/Unify.java b/src/de/dhbwstuttgart/typeinference/unify/Unify.java index b7f21c23..b7e54a07 100755 --- a/src/de/dhbwstuttgart/typeinference/unify/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/Unify.java @@ -760,6 +760,9 @@ public class Unify int counter = 0; for(Menge vecpair : bigCartProductErg) { + //Klone die Menge vecpair, bevor substituiert wird. Viele Paare sind doppelt referenziert und müssen vor dem Substituieren geklont werden + vecpair = vecpair.stream().map(x -> x.clone()).collect(Menge::new, Menge::add, Menge::addAll); + counter++; if(counter > 1000){ System.out.println(counter + " von "+bigCartProductErg.size()); @@ -2467,18 +2470,6 @@ throws MatchException inferencelog.debug("TV: " + a.getName()); inferencelog.debug("Bedingung: " + bMitVorbedingung); - Cloner cloner = new Cloner(); - cloner.setDumpClonedClasses(true); - - SectionLogger log = Logger.getSectionLogger("Subst-Methode", Section.UNIFY); - Timewatch timer = Timewatch.getTimewatch(); - de.dhbwstuttgart.logger.Timestamp timestamp = timer.start("Unify-Subst"); - P = cloner.deepClone(P); - a = cloner.deepClone(a); - o = cloner.deepClone(o); - long time = timestamp.stop(); - log.debug("Benötigte Zeit für DeepClone: "+time); - // richtiger Typ aus Pair raussuchen Type T = null; if( nTypnrInPair == 1 ) From 3601d11b0b97024316a9d9585431a16e7dd95453 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 15 Jul 2015 17:09:49 +0200 Subject: [PATCH 4/8] Fehler in deepCopy behoben --- .../dhbwstuttgart/syntaxtree/SourceFile.java | 2 +- .../typeinference/DeepCloneable.java | 18 ++++++++++++ src/de/dhbwstuttgart/typeinference/Menge.java | 3 +- src/de/dhbwstuttgart/typeinference/Pair.java | 5 +++- .../typeinference/unify/Unify.java | 28 +++++++++++++++++-- 5 files changed, 50 insertions(+), 6 deletions(-) create mode 100644 src/de/dhbwstuttgart/typeinference/DeepCloneable.java diff --git a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java index 7dbc0864..40e96d38 100755 --- a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java +++ b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java @@ -810,7 +810,7 @@ public class SourceFile // In streamconstraintsclone sind die Mengen von Paar enthalten die unifiziert werden muessen Stream> streamconstraintsclone = indexeset.stream().map(x -> x.stream() .map(i -> constraintsClone.elementAt(i)) - .collect(Menge::new, Menge::add, Menge::addAll)); + .>collect(Menge::new, Menge::add, Menge::addAll)); //Menge> vecconstraintsclone = streamconstraintsclone.collect(Menge::new, Menge::add, Menge::addAll); System.out.println(); //Schritt 4: Unifikation diff --git a/src/de/dhbwstuttgart/typeinference/DeepCloneable.java b/src/de/dhbwstuttgart/typeinference/DeepCloneable.java new file mode 100644 index 00000000..c20b6493 --- /dev/null +++ b/src/de/dhbwstuttgart/typeinference/DeepCloneable.java @@ -0,0 +1,18 @@ +package de.dhbwstuttgart.typeinference; + +public interface DeepCloneable{ + public A deepClone(); +} + +/* +public class CloneableMenge extends Menge{ + + public CloneableMenge deepClone(){ + CloneableMenge ret = new CloneableMenge<>(); + for(A i : this){ + ret.add(i.deepClone()); + } + return ret; + } +} +*/ \ No newline at end of file diff --git a/src/de/dhbwstuttgart/typeinference/Menge.java b/src/de/dhbwstuttgart/typeinference/Menge.java index 10df5235..aa2b2f43 100644 --- a/src/de/dhbwstuttgart/typeinference/Menge.java +++ b/src/de/dhbwstuttgart/typeinference/Menge.java @@ -3,6 +3,7 @@ package de.dhbwstuttgart.typeinference; import java.util.Set; import java.util.Vector; + public class Menge extends Vector implements Set{ - + } diff --git a/src/de/dhbwstuttgart/typeinference/Pair.java b/src/de/dhbwstuttgart/typeinference/Pair.java index 21f0e989..dcb13958 100755 --- a/src/de/dhbwstuttgart/typeinference/Pair.java +++ b/src/de/dhbwstuttgart/typeinference/Pair.java @@ -31,7 +31,7 @@ import de.dhbwstuttgart.syntaxtree.type.WildcardType; // Klasse, die ein Paar in der Menge Eq speichern kann // ino.end // ino.class.Pair.26540.declaration -public class Pair implements Serializable +public class Pair implements Serializable, DeepCloneable // ino.end // ino.class.Pair.26540.body { @@ -414,6 +414,7 @@ public class Pair implements Serializable } public Pair deepClone() { + /* try { ByteArrayOutputStream baos = new ByteArrayOutputStream(); ObjectOutputStream oos = new ObjectOutputStream(baos); @@ -427,6 +428,8 @@ public class Pair implements Serializable } catch (ClassNotFoundException e) { return null; } + */ + return clone(); } } // ino.end diff --git a/src/de/dhbwstuttgart/typeinference/unify/Unify.java b/src/de/dhbwstuttgart/typeinference/unify/Unify.java index b7e54a07..bb561cbf 100755 --- a/src/de/dhbwstuttgart/typeinference/unify/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/Unify.java @@ -11,6 +11,9 @@ import java.util.Set; import de.dhbwstuttgart.typeinference.Menge; +import java.util.function.BiConsumer; +import java.util.function.Function; +import java.util.function.Supplier; import java.util.stream.Stream; import com.google.common.collect.Sets; @@ -41,6 +44,7 @@ import de.dhbwstuttgart.syntaxtree.type.ObjectType; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.WildcardType; import de.dhbwstuttgart.typeinference.ConstraintsSet; +import de.dhbwstuttgart.typeinference.DeepCloneable; import de.dhbwstuttgart.typeinference.OderConstraint; import de.dhbwstuttgart.typeinference.Pair; import de.dhbwstuttgart.typeinference.Pair.PairOperator; @@ -674,7 +678,7 @@ public class Unify for (Menge> vecvecpair : cartProduktSets){ if(vecvecpair.size() == 1){//gibt es nur eine UndMenge in diesem Set, dann kommt diese in jedem Karthesischen Produkt vor: //undMenge.addAll(cloner.deepClone(vecvecpair.firstElement())); - undMenge.addAll(vecvecpair.firstElement()); + undMenge.addAll(Unify.deepClone(vecvecpair.firstElement())); temp.add(vecvecpair); }else{//gibt es mehrere Mengen, kann gefiltert werden: oderConstraints.add(vecvecpair); //die Menge zu den zu filternden OderConstraints anfügen @@ -2469,7 +2473,19 @@ throws MatchException inferencelog.debug("Nummer: " + nTypnrInPair); inferencelog.debug("TV: " + a.getName()); inferencelog.debug("Bedingung: " + bMitVorbedingung); - + /* + Cloner cloner = new Cloner(); + cloner.setDumpClonedClasses(true); + SectionLogger log = Logger.getSectionLogger("Subst-Methode", Section.UNIFY); + Timewatch timer = Timewatch.getTimewatch(); + de.dhbwstuttgart.logger.Timestamp timestamp = timer.start("Unify-Subst"); + P = cloner.deepClone(P); + a = cloner.deepClone(a); + o = cloner.deepClone(o); + long time = timestamp.stop(); + log.debug("Benötigte Zeit für DeepClone: "+time); + */ + // richtiger Typ aus Pair raussuchen Type T = null; if( nTypnrInPair == 1 ) @@ -3632,5 +3648,11 @@ tempKlasse.get_Superclass_Name() ); System.out.println( "P. S.: return T instanceof FreshWildcardType; } + private static Menge deepClone(Menge m){ + + Menge ret = m.stream().map((Function)(x -> x.deepClone())).>collect(Menge::new, Menge::add, Menge::addAll); + + return ret; + } } -// ino.end +// ino.end \ No newline at end of file From fbc1bc5b5bd30ee8f106db9f4e74d0d3ccc1ac10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Pl=C3=BCmicke?= Date: Thu, 16 Jul 2015 01:16:06 +0200 Subject: [PATCH 5/8] Cloner durch Unify.deepClone in UndMenge.java ersetzt --- src/de/dhbwstuttgart/typeinference/UndMenge.java | 9 +++++---- src/de/dhbwstuttgart/typeinference/unify/Unify.java | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/UndMenge.java b/src/de/dhbwstuttgart/typeinference/UndMenge.java index 0dd2c06c..6771bf18 100644 --- a/src/de/dhbwstuttgart/typeinference/UndMenge.java +++ b/src/de/dhbwstuttgart/typeinference/UndMenge.java @@ -1,18 +1,19 @@ package de.dhbwstuttgart.typeinference; +import de.dhbwstuttgart.typeinference.unify.Unify; import java.util.Collection; import java.util.Iterator; -import com.rits.cloning.Cloner; +//import com.rits.cloning.Cloner; -public abstract class UndMenge implements KomplexeMenge{ +public abstract class UndMenge implements KomplexeMenge{ public abstract Menge> getSet(); @Override public Menge> cartesianProduct() { Menge> ret = null; - Cloner cloner = new Cloner(); + //Cloner cloner = new Cloner(); for(KomplexeMenge km : this.getSet()){ if(ret == null){ ret = km.cartesianProduct(); @@ -20,7 +21,7 @@ public abstract class UndMenge implements KomplexeMenge{ Menge> cartesianProduct = new Menge<>(); for(Menge r : ret)for(Menge m : km.cartesianProduct()){ //Für jedes Element aus dem Karthesischen Produkt: Menge undElement = new Menge(); - undElement.addAll(cloner.deepClone(r)); + undElement.addAll(Unify.deepClone(r)); undElement.addAll(m); cartesianProduct.add(undElement); } diff --git a/src/de/dhbwstuttgart/typeinference/unify/Unify.java b/src/de/dhbwstuttgart/typeinference/unify/Unify.java index bb561cbf..dbe8d5e1 100755 --- a/src/de/dhbwstuttgart/typeinference/unify/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/Unify.java @@ -3648,7 +3648,7 @@ tempKlasse.get_Superclass_Name() ); System.out.println( "P. S.: return T instanceof FreshWildcardType; } - private static Menge deepClone(Menge m){ + public static Menge deepClone(Menge m){ Menge ret = m.stream().map((Function)(x -> x.deepClone())).>collect(Menge::new, Menge::add, Menge::addAll); From 70b804fc4a23d08e3ca0b1a7688a0680fb603079 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Thu, 16 Jul 2015 01:35:06 +0200 Subject: [PATCH 6/8] =?UTF-8?q?Zeitmessung=20f=C3=BCr=20Clone?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/de/dhbwstuttgart/typeinference/unify/Unify.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/Unify.java b/src/de/dhbwstuttgart/typeinference/unify/Unify.java index bb561cbf..5bd9e505 100755 --- a/src/de/dhbwstuttgart/typeinference/unify/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/Unify.java @@ -23,6 +23,7 @@ import com.rits.cloning.Cloner; import de.dhbwstuttgart.logger.Logger; import de.dhbwstuttgart.logger.Section; import de.dhbwstuttgart.logger.SectionLogger; +import de.dhbwstuttgart.logger.Timestamp; import de.dhbwstuttgart.logger.Timewatch; import de.dhbwstuttgart.core.MyCompiler; import de.dhbwstuttgart.myexception.CTypeReconstructionException; @@ -673,7 +674,7 @@ public class Unify Menge>> temp = new Menge<>(); //hier werden gefilterte Constraints gesammelt Menge undMenge = new Menge(); //Die Menge von Pairs, welche in jedem Kartesischen Produkt enthalten sind. //undMenge.addAll(cloner.deepClone(Eq1)); - undMenge.addAll(Eq1); + undMenge.addAll(Unify.deepClone(Eq1)); Menge>> oderConstraints = new Menge<>();//Die zu filternden Constraints for (Menge> vecvecpair : cartProduktSets){ if(vecvecpair.size() == 1){//gibt es nur eine UndMenge in diesem Set, dann kommt diese in jedem Karthesischen Produkt vor: @@ -691,8 +692,8 @@ public class Unify Menge testMenge = new Menge(); //testMenge.addAll(cloner.deepClone(undMenge)); //testMenge.addAll(cloner.deepClone(pairs)); - testMenge.addAll(undMenge); - testMenge.addAll(pairs); + testMenge.addAll(Unify.deepClone(undMenge)); + testMenge.addAll(Unify.deepClone(pairs)); Menge> test = Unify.unifyFiltered(testMenge, fc_tto, false); if(test.size()>0){ filteredOCons.add(pairs); @@ -3649,9 +3650,10 @@ tempKlasse.get_Superclass_Name() ); System.out.println( "P. S.: } private static Menge deepClone(Menge m){ - + Timewatch watch = Timewatch.getTimewatch(); + Timestamp timer = watch.start("Unify - deepClone"); Menge ret = m.stream().map((Function)(x -> x.deepClone())).>collect(Menge::new, Menge::add, Menge::addAll); - + timer.stop(); return ret; } } From 8d1b2c6b8210a03dab3471d91ce6bd65c88a915b Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Tue, 4 Aug 2015 11:06:18 +0200 Subject: [PATCH 7/8] =?UTF-8?q?Unify=20Debuoutput=20angef=C3=BCgt?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/de/dhbwstuttgart/typeinference/unify/Unify.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/de/dhbwstuttgart/typeinference/unify/Unify.java b/src/de/dhbwstuttgart/typeinference/unify/Unify.java index 1a1b827c..9ffa28e4 100755 --- a/src/de/dhbwstuttgart/typeinference/unify/Unify.java +++ b/src/de/dhbwstuttgart/typeinference/unify/Unify.java @@ -136,8 +136,11 @@ public class Unify //public static Menge> unifyWC (Menge E, FC_TTO fc_tto) public static Menge> unifyFiltered (Menge E, FC_TTO fc_tto, boolean filter) { + SectionLogger log = Logger.getSectionLogger(Unify.class.getName(), Section.UNIFY); + //Schritt 1: Aufrufen der Regeln durch sub_unify. Menge Eq = sub_unify(E,fc_tto); + log.debug("Eq Set nach Schritt 1: "+Eq); /* Schritt 2: Rausfiltern der Typen die entweder beides Typvariablen sind oder nicht. * Sobald ein Paar auftauch, bei denen kein Typ mehr eine Typvariable ist, kann dieses Paar * nicht mehr unifiziert werden, deshalb abbruch.*/ @@ -641,7 +644,7 @@ public class Unify } } //Schritt 4, Teil 2: Kartesisches Produkt bilden. - + log.debug("Unify Sets nach Schritt 4 vor dem Erstellen des Karthesischen Produkts: "+cartProduktSets); /* //TODO: Vor der Bildung des Karthesischen Produkts unmögliche Kombinationen ausfiltern //cartProduktSets kontrollieren: @@ -667,7 +670,6 @@ public class Unify if(filter)log.debug("Karthesisches Produkt nach Filterung: "+bigCartProductErg3); Sets.cartesianProduct(bigCartProductErg3); */ - SectionLogger log = Logger.getSectionLogger(Unify.class.getName(), Section.UNIFY); if(filter){ //Cloner cloner = new Cloner(); From 2d8adb5c696e69b1aa88089bbba951d569f4dc56 Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Wed, 26 Aug 2015 14:48:51 +0200 Subject: [PATCH 8/8] =?UTF-8?q?Beginn=20der=20Implementierung=20von=20Byte?= =?UTF-8?q?code=20f=C3=BCr=20Lambda=20Expression?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .classpath | 5 ++-- src/de/dhbwstuttgart/syntaxtree/Class.java | 4 ++-- .../dhbwstuttgart/syntaxtree/Constructor.java | 5 +++- .../dhbwstuttgart/syntaxtree/SourceFile.java | 2 +- .../syntaxtree/SyntaxTreeNode.java | 6 +++-- .../syntaxtree/misc/ConstructorCall.java | 15 ++++++++---- .../statement/LambdaExpression.java | 24 ++++++++++++------- .../syntaxtree/statement/MethodCall.java | 4 +++- .../syntaxtree/statement/SuperCall.java | 3 +++ .../syntaxtree/statement/This.java | 13 +++++++--- .../TypeInsertTests/LambdaTest16.jav | 1 - .../LambdaTest2_2.java | 3 ++- 12 files changed, 58 insertions(+), 27 deletions(-) rename test/plugindevelopment/TypeInsertTests/{ => LargeSourceCodeTests}/LambdaTest2_2.java (83%) diff --git a/.classpath b/.classpath index a66c92d7..b02a00af 100755 --- a/.classpath +++ b/.classpath @@ -1,12 +1,13 @@ - + + - + diff --git a/src/de/dhbwstuttgart/syntaxtree/Class.java b/src/de/dhbwstuttgart/syntaxtree/Class.java index d00cca51..e2dec91b 100755 --- a/src/de/dhbwstuttgart/syntaxtree/Class.java +++ b/src/de/dhbwstuttgart/syntaxtree/Class.java @@ -1227,10 +1227,10 @@ public class Class extends GTVDeclarationContext implements AClassOrInterface, I //Alle Methoden auf Konstruktoren durchsuchen und diese umwandeln: Menge tempFields = new Menge(); for(Field f : this.getFields()){ - if(f instanceof Method && !(f instanceof Constructor)){ + if(f instanceof Method && !(f instanceof Constructor)){ //Der Check, ob f ein Konstruktor ist eigentlich obsolet, da der Parser keinen Konstruktor generiert Method method = (Method)f; if(method.get_Method_Name().equals(this.getName().toString()) ){ - tempFields.add(new Constructor(method)); + tempFields.add(new Constructor(method, this)); }else{ tempFields.add(f); } diff --git a/src/de/dhbwstuttgart/syntaxtree/Constructor.java b/src/de/dhbwstuttgart/syntaxtree/Constructor.java index e8f651b8..cf592857 100644 --- a/src/de/dhbwstuttgart/syntaxtree/Constructor.java +++ b/src/de/dhbwstuttgart/syntaxtree/Constructor.java @@ -38,11 +38,12 @@ public class Constructor extends Method { * Parser kann nicht zwischen einem Konstruktor und einer Methode unterscheiden. * Diese Klasse beherbegt den als Methode geparsten Konstruktor und wandelt sein verhalten zu dem eines Konstruktors ab. */ - public Constructor(Method methode){ + public Constructor(Method methode, Class parent){ super(methode.get_Method_Name(), methode.getType(), methode.getParameterList(),methode.get_Block(), methode.getGenericDeclarationList(), methode.getOffset()); //Sicherstellen, dass das erste Statement in der Methode ein SuperCall ist: if(this.get_Block().get_Statement().size() <1 || ! (this.get_Block().get_Statement().firstElement() instanceof SuperCall)){ this.get_Block().statements.add(0, new SuperCall(this.get_Block())); + this.parserPostProcessing(parent); } } @Override @@ -121,6 +122,8 @@ public class Constructor extends Method { return this.getType().getName(); } + + } /* diff --git a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java index 40e96d38..1210078c 100755 --- a/src/de/dhbwstuttgart/syntaxtree/SourceFile.java +++ b/src/de/dhbwstuttgart/syntaxtree/SourceFile.java @@ -1779,7 +1779,7 @@ public class SourceFile @Override public void parserPostProcessing(SyntaxTreeNode parent) { if(parent!=null)throw new DebugException("Eine SourceFile hat kein Elternelement im Syntaxbaum"); - super.parserPostProcessing(parent); + super.parserPostProcessing(this); //for(SyntaxTreeNode node : this.getChildren())node.parserPostProcessing(this); } diff --git a/src/de/dhbwstuttgart/syntaxtree/SyntaxTreeNode.java b/src/de/dhbwstuttgart/syntaxtree/SyntaxTreeNode.java index deb03d89..0d234b61 100644 --- a/src/de/dhbwstuttgart/syntaxtree/SyntaxTreeNode.java +++ b/src/de/dhbwstuttgart/syntaxtree/SyntaxTreeNode.java @@ -30,12 +30,14 @@ public abstract class SyntaxTreeNode implements IItemWithOffset{ * */ public void parserPostProcessing(SyntaxTreeNode parent) { + if(parent == null)throw new NullPointerException(); this.parent = parent; for(SyntaxTreeNode node : this.getChildren()) if(node!=null)node.parserPostProcessing(this); } public SyntaxTreeNode getParent() { + //if(this.parent == null)throw new NullPointerException(); return this.parent; } @@ -123,10 +125,10 @@ public abstract class SyntaxTreeNode implements IItemWithOffset{ } public GTVDeclarationContext getGTVDeclarationContext(){ - if(this.getParent()==null)return null; + if(this.getParent()==null) + throw new NullPointerException();//throw new DebugException("getGTVDeclarationContext auf unzulässiger Klasse aufgerufen"); return this.getParent().getGTVDeclarationContext(); } - } diff --git a/src/de/dhbwstuttgart/syntaxtree/misc/ConstructorCall.java b/src/de/dhbwstuttgart/syntaxtree/misc/ConstructorCall.java index 3ef7c81d..b772db27 100644 --- a/src/de/dhbwstuttgart/syntaxtree/misc/ConstructorCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/misc/ConstructorCall.java @@ -1,5 +1,6 @@ package de.dhbwstuttgart.syntaxtree.misc; +import de.dhbwstuttgart.syntaxtree.SyntaxTreeNode; import de.dhbwstuttgart.syntaxtree.statement.ArgumentList; import de.dhbwstuttgart.syntaxtree.statement.MethodCall; import de.dhbwstuttgart.syntaxtree.statement.Receiver; @@ -16,10 +17,10 @@ import de.dhbwstuttgart.typeinference.exceptions.TypeinferenceException; public class ConstructorCall extends MethodCall { public ConstructorCall(Receiver receiver, String methodName, ArgumentList argumentList, int offset){ - super(offset, 0); - this.set_Receiver(receiver); - this.set_Name(methodName); - this.set_ArgumentList(argumentList); + super(receiver, methodName, argumentList,offset); + //this.set_Receiver(receiver); + //this.set_Name(methodName); + //this.set_ArgumentList(argumentList); } /* @@ -38,4 +39,10 @@ public class ConstructorCall extends MethodCall ret.add(constraintsFromMethodAssumption(cAss, assumptions)); return ret; } + + @Override + public void parserPostProcessing(SyntaxTreeNode parent) { + super.parserPostProcessing(parent); + } + } \ No newline at end of file diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java b/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java index 62c3c761..3f9e747f 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/LambdaExpression.java @@ -2,6 +2,7 @@ package de.dhbwstuttgart.syntaxtree.statement; import java.util.Hashtable; +import org.apache.bcel.classfile.BootstrapMethod; import org.apache.bcel.classfile.ConstantPool; import org.apache.bcel.generic.BIPUSH; import org.apache.bcel.generic.ClassGen; @@ -217,20 +218,25 @@ public class LambdaExpression extends Expr{ public InstructionList genByteCode(ClassGen cg) { ConstantPoolGen cp = cg.getConstantPool(); InstructionList il = new InstructionList(); + /* - * Bytecode: - * 0: invokedynamic #2, 0 //#2 führt zu einem InvokeDynamic im KP - wildes Referenzieren - * 5: astore_1 //Speichert wahrscheinlich den String meiner TestEXPR - * 6: return + * Invokedynamic 186 (0xBA) + * - Auf dem Operanten Stack liegen die Argumente + * + * InvokeDynamik_Info Structure auf den der Indexzeiger zeigen muss: https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.4.10 + * + * Ablauf: + * 1. Methode erstellen, mit dem Inhalt der Lambda-Expression //Dabei wird das This-Stat + * 2. Invokedynamic-Call erzeugen + * */ + new BootstrapMethod(); //---Variante 1 mit opcode---- - short opcode = 186;//opcode - was genau ist das? - il.append(new INVOKEDYNAMIC(opcode, 0));//Invokedynamic lässt sich bei mir weder automatisch noch manuell importieren + short opcode = 186; + int index = 0; //indexbyte 1 und 2 müssen ein Zeiger auf ein call site specifier im Konstantenpool sein (InvokeDynamic_Info). + il.append(new INVOKEDYNAMIC(opcode, index)); - //---Variante 2 mit Konstantenpool-Referenz--- - //int cpSize = cp.getSize()-1;//Vermutlich ist die benötigte Referenz das aktuellste Element? - //il.append(new INVOKEDYNAMIC((short) cpSize, 0)); return il; } diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java index 45f2716b..1ea8c297 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/MethodCall.java @@ -299,11 +299,13 @@ public class MethodCall extends Expr return ret; } + /* @Override public void parserPostProcessing(SyntaxTreeNode parent) { super.parserPostProcessing(parent); } - + */ + @Override public InstructionList genByteCode(ClassGen _cg) { // TODO Auto-generated method stub diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java b/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java index eea3f491..6b354f2a 100644 --- a/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/SuperCall.java @@ -65,7 +65,10 @@ public class SuperCall extends ThisCall ((Constructor)p).get_Block().statements.firstElement().equals(this)){ //Constraints generieren: + if(this.arglist == null)this.arglist = new ArgumentList(); + MethodCall constructorCall = new ConstructorCall(new Receiver(new This(this)), className, arglist, this.getOffset()); + constructorCall.parserPostProcessing(this); ret.add(constructorCall.TYPEStmt(assumptions)); return ret; }else{ diff --git a/src/de/dhbwstuttgart/syntaxtree/statement/This.java b/src/de/dhbwstuttgart/syntaxtree/statement/This.java index dfb5f32a..1f5ed185 100755 --- a/src/de/dhbwstuttgart/syntaxtree/statement/This.java +++ b/src/de/dhbwstuttgart/syntaxtree/statement/This.java @@ -5,6 +5,11 @@ package de.dhbwstuttgart.syntaxtree.statement; import java.util.Hashtable; import org.apache.bcel.generic.ClassGen; +import org.apache.bcel.generic.InstructionFactory; +import org.apache.bcel.generic.InstructionHandle; +import org.apache.bcel.generic.InstructionList; +import org.apache.bcel.generic.MethodGen; +import org.apache.bcel.generic.ObjectType; import de.dhbwstuttgart.typeinference.Menge; import de.dhbwstuttgart.logger.Logger; @@ -143,9 +148,11 @@ public class This extends Expr } @Override - public void genByteCode(ClassGen _cg) { - // TODO Auto-generated method stub - + public InstructionList genByteCode(ClassGen _cg) { + InstructionList il = new InstructionList(); + InstructionHandle ih_0 = il.append(InstructionFactory.createLoad(org.apache.bcel.generic.Type.OBJECT, 0)); + InstructionHandle ih_1 = il.append(InstructionFactory.createReturn(org.apache.bcel.generic.Type.OBJECT)); + return il; } } diff --git a/test/plugindevelopment/TypeInsertTests/LambdaTest16.jav b/test/plugindevelopment/TypeInsertTests/LambdaTest16.jav index 839afeb5..bc58f522 100644 --- a/test/plugindevelopment/TypeInsertTests/LambdaTest16.jav +++ b/test/plugindevelopment/TypeInsertTests/LambdaTest16.jav @@ -1,4 +1,3 @@ class Matrix2{ Fun1>, DF> op = (m)->(f)->{return f.apply(this,m);}; } - \ No newline at end of file diff --git a/test/plugindevelopment/TypeInsertTests/LambdaTest2_2.java b/test/plugindevelopment/TypeInsertTests/LargeSourceCodeTests/LambdaTest2_2.java similarity index 83% rename from test/plugindevelopment/TypeInsertTests/LambdaTest2_2.java rename to test/plugindevelopment/TypeInsertTests/LargeSourceCodeTests/LambdaTest2_2.java index 5503c7fe..662846f1 100644 --- a/test/plugindevelopment/TypeInsertTests/LambdaTest2_2.java +++ b/test/plugindevelopment/TypeInsertTests/LargeSourceCodeTests/LambdaTest2_2.java @@ -1,6 +1,7 @@ -package plugindevelopment.TypeInsertTests; +package plugindevelopment.TypeInsertTests.LargeSourceCodeTests; import de.dhbwstuttgart.typeinference.Menge; +import plugindevelopment.TypeInsertTests.MultipleTypesInsertTester; import org.junit.Test;