Compare commits

...

88 Commits

Author SHA1 Message Date
pl@gohorb.ba-horb.de
c68d773486 modified: ../../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java
modified:   ../../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
Threadsteuerung veranendert, so dass möglichst veile Threads gleichzeitig laufen.
Müsste noch verbessert werden können.
2019-11-18 14:37:59 +01:00
pl@gohorb.ba-horb.de
00bbd5279f modified: src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
log-File-Ausgabe etwas ergaenzt

	modified:   src/main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/SyntaxTreeGenerator.java
Fehler korrigiert, dass alle Fieldinitializer bei mehreren Klassen additiv hinzugefuegt werden

	modified:   src/main/java/de/dhbwstuttgart/syntaxtree/statement/This.java
toString veranedert

	modified:   src/test/resources/bytecode/javFiles/mathStruc.jav
leichte Korrektur

	new file:   src/test/java/bytecode/mathStrucIntegerTest.java
	new file:   src/test/resources/bytecode/javFiles/mathStrucInteger.jav
mathStruc auf Integer angewandt

	new file:   src/test/resources/bytecode/javFiles/mathStrucMatrixOP.jav
mathStruc auf MatrixOP angewandt, laeuft noch nicht durch, des halb Test noch nicht eingecheckt
2019-10-24 17:47:51 +02:00
pl@gohorb.ba-horb.de
6c783a18c7 new file: ../../../../../PlugInBau.txt
modified:   ../../bytecode/javFiles/Faculty.jav
	modified:   ../../bytecode/javFiles/OL.jav
	modified:   ../../bytecode/javFiles/Y.jav
	modified:   ../../bytecode/javFiles/mathStruc.jav
2019-10-22 16:44:38 +02:00
Fayez Abu Alia
8c195601d5 Fixed signature problem for FunN 2019-10-12 11:32:56 +02:00
pl@gohorb.ba-horb.de
37f8f2e1e0 modified: ../../bytecode/javFiles/Y.jav
Anwendung von Y eingefuegt.
2019-09-19 13:57:49 +02:00
Fayez Abu Alia
0903efda0d Fixed bug 115 2019-09-19 13:00:35 +02:00
Fayez Abu Alia
c2030123d5 Fixed bugs 163 and 169 2019-09-17 09:33:18 +02:00
Fayez Abu Alia
d1637b8eb9 Merge branch 'bytecode2' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bytecode2 2019-08-29 11:50:23 +02:00
Fayez Abu Alia
9abda637a1 Generic generator algorithm - fixed bug 2019-08-29 10:49:18 +02:00
pl@gohorb.ba-horb.de
82c0837d1f mathStruc.jav hinzugefügt 2019-08-23 15:06:54 +02:00
Fayez Abu Alia
a41e9804a0 Merge branch 'bytecode2' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bytecode2 2019-07-31 13:18:07 +02:00
Fayez Abu Alia
25c685c705 Merged with simplifyRes and cleaned up code 2019-07-31 13:16:14 +02:00
Fayez Abu Alia
3ecb202a90 Generic generator algorithm v1 2019-07-31 11:55:24 +02:00
Fayez Abu Alia
efdb58e67c Added throw Exception to method getSimplifyResultsByName 2019-07-31 10:33:43 +02:00
Fayez Abu Alia
eed8f32cb7 Merge branch 'simplifyRes' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into simplifyRes 2019-07-31 10:27:43 +02:00
Fayez Abu Alia
87d0a46ba5 Generic generator algorithm v0.1 2019-07-31 10:24:58 +02:00
Michael Uhl
5b75250fcf Merge branch 'bigRefactoring' into simplifyRes
# Conflicts:
#	src/main/java/de/dhbwstuttgart/bytecode/utilities/SimplifyResult.java
#	src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
2019-07-29 16:21:25 +02:00
Michael Uhl
7f29b39195 Generic Method inserts. 2019-07-26 10:12:53 +02:00
Fayez Abu Alia
7a4bc32974 Generic generator algorithm v0.1 2019-07-25 22:24:06 +02:00
Fayez Abu Alia
dfddc44f29 Separated the algorithm into two parts. Part 1 is the simplification of
the constraints and part 2 is generation of generics.
2019-07-12 19:50:46 +02:00
Fayez Abu Alia
347d86a379 Genericsgenerator step 2 and 3 2019-07-11 15:52:38 +02:00
Fayez Abu Alia
d77f2176f2 Generics generator step 1 2019-07-10 15:26:16 +02:00
Fayez Abu Alia
4f39eccecb Removed an old getter method 2019-07-05 13:45:24 +02:00
Fayez Abu Alia
669e7f111f Separated the generation of bytecode and the calculation of simplify
results from each other
2019-07-05 13:29:34 +02:00
pl@gohorb.ba-horb.de
32d12677bf Merge branch 'bytecode2' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bytecode2 2019-06-28 11:41:47 +02:00
pl@gohorb.ba-horb.de
92b2f5c9cc modified: src/test/resources/bytecode/javFiles/Faculty.jav
} eingefuegt
2019-06-28 11:41:19 +02:00
Fayez Abu Alia
c1e6526b43 Removed unnecessary tests 2019-06-26 12:18:49 +02:00
Fayez Abu Alia
0194e30206 Fixed Bug 150. 2019-06-26 12:16:47 +02:00
Fayez Abu Alia
3c36c61077 Fixed Bugs 159, 162 and 163 2019-06-13 14:01:32 +02:00
Fayez Abu Alia
857d63322e Fixed Bug 152 Faculty Probleme 2019-06-07 10:28:48 +02:00
Fayez Abu Alia
b801e144c3 Merged with bigRefactoring. Added method to generate signature to
FunN-Interfaces. Adapted jav-Files.
2019-06-06 12:15:51 +02:00
Martin Plümicke
f6669f8c13 new file: ../../../java/bytecode/VectorAddTest.java 2019-06-05 10:28:51 +02:00
Martin Plümicke
2b7aef5e87 modified: ../../../../main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
modified:   ../../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
Pfad fuer logFile nach JavaCompilerCore/logFiles verlegt.

	modified:   ../../bytecode/javFiles/OL.jav
	modified:   ../../bytecode/javFiles/VectorAdd.jav
2019-06-05 10:21:25 +02:00
Michael Uhl
0233426979 Merge remote-tracking branch 'origin/bigRefactoring' into bigRefactoring 2019-05-14 21:54:41 +02:00
Michael Uhl
3d0d11adb7 Code aufgeräumt. 2019-05-14 21:43:32 +02:00
Martin Plümicke
212144db86 renamed: test/java/bytecode/FunOLTest.java -> test/java/bytecode/OLFunTest.java
new file:   test/resources/bytecode/javFiles/OLFun.jav
2019-05-14 20:30:32 +02:00
Martin Plümicke
bd0517ae29 modified: src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
log-File in anderen Pfad

	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java
substitutions gekapselt
2019-05-14 19:54:51 +02:00
Martin Plümicke
f210dd3c25 modified: ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
try der Nullpointer-Exception erweitert.
2019-05-13 11:11:47 +02:00
Martin Plümicke
4602e95f09 modified: ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java 2019-05-12 20:00:03 +02:00
Martin Plümicke
1ef228a045 modified: ../../../main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
auf publich gesetzt
2019-05-12 19:54:30 +02:00
Martin Plümicke
c3c0a11572 Debugabfrage entfernt, die Exception ausgeloest hat
modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyTaskModel.java
Methoden synchronized gemacht
2019-05-12 19:15:26 +02:00
Martin Plümicke
d14406e474 modified: ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
modified:   ../../resources/bytecode/javFiles/MatrixOP.jav
2019-05-10 21:23:28 +02:00
Martin Plümicke
a149b0c391 modified: ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java
modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
	modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/UnifyTaskModel.java

Eigenen Cancel-Mechanismus implementiert
2019-05-10 21:02:24 +02:00
pl@gohorb.ba-horb.de
bfbce81409 Abbruch aller Threads eingebaut
modified:   src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java
	modified:   src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
	new file:   src/main/java/de/dhbwstuttgart/typeinference/unify/UnifyTaskModel.java
2019-05-10 16:30:55 +02:00
Martin Plümicke
985704c0b0 modified: src/main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java
Wen kein Import für die Addition vorhanden ist, wird Fehler ausgegeben
2019-05-08 08:58:19 +02:00
Michael Uhl
1f20fecfee ResultPair durchgeschleift. 2019-05-07 10:38:25 +02:00
Michael Uhl
4b8b0ec362 ConcurrentModificationException umgangen. 2019-05-05 22:33:16 +02:00
Michael Uhl
e48f2b2fd5 Merge remote-tracking branch 'origin/bigRefactoring' into bigRefactoring
# Conflicts:
#	src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java
2019-04-27 16:33:20 +02:00
Michael Uhl
11bee80969 Bytecode-Generierung generiert jetzt wieder Bytecode für alle möglichen Typen. 2019-04-27 16:29:38 +02:00
Martin Plümicke
448c489a49 modified: src/main/java/de/dhbwstuttgart/typeinference/result/ResultSet.java
modified:   src/test/resources/bytecode/javFiles/Lambda.jav
	modified:   src/test/resources/bytecode/javFiles/MatrixOP.jav
	modified:   src/test/resources/bytecode/javFiles/OL.jav
2019-04-27 15:44:21 +02:00
pl@gohorb.ba-horb.de
1e1eb2a2f2 geändert: src/main/java/de/dhbwstuttgart/typeinference/result/ResultSet.java 2019-04-27 14:51:25 +02:00
pl@gohorb.ba-horb.de
4a7c124fd6 Merge branch 'bytecode2' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bigRefactoring 2019-04-27 09:51:22 +02:00
pl@gohorb.ba-horb.de
7d01c866a9 modified: ../src/test/resources/bytecode/javFiles/Id.jav
modified:   ../src/test/resources/bytecode/javFiles/Matrix.jav
	modified:   ../src/test/resources/bytecode/javFiles/MatrixOP.jav
	modified:   ../src/test/resources/bytecode/javFiles/OL.jav
2019-04-26 14:12:46 +02:00
Fayez Abu Alia
73f412d22d Klassendatei fuer FunN beim Methodaufruf wird erzeugt, wenn der Receiver
den Typ FunN besitzt.
Die Loesung vom Duplicate Field Problem wird angepasst.
2019-04-26 11:56:58 +02:00
Fayez Abu Alia
9ffc74467b Wenn ein Attribut mehrere Loesungen bekommt, wird die Bytecodeerzeugung
abgebrochen und ensprechende Exception geworfen.
2019-04-26 10:27:15 +02:00
Fayez Abu Alia
5950fcc0a9 Neue Klasse MethodCallHelper und Exceptions definiert, die fuer die
Uebersetzung von MethodCalls verwendet werden
2019-04-24 15:43:00 +02:00
Martin Plümicke
d2fb17ad4e Merge branch 'bcGenerics' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bcGenerics 2019-04-21 22:32:20 +02:00
Martin Plümicke
d9f084cd0f modified: ../../bytecode/javFiles/Faculty.jav
neue Imports hinzugefuegt
2019-04-21 22:31:55 +02:00
Michael Uhl
481986e8ab Kein Compileraufruf bei Type-Insert
- ResultPairMap wird wieder geleeert.
2019-04-20 17:22:10 +02:00
Michael Uhl
23c37a8cc2 Richtiges Einsetzen ohne Speichern. 2019-04-19 20:49:28 +02:00
Fayez Abu Alia
6a519ff6dc Ein Feld wird nur einmal in Bytecode uebersetzt. genIns in ResultSet
wird angepasst.
2019-04-18 13:17:50 +02:00
Fayez Abu Alia
5b527ec8ab Merge branch 'bcGenerics' of ssh://abualia@gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bcGenerics 2019-04-18 10:50:02 +02:00
Fayez Abu Alia
709041f024 Adapted TypedID jav-file 2019-04-18 10:48:59 +02:00
Michael Uhl
905d9e25a2 [PLUGIN]: Filter type insert points after insertion. 2019-04-18 09:48:56 +02:00
Martin Plümicke
e086ff187e modified: ../../../../main/java/de/dhbwstuttgart/typeinference/result/ResolvedType.java
Attribut additionalGenerics auskommentiert.
2019-04-12 10:41:42 +02:00
Martin Plümicke
588212389a Die Bestimmung der Constraints aus dem ResolvedType herausgenommen und im ResultSet integriert.
Damit kommen immer die gleichen Constraints raus. Diese werden ohnehin in der Bytecodegenerierung
nochmals ausgewertet.

	modified:   ../../../../main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java
Zugriff auf Constraints ueber ResultSet eingefuehrt

	modified:   ../../../../main/java/de/dhbwstuttgart/bytecode/signature/Signature.java
Zugriff auf Constraints ueber ResultSet eingefuehrt

	modified:   ../../../../main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
	modified:   ../../../../main/java/de/dhbwstuttgart/typeinference/result/GenericInsertPair.java
	modified:   ../../../../main/java/de/dhbwstuttgart/typeinference/result/PairTPHequalRefTypeOrWildcardType.java
	modified:   ../../../../main/java/de/dhbwstuttgart/typeinference/result/PairTPHsmallerTPH.java
toString veraendert

	modified:   ../../../../main/java/de/dhbwstuttgart/typeinference/result/ResultSet.java
Attribut genIns eingefuehrt, indem alle GenericInsertPairs gespeichert werden, die Form (TPH a <. TPH b)
im Attribut results haben

	modified:   ../../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
	modified:   ../../bytecode/javFiles/Id.jav
	modified:   ../../bytecode/javFiles/MatrixOP.jav
2019-04-12 10:28:39 +02:00
Martin Plümicke
1454281628 Merge branch 'bigRefactoring' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bcGenerics 2019-04-11 11:57:30 +02:00
Fayez Abu Alia
602216d9e2 Generics beruecksichtigt 2019-04-11 11:26:54 +02:00
Martin Plümicke
e53c29f582 modified: ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
Typeinference-Exception eingefuegt, wenn kein korrekter Typ inferierbar ist.

	modified:   ../../resources/bytecode/javFiles/Id.jav
2019-04-06 00:53:35 +02:00
Martin Plümicke
656c77d16b Merge branch 'bytecode2' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bigRefactoring 2019-04-05 12:52:28 +02:00
Fayez Abu Alia
9d16855ce2 Bug in Matrix gefixt 2019-04-05 12:38:29 +02:00
Fayez Abu Alia
9d2fdf9692 Merge branch 'bytecode2' of ssh://abualia@gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bytecode2 2019-04-05 12:06:22 +02:00
Fayez Abu Alia
5c5b1ea2b1 IdTest funktioniert 2019-04-05 12:05:07 +02:00
Martin Plümicke
2e2227b701 Merge branch 'bytecode2' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bytecode2 2019-04-05 12:00:30 +02:00
Martin Plümicke
16baa5eaa8 modified: ../../../../main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java
modified:   ../../../../main/java/de/dhbwstuttgart/typeinference/unify/model/ReferenceType.java

Konstruktur fuer ReferenceType mit zwei Argumenten versehen, um Generice unterscheiden zu können.
2019-04-05 11:59:34 +02:00
Fayez Abu Alia
588b9ef83a Merge branch 'bytecode2' of ssh://abualia@gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bytecode2 2019-04-05 10:44:52 +02:00
Fayez Abu Alia
ee932892c6 subString durch contains ersetzt 2019-04-05 10:43:09 +02:00
Martin Plümicke
547ad9601a Merge branch 'bytecode2' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bytecode2 2019-04-04 14:08:31 +02:00
Michael Uhl
6c94404f27 [MINOR]: Optimized imports. 2019-03-31 11:45:49 +02:00
Michael Uhl
2b5b677682 Für Eclipse-Plugin: Vorläufige Lösung zum Einsetzen von Generics nur an Klassen ausgeschaltet. 2019-03-31 11:39:57 +02:00
Martin Plümicke
1edc023ed9 modified: ../../../main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java
modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/model/ReferenceType.java
Generische Typvariablen im Unify durch Tag im ReferenceType eingefuehrt
2019-03-28 17:44:42 +01:00
Martin Plümicke
df0f26c021 :w:wq 2019-03-28 16:55:48 +01:00
Michael Uhl
53d1f20a40 Merge remote-tracking branch 'origin/bytecode2' into bytecode2 2019-03-28 14:56:47 +01:00
Michael Uhl
ec4defd087 Getter and setter for token. 2019-03-28 14:56:36 +01:00
Fayez Abu Alia
6a2a8313e6 Generics werden in Signature richtig dargestellt und die passende
Deskriptoren werden richtig erzeugt
2019-03-28 14:07:04 +01:00
Fayez Abu Alia
d4a59517d3 Wenn die Klasse keine Generics besitzt und Methoden besitzen Generics
wird eine new SimplifyResult Instanz erzeugt, da sonst eine
NullException aufgelöst wird
2019-03-21 12:23:50 +01:00
Fayez Abu Alia
f4b5124fd3 Merge branch 'bytecode2' of ssh://abualia@gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bytecode2 2019-03-21 12:06:01 +01:00
Fayez Abu Alia
c921330b55 Methode getSimplifyList definiert, die eine Liste von Ergebnisse des
Simplify-Alg zurueckliefert
2019-03-21 12:03:13 +01:00
141 changed files with 26494 additions and 24021 deletions

22
PlugInBau.txt Normal file
View File

@@ -0,0 +1,22 @@
Repositories: Branches: JavaCompilerCore: simplyRes
JavaCompilerPlugin: copy_libs
JavaCompilerCore > mvn install -Dskip.test=true
[INFO] Installing /Users/pl/workspace_oxygen/JavaCompilerCore/target/JavaTXcompiler-0.2.jar to /Users/pl/.m2/repository/de/dhbwstuttgart/JavaTXcompiler/0.2/JavaTXcompiler-0.2.jar
[INFO] Installing /Users/pl/workspace_oxygen/JavaCompilerCore/pom.xml to /Users/pl/.m2/repository/de/dhbwstuttgart/JavaTXcompiler/0.2/JavaTXcompiler-0.2.pom
[INFO] Installing /Users/pl/workspace_oxygen/JavaCompilerCore/target/JavaTXcompiler-0.2-jar-with-dependencies.jar to /Users/pl/.m2/repository/de/dhbwstuttgart/JavaTXcompiler/0.2/JavaTXcompiler-0.2-jar-with-dependencies.jar
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 23.279 s
[INFO] Finished at: 2019-09-17T09:31:30+02:00
[INFO] -------------------------------------
JavaCompilerCore > cd target
JavaCompilerCore/target > cp JavaTXcompiler-0.2.jar ../../Plugin_JCC/JavaCompilerPlugin/bundles/JavaCompilerPlugin.Plugin/lib/JavaTXcompiler.jar
Im Eclipse: Plugin_JCC/JavaCompilerPlugin> mvn install
Plugin_JCC/JavaCompilerPlugin/releng/JavaCompilerPlugin.Update/target > cp JavaCompilerPlugin.Update-0.1.0-SNAPSHOT.zip ~/webdav/public_html/javatx/javatx_XXXXXX.zip

View File

@@ -7,14 +7,14 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<artifactId>JavaTXcompiler</artifactId> <artifactId>JavaTXcompiler</artifactId>
<packaging>jar</packaging> <packaging>jar</packaging>
<version>0.1</version> <version>0.2</version>
<name>JavaTXcompiler</name> <name>JavaTXcompiler</name>
<url>http://maven.apache.org</url> <url>http://maven.apache.org</url>
<dependencies> <dependencies>
<dependency> <dependency>
<groupId>junit</groupId> <groupId>junit</groupId>
<artifactId>junit</artifactId> <artifactId>junit</artifactId>
<version>4.0</version> <version>4.11</version>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency> <dependency>
@@ -127,7 +127,7 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<!-- specify your depencies here --> <!-- specify your depencies here -->
<!-- groupId:artifactId:version --> <!-- groupId:artifactId:version -->
<artifact> <artifact>
<id>de.dhbwstuttgart:JavaTXcompiler:0.1</id> <id>de.dhbwstuttgart:JavaTXcompiler:0.2</id>
</artifact> </artifact>
<artifact> <artifact>
<id>org.reflections:reflections:0.9.11</id> <id>org.reflections:reflections:0.9.11</id>

View File

@@ -61,7 +61,7 @@ public class ArgumentVisitor implements StatementVisitor {
assign.accept(bytecodeGenMethod); assign.accept(bytecodeGenMethod);
if(argListMethCall.get(0)) if(argListMethCall.get(0))
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(assign.getType())); bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(assign.getType()));
argListMethCall.remove(0); argListMethCall.remove(0);
} }
@@ -70,9 +70,9 @@ public class ArgumentVisitor implements StatementVisitor {
binary.accept(bytecodeGenMethod); binary.accept(bytecodeGenMethod);
if(argListMethCall.get(0)) { if(argListMethCall.get(0)) {
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(binary.getType())); bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(binary.getType()));
} else { } else {
bytecodeGenMethod.doBoxing(bytecodeGenMethod.getResolvedType(binary.getType())); bytecodeGenMethod.doBoxing(bytecodeGenMethod.getResolver().getResolvedType(binary.getType()));
} }
argListMethCall.remove(0); argListMethCall.remove(0);
} }
@@ -88,7 +88,7 @@ public class ArgumentVisitor implements StatementVisitor {
castExpr.accept(bytecodeGenMethod); castExpr.accept(bytecodeGenMethod);
if(argListMethCall.get(0)) if(argListMethCall.get(0))
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(castExpr.getType())); bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(castExpr.getType()));
argListMethCall.remove(0); argListMethCall.remove(0);
} }
@@ -103,7 +103,7 @@ public class ArgumentVisitor implements StatementVisitor {
fieldVar.accept(bytecodeGenMethod); fieldVar.accept(bytecodeGenMethod);
if(argListMethCall.get(0)) if(argListMethCall.get(0))
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(fieldVar.getType())); bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(fieldVar.getType()));
argListMethCall.remove(0); argListMethCall.remove(0);
} }
@@ -124,7 +124,7 @@ public class ArgumentVisitor implements StatementVisitor {
instanceOf.accept(bytecodeGenMethod); instanceOf.accept(bytecodeGenMethod);
if(argListMethCall.get(0)) if(argListMethCall.get(0))
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(instanceOf.getType())); bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(instanceOf.getType()));
argListMethCall.remove(0); argListMethCall.remove(0);
} }
@@ -133,7 +133,7 @@ public class ArgumentVisitor implements StatementVisitor {
localVar.accept(bytecodeGenMethod); localVar.accept(bytecodeGenMethod);
if(!bytecodeGenMethod.isBinaryExp) { if(!bytecodeGenMethod.isBinaryExp) {
if(argListMethCall.get(0)) if(argListMethCall.get(0))
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(localVar.getType())); bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(localVar.getType()));
} }
argListMethCall.remove(0); argListMethCall.remove(0);
} }
@@ -149,7 +149,7 @@ public class ArgumentVisitor implements StatementVisitor {
methodCall.accept(bytecodeGenMethod); methodCall.accept(bytecodeGenMethod);
if(argListMethCall.get(0)) if(argListMethCall.get(0))
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(methodCall.getType())); bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(methodCall.getType()));
argListMethCall.remove(0); argListMethCall.remove(0);
} }
@@ -158,7 +158,7 @@ public class ArgumentVisitor implements StatementVisitor {
methodCall.accept(bytecodeGenMethod); methodCall.accept(bytecodeGenMethod);
if(argListMethCall.get(0)) if(argListMethCall.get(0))
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(methodCall.getType())); bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(methodCall.getType()));
argListMethCall.remove(0); argListMethCall.remove(0);
} }
@@ -197,7 +197,7 @@ public class ArgumentVisitor implements StatementVisitor {
aThis.accept(bytecodeGenMethod); aThis.accept(bytecodeGenMethod);
if(argListMethCall.get(0)) if(argListMethCall.get(0))
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(aThis.getType())); bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(aThis.getType()));
argListMethCall.remove(0); argListMethCall.remove(0);
} }
@@ -242,7 +242,7 @@ public class ArgumentVisitor implements StatementVisitor {
unaryExpr.accept(bytecodeGenMethod); unaryExpr.accept(bytecodeGenMethod);
if(argListMethCall.get(0)) if(argListMethCall.get(0))
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(unaryExpr.getType())); bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(unaryExpr.getType()));
argListMethCall.remove(0); argListMethCall.remove(0);
} }
@@ -251,7 +251,7 @@ public class ArgumentVisitor implements StatementVisitor {
literal.accept(bytecodeGenMethod); literal.accept(bytecodeGenMethod);
if(argListMethCall.get(0)) if(argListMethCall.get(0))
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(literal.getType())); bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolver().getResolvedType(literal.getType()));
argListMethCall.remove(0); argListMethCall.remove(0);
} }

View File

@@ -1,46 +1,77 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.NoSuchElementException;
import java.util.Optional; import java.util.Optional;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.statement.*;
import org.objectweb.asm.ClassWriter; import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.FieldVisitor; import org.objectweb.asm.FieldVisitor;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint; import de.dhbwstuttgart.bytecode.Exception.BytecodeGeneratorError;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString; import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor; import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
import de.dhbwstuttgart.bytecode.signature.Signature; import de.dhbwstuttgart.bytecode.signature.Signature;
import de.dhbwstuttgart.bytecode.signature.TypeToSignature; import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
import de.dhbwstuttgart.bytecode.signature.TypeToString; import de.dhbwstuttgart.bytecode.signature.TypeToString;
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH; import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGenratorResultForSourceFile;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResultForClass;
import de.dhbwstuttgart.bytecode.utilities.MethodUtility;
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor; import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
import de.dhbwstuttgart.bytecode.utilities.NormalMethod; import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
import de.dhbwstuttgart.bytecode.utilities.Simplify; import de.dhbwstuttgart.bytecode.utilities.Resolver;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.ASTVisitor;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.Field;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
import de.dhbwstuttgart.syntaxtree.statement.Assign;
import de.dhbwstuttgart.syntaxtree.statement.AssignToField;
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr;
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.CastExpr;
import de.dhbwstuttgart.syntaxtree.statement.DoStmt;
import de.dhbwstuttgart.syntaxtree.statement.EmptyStmt;
import de.dhbwstuttgart.syntaxtree.statement.ExpressionReceiver;
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
import de.dhbwstuttgart.syntaxtree.statement.ForStmt;
import de.dhbwstuttgart.syntaxtree.statement.IfStmt;
import de.dhbwstuttgart.syntaxtree.statement.InstanceOf;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
import de.dhbwstuttgart.syntaxtree.statement.Literal; import de.dhbwstuttgart.syntaxtree.statement.Literal;
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl;
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
import de.dhbwstuttgart.syntaxtree.statement.NewArray;
import de.dhbwstuttgart.syntaxtree.statement.NewClass;
import de.dhbwstuttgart.syntaxtree.statement.Return;
import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid;
import de.dhbwstuttgart.syntaxtree.statement.StaticClassName;
import de.dhbwstuttgart.syntaxtree.statement.Super;
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
import de.dhbwstuttgart.syntaxtree.statement.This;
import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr;
import de.dhbwstuttgart.syntaxtree.statement.WhileStmt;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType; import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
import de.dhbwstuttgart.typeinference.result.ResolvedType;
import de.dhbwstuttgart.typeinference.result.ResultPair;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
public class BytecodeGen implements ASTVisitor { public class BytecodeGen implements ASTVisitor {
@@ -50,9 +81,10 @@ public class BytecodeGen implements ASTVisitor {
String type; String type;
public static RefTypeOrTPHOrWildcardOrGeneric THISTYPE = null; public static RefTypeOrTPHOrWildcardOrGeneric THISTYPE = null;
String className; private String className;
private String pkgName;
private boolean isInterface; private boolean isInterface;
private List<ResultSet> listOfResultSets; private Collection<ResultSet> listOfResultSets;
private ResultSet resultSet; private ResultSet resultSet;
private SourceFile sf; private SourceFile sf;
private String path; private String path;
@@ -63,46 +95,55 @@ public class BytecodeGen implements ASTVisitor {
private String superClass; private String superClass;
private ArrayList<TypePlaceholder> tphsClass; private List<String> tphsClass;
// stores parameter, local vars and the next index on the local variable table, which use for aload_i, astore_i,... // stores parameter, local vars and the next index on the local variable table,
// which use for aload_i, astore_i,...
HashMap<String, Integer> paramsAndLocals = new HashMap<>(); HashMap<String, Integer> paramsAndLocals = new HashMap<>();
// stores generics and their bounds of class // stores generics and their bounds of class
HashMap<String, String> genericsAndBounds = new HashMap<>(); HashMap<String, String> genericsAndBounds = new HashMap<>();
private int constructorPos = 0; private int constructorPos = 0;
private final TPHExtractor tphExtractor = new TPHExtractor();
private final ArrayList<GenericInsertPair> commonPairs = new ArrayList<>();
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes = new HashMap<>(); HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes = new HashMap<>();
byte[] bytecode; byte[] bytecode;
HashMap<String, byte[]> classFiles; HashMap<String, byte[]> classFiles;
ArrayList<String> methodNameAndParamsT = new ArrayList<>(); private final ArrayList<String> methodNameAndParamsT = new ArrayList<>();
private final ArrayList<String> fieldNameAndParamsT = new ArrayList<>();
public BytecodeGen(HashMap<String,byte[]> classFiles, List<ResultSet> listOfResultSets,SourceFile sf ,String path) { private final ArrayList<String> fieldNameSignature = new ArrayList<>();
private List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles;
private GenericsGeneratorResultForClass generatedGenerics;
private Resolver resolver;
public BytecodeGen(HashMap<String, byte[]> classFiles, Collection<ResultSet> listOfResultSets, List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles, SourceFile sf,
String path) {
this.classFiles = classFiles; this.classFiles = classFiles;
this.listOfResultSets = listOfResultSets; this.listOfResultSets = listOfResultSets;
this.simplifyResultsForAllSourceFiles = simplifyResultsForAllSourceFiles;
this.sf = sf; this.sf = sf;
this.path = path; this.path = path;
this.pkgName = sf.getPkgName();
} }
@Override @Override
public void visit(SourceFile sourceFile) { public void visit(SourceFile sourceFile) {
for (ClassOrInterface cl : sourceFile.getClasses()) { for (ClassOrInterface cl : sourceFile.getClasses()) {
System.out.println("in Class: " + cl.getClassName().toString()); System.out.println("in Class: " + cl.getClassName().toString());
BytecodeGen classGen = new BytecodeGen(classFiles, listOfResultSets, sf, path); BytecodeGen classGen = new BytecodeGen(classFiles, listOfResultSets, simplifyResultsForAllSourceFiles, sf, path);
cl.accept(classGen); cl.accept(classGen);
classGen.writeClass(cl.getClassName().toString()); classGen.writeClass(cl.getClassName().toString());
} }
} }
/** /**
* Associates the bytecode of the class that was build with the classWriter {@link #cw} * Associates the bytecode of the class that was build with the classWriter
* with the class name in the map {@link #classFiles} * {@link #cw} with the class name in the map {@link #classFiles}
* *
* @param name name of the class with which the the bytecode is to be associated * @param name name of the class with which the bytecode is to be associated
*/ */
private void writeClass(String name) { private void writeClass(String name) {
bytecode = cw.toByteArray(); bytecode = cw.toByteArray();
@@ -114,7 +155,6 @@ public class BytecodeGen implements ASTVisitor {
return classFiles; return classFiles;
} }
@Override @Override
public void visit(ClassOrInterface classOrInterface) { public void visit(ClassOrInterface classOrInterface) {
@@ -124,62 +164,43 @@ public class BytecodeGen implements ASTVisitor {
isInterface = (classOrInterface.getModifiers() & 512) == 512; isInterface = (classOrInterface.getModifiers() & 512) == 512;
int acc = isInterface?classOrInterface.getModifiers()+Opcodes.ACC_ABSTRACT:classOrInterface.getModifiers()+Opcodes.ACC_SUPER; int acc = isInterface ? classOrInterface.getModifiers() + Opcodes.ACC_ABSTRACT
: classOrInterface.getModifiers() + Opcodes.ACC_SUPER;
fieldInitializations = classOrInterface.getfieldInitializations(); fieldInitializations = classOrInterface.getfieldInitializations();
// resultSet = listOfResultSets.get(0); // resultSet = listOfResultSets.get(0);
boolean isConsWithNoParamsVisited = false;
boolean isVisited = false; boolean isVisited = false;
for(ResultSet rs : listOfResultSets) { List<ResultSet> listOfResultSetsList = new ArrayList<>(listOfResultSets);
generatedGenerics = simplifyResultsForAllSourceFiles.stream().map(sr->sr.getSimplifyResultsByName(pkgName, className)).findFirst().get();
for (int i = 0; i < listOfResultSetsList.size(); i++) {
//for (ResultSet rs : listOfResultSets) {
superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()); superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor());
resultSet = rs; resultSet = listOfResultSetsList.get(i);
tphExtractor.setResultSet(resultSet); resolver = new Resolver(resultSet);
// tphExtractor.setResultSet(resultSet);
// Nur einmal ausführen!! // Nur einmal ausführen!!
if (!isVisited) { if (!isVisited) {
classOrInterface.accept(tphExtractor);
getCommonTPHS(tphExtractor);
tphsClass = new ArrayList<>();
for(TypePlaceholder t : tphExtractor.allTPHS.keySet()) {
if(!tphExtractor.allTPHS.get(t))
tphsClass.add(t);
}
String sig = null; String sig = null;
/* if class has generics then creates signature /*
* Signature looks like: * if class has generics then creates signature Signature looks like:
* <E:Ljava/...>Superclass * <E:Ljava/...>Superclass
*/ */
if(classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty() || if (classOrInterface.getGenerics().iterator().hasNext() || classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<")
classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<") || !generatedGenerics.getClassConstraints().isEmpty()) {
|| !tphsClass.isEmpty()) {
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraintsClass(tphExtractor,tphsClass);
ArrayList<TPHConstraint> consClass = new ArrayList<>();
for(TPHConstraint cons : constraints.keySet()) {
TypePlaceholder right = null;
for(TypePlaceholder tph : tphsClass) {
if(cons.getLeft().equals(tph.getName())) {
consClass.add(cons); List<GenericsGeneratorResult> consClass = generatedGenerics.getClassConstraints();
right = getTPH(cons.getRight()); //
} Signature signature = new Signature(classOrInterface, genericsAndBounds, consClass);
} sig = signature.createSignatureForClassOrInterface();
if(right != null) {
tphsClass.add(right);
removeFromMethod(right.getName());
right = null;
}
}
Signature signature = new Signature(classOrInterface, genericsAndBounds,commonPairs,tphsClass, consClass);
sig = signature.toString();
System.out.println("Signature: => " + sig); System.out.println("Signature: => " + sig);
} }
cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString() cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString(), sig,
, sig, classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null); classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null);
isVisited = true; isVisited = true;
} }
@@ -189,12 +210,7 @@ public class BytecodeGen implements ASTVisitor {
} }
for (Constructor c : classOrInterface.getConstructors()) { for (Constructor c : classOrInterface.getConstructors()) {
// if(!isConsWithNoParamsVisited) {
c.accept(this); c.accept(this);
// }
// if(!c.getParameterList().iterator().hasNext())
// isConsWithNoParamsVisited = true;
} }
for (Method m : classOrInterface.getMethods()) { for (Method m : classOrInterface.getMethods()) {
@@ -205,69 +221,20 @@ public class BytecodeGen implements ASTVisitor {
} }
private void removeFromMethod(String name) {
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
ArrayList<String> toRemove = new ArrayList<>();
for(String tph : m.getTphs()) {
if(tph.equals(name)) {
toRemove.add(tph);
}
}
if(!toRemove.isEmpty()) {
m.getTphs().removeAll(toRemove);
return;
}
}
}
private TypePlaceholder getTPH(String name) {
for(TypePlaceholder tph: tphExtractor.allTPHS.keySet()) {
if(tph.getName().equals(name))
return tph;
}
throw new NoSuchElementException("TPH "+name +" does not exist");
}
private void getCommonTPHS(TPHExtractor tphExtractor) {
// Gemeinsame TPHs
ArrayList<TypePlaceholder> cTPHs = new ArrayList<>();
// Alle TPHs der Felder speichern
for(TypePlaceholder tph : tphExtractor.allTPHS.keySet()) {
if(!tphExtractor.allTPHS.get(tph))
cTPHs.add(tph);
}
}
@Override @Override
public void visit(Constructor field) { public void visit(Constructor field) {
System.out.println("ResultSet: ");
resultSet.results.forEach(a->{
System.out.println(a.getLeft().toString() + " = " + a.getRight().toString());
});
System.out.println("---------------");
// stores generics and their bounds of method // stores generics and their bounds of method
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>(); HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
field.getParameterList().accept(this); field.getParameterList().accept(this);
String methParamTypes = field.name+"%%"; String id = MethodUtility.createID(resolver, field);
Iterator<FormalParameter> itr = field.getParameterList().iterator(); if (methodNameAndParamsT.contains(id)) {
while(itr.hasNext()) {
FormalParameter fp = itr.next();
methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";";
// methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";";
}
if(methodNameAndParamsT.contains(methParamTypes)) {
System.out.println("ignore - Method: "+field.name +" , paramsType: "+methParamTypes);
return; return;
} }
methodNameAndParamsT.add(methParamTypes); methodNameAndParamsT.add(id);
System.out.println("Method: "+field.name +" , paramsType: "+methParamTypes); System.out.println("Constructor: " + field.name + " , paramsType: " + id);
String desc = null; String desc = null;
boolean hasGen = false; boolean hasGen = false;
@@ -275,17 +242,18 @@ public class BytecodeGen implements ASTVisitor {
for (String paramName : methodParamsAndTypes.keySet()) { for (String paramName : methodParamsAndTypes.keySet()) {
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature()); String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature());
System.out.println(typeOfParam); System.out.println(typeOfParam);
if(genericsAndBounds.containsKey(typeOfParam) ||typeOfParam.contains("$") if (genericsAndBounds.containsKey(typeOfParam) || typeOfParam.contains("$") || typeOfParam.contains("<")) {
|| typeOfParam.contains("<")) {
hasGen = true; hasGen = true;
break; break;
} }
} }
String sig = null; String sig = null;
if (hasGen) { if (hasGen) {
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(field.name, tphExtractor,tphsClass); List<GenericsGeneratorResult> constraints = generatedGenerics.getClassConstraints();
Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,constraints); Signature signature = new Signature(genericsAndBounds,
sig = signature.toString(); methodParamsAndTypes, resultSet, constraints);
sig = signature.createSignatureForConstructor(field);
} }
if (field.getParameterList().iterator().hasNext()) if (field.getParameterList().iterator().hasNext())
System.out.println(field.getParameterList().iterator().next().getType().acceptTV(new TypeToDescriptor())); System.out.println(field.getParameterList().iterator().next().getType().acceptTV(new TypeToDescriptor()));
@@ -302,7 +270,8 @@ public class BytecodeGen implements ASTVisitor {
BytecodeGenMethod gen = new BytecodeGenMethod(className, superClass, resultSet, field, mv, paramsAndLocals, cw, BytecodeGenMethod gen = new BytecodeGenMethod(className, superClass, resultSet, field, mv, paramsAndLocals, cw,
genericsAndBoundsMethod, genericsAndBounds, isInterface, classFiles, sf, path, block, constructorPos); genericsAndBoundsMethod, genericsAndBounds, isInterface, classFiles, sf, path, block, constructorPos);
if(!field.getParameterList().iterator().hasNext() && !(field.block.statements.get(field.block.statements.size()-1) instanceof ReturnVoid)) { if (!field.getParameterList().iterator().hasNext()
&& !(field.block.statements.get(field.block.statements.size() - 1) instanceof ReturnVoid)) {
mv.visitInsn(Opcodes.RETURN); mv.visitInsn(Opcodes.RETURN);
} }
mv.visitMaxs(0, 0); mv.visitMaxs(0, 0);
@@ -311,27 +280,23 @@ public class BytecodeGen implements ASTVisitor {
@Override @Override
public void visit(Method method) { public void visit(Method method) {
// TODO: check if the method is static => if static then the first param will be stored in pos 0 // TODO: check if the method is static => if static then the first param will be
// stored in pos 0
// else it will be stored in pos 1 and this will be stored in pos 0 // else it will be stored in pos 1 and this will be stored in pos 0
String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor()); String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
// String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
String methParamTypes = retType+method.name+"%%";
method.getParameterList().accept(this);
Iterator<FormalParameter> itr = method.getParameterList().iterator(); String id = MethodUtility.createID(resolver, method);
while(itr.hasNext()) {
FormalParameter fp = itr.next();
methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";";
// methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";";
}
if(methodNameAndParamsT.contains(methParamTypes)) { if (methodNameAndParamsT.contains(id)) {
return; return;
} }
methodNameAndParamsT.add(methParamTypes); methodNameAndParamsT.add(id);
System.out.println("Method: "+method.name +" , paramsType: "+methParamTypes); System.out.println("Method: " + method.name + " , paramsType: " + id);
// stores generics and their bounds of method // stores generics and their bounds of method
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>(); HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
method.getParameterList().accept(this);
String methDesc = null; String methDesc = null;
// Method getModifiers() ? // Method getModifiers() ?
@@ -339,43 +304,48 @@ public class BytecodeGen implements ASTVisitor {
System.out.println(acc); System.out.println(acc);
/* Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist */ /* Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist */
boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.subSequence(0, 4).equals("TPH ") || boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.contains("TPH ")
resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature()).contains("<"); || resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature())
/*Wenn die Rückgabe-Type eine Typ-variable ist, erzeuge direkt die Signature, wenn nicht, .contains("<");
* prüfe, ob einer der Parameter Typ-Variable als Typ hat*/ /*
* Wenn die Rückgabe-Type eine Typ-variable ist, erzeuge direkt die Signature,
* wenn nicht, prüfe, ob einer der Parameter Typ-Variable als Typ hat
*/
if (!hasGenInParameterList) { if (!hasGenInParameterList) {
for (String paramName : methodParamsAndTypes.keySet()) { for (String paramName : methodParamsAndTypes.keySet()) {
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor()); String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor());
String sigOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature()); String sigOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature());
if(genericsAndBounds.containsKey(typeOfParam)||typeOfParam.substring(0, 4).equals("TPH ")||sigOfParam.contains("<")) { if (genericsAndBounds.containsKey(typeOfParam) || typeOfParam.contains("TPH ")
|| sigOfParam.contains("<")) {
hasGenInParameterList = true; hasGenInParameterList = true;
break; break;
} }
} }
} }
//TODO: Test if the return-type or any of the parameter is a parameterized type. (VP) // TODO: Test if the return-type or any of the parameter is a parameterized
// type. (VP)
// then create the descriptor with the new syntax. // then create the descriptor with the new syntax.
String sig = null; String sig = null;
/* method.getGenerics: <....> RT method(..) /*
* */ * method.getGenerics: <....> RT method(..)
*/
boolean hasGen = method.getGenerics().iterator().hasNext() || hasGenInParameterList; boolean hasGen = method.getGenerics().iterator().hasNext() || hasGenInParameterList;
/* if method has generics or return type is TPH, create signature */ /* if method has generics or return type is TPH, create signature */
// zwite operand muss weggelassen werden // zwite operand muss weggelassen werden
if(hasGen||resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString()).equals("TPH")) { if (hasGen || resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString())
System.out.println("ALL CONST: " + tphExtractor.allCons.size()); .equals("TPH")) {
tphExtractor.allCons.forEach(c->System.out.println(c.toString()));
System.out.println("----------------"); List<GenericsGeneratorResult> constraints = generatedGenerics.getMethodConstraintsByID(id);
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(method.name, tphExtractor, tphsClass); List<GenericsGeneratorResult> classConstraints = generatedGenerics.getClassConstraints();
// ArrayList<GenericInsertPair> pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons); Signature signature = new Signature(genericsAndBoundsMethod, genericsAndBounds,
Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet,constraints); methodParamsAndTypes, resultSet, constraints,classConstraints);
sig = signature.toString(); sig = signature.createSignatureForMethod(method);
} }
System.out.println(method.getName() + " ==> " + sig); System.out.println(method.getName() + " ==> " + sig);
NormalMethod meth = new NormalMethod(method, genericsAndBounds, genericsAndBoundsMethod, hasGen); NormalMethod meth = new NormalMethod(method, genericsAndBounds, genericsAndBoundsMethod, hasGen);
methDesc = meth.accept(new DescriptorToString(resultSet)); methDesc = meth.accept(new DescriptorToString(resultSet));
// System.out.println(methDesc);
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + acc, method.getName(), methDesc, sig, null); MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + acc, method.getName(), methDesc, sig, null);
mv.visitCode(); mv.visitCode();
@@ -440,7 +410,8 @@ public class BytecodeGen implements ASTVisitor {
public void visit(FieldVar fieldVar) { public void visit(FieldVar fieldVar) {
System.out.println("In FieldVar ---"); System.out.println("In FieldVar ---");
// cw.newField(fieldVar.receiver.toString(), fieldVar.fieldVarName.toString(), fieldVar.getType().toString()); // cw.newField(fieldVar.receiver.toString(), fieldVar.fieldVarName.toString(), fieldVar.getType().toString());
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, fieldVar.fieldVarName, "L"+fieldVar.getType()+";", null, null); FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, fieldVar.fieldVarName, "L" + fieldVar.getType() + ";",
null, null);
fv.visitEnd(); fv.visitEnd();
} }
@@ -455,14 +426,23 @@ public class BytecodeGen implements ASTVisitor {
} }
des += ";"; des += ";";
System.out.println(des); System.out.println(des);
String sig = resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToSignature()); String sig = resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToSignature(generatedGenerics.getClassConstraints()));
System.out.println(sig); System.out.println(sig);
if (sig.charAt(sig.length() - 1) != (";").charAt(0)) { if (sig.charAt(sig.length() - 1) != (";").charAt(0)) {
sig += ";"; sig += ";";
} }
cw.visitField(field.modifier, field.getName(), String nameAndDesc = field.getName() + "%%" + des;
des, sig, String nameAndSig = field.getName() + "%%" + sig;
null); if (fieldNameAndParamsT.contains(nameAndDesc)) {
if (fieldNameSignature.contains(nameAndSig)) {
return;
}
throw new BytecodeGeneratorError("Bytecode generation aborted due to duplicate field name&signature");
}
fieldNameAndParamsT.add(nameAndDesc);
fieldNameSignature.add(nameAndSig);
cw.visitField(field.modifier, field.getName(), des, sig, null);
} }
@Override @Override
@@ -643,5 +623,4 @@ public class BytecodeGen implements ASTVisitor {
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }

View File

@@ -1,9 +1,5 @@
package de.dhbwstuttgart.bytecode; package de.dhbwstuttgart.bytecode;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.invoke.CallSite; import java.lang.invoke.CallSite;
import java.lang.invoke.MethodHandle; import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
@@ -14,11 +10,10 @@ import java.net.URLClassLoader;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Map;
import de.dhbwstuttgart.bytecode.utilities.*;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr.Operator; import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr.Operator;
@@ -30,36 +25,28 @@ import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor; import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes; import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureVisitor;
import org.objectweb.asm.signature.SignatureWriter;
import de.dhbwstuttgart.bytecode.Exception.NotInCurrentPackageException;
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString; import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor; import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
import de.dhbwstuttgart.bytecode.signature.Signature;
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
import de.dhbwstuttgart.bytecode.utilities.KindOfLambda;
import de.dhbwstuttgart.bytecode.utilities.Lambda;
import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
import de.dhbwstuttgart.bytecode.utilities.SamMethod;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.SourceFile; import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.StatementVisitor; import de.dhbwstuttgart.syntaxtree.StatementVisitor;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
import javassist.NotFoundException;
public class BytecodeGenMethod implements StatementVisitor { public class BytecodeGenMethod implements StatementVisitor {
private Resolver resolver;
private Method m; private Method m;
private MethodVisitor mv; private MethodVisitor mv;
private HashMap<String, Integer> paramsAndLocals = new HashMap<>(); private HashMap<String, Integer> paramsAndLocals = new HashMap<>();
private String className; private String className;
private int lamCounter = -1; private int lamCounter;
private ClassWriter cw; private ClassWriter cw;
private ResultSet resultSet; private ResultSet resultSet;
private boolean isInterface; private boolean isInterface;
@@ -98,6 +85,7 @@ public class BytecodeGenMethod implements StatementVisitor {
this.className = className; this.className = className;
this.superClass = superClass; this.superClass = superClass;
this.resultSet = resultSet; this.resultSet = resultSet;
this.resolver = new Resolver(resultSet);
this.m = m; this.m = m;
this.mv = mv; this.mv = mv;
this.paramsAndLocals = paramsAndLocals; this.paramsAndLocals = paramsAndLocals;
@@ -108,6 +96,7 @@ public class BytecodeGenMethod implements StatementVisitor {
this.classFiles = classFiles; this.classFiles = classFiles;
this.sf = sf; this.sf = sf;
this.path = path; this.path = path;
this.lamCounter = -1;
this.constructorPos = constructorPos; this.constructorPos = constructorPos;
if(block != null) if(block != null)
this.blockFieldInit = block; this.blockFieldInit = block;
@@ -123,6 +112,7 @@ public class BytecodeGenMethod implements StatementVisitor {
this.className = className; this.className = className;
this.superClass = superClass; this.superClass = superClass;
this.resultSet = resultSet; this.resultSet = resultSet;
this.resolver = new Resolver(resultSet);
this.m = m; this.m = m;
this.mv = mv; this.mv = mv;
this.paramsAndLocals = paramsAndLocals; this.paramsAndLocals = paramsAndLocals;
@@ -133,17 +123,19 @@ public class BytecodeGenMethod implements StatementVisitor {
this.classFiles = classFiles; this.classFiles = classFiles;
this.sf = sf; this.sf = sf;
this.path = path; this.path = path;
this.lamCounter = -1;
if (!isInterface) if (!isInterface)
this.m.block.accept(this); this.m.block.accept(this);
} }
public BytecodeGenMethod(LambdaExpression lambdaExpression, ArrayList<String> usedVars, ResultSet resultSet, MethodVisitor mv, public BytecodeGenMethod(String className, ClassWriter cw, LambdaExpression lambdaExpression, ArrayList<String> usedVars, ResultSet resultSet, MethodVisitor mv,
int indexOfFirstParamLam, boolean isInterface, HashMap<String, byte[]> classFiles, String path, int lamCounter, SourceFile sf,HashMap<String, String> genericsAndBoundsMethod, int indexOfFirstParamLam, boolean isInterface, HashMap<String, byte[]> classFiles, String path, int lamCounter, SourceFile sf,HashMap<String, String> genericsAndBoundsMethod,
HashMap<String, String> genericsAndBounds) { HashMap<String, String> genericsAndBounds) {
this.className = className;
this.cw = cw;
this.resultSet = resultSet; this.resultSet = resultSet;
this.resolver = new Resolver(resultSet);
this.mv = mv; this.mv = mv;
this.isInterface = isInterface; this.isInterface = isInterface;
this.classFiles = classFiles; this.classFiles = classFiles;
@@ -169,21 +161,22 @@ public class BytecodeGenMethod implements StatementVisitor {
lambdaExpression.methodBody.accept(this); lambdaExpression.methodBody.accept(this);
} }
public Resolver getResolver() {
return resolver;
}
public void isBinary(boolean isBinary) { public void isBinary(boolean isBinary) {
this.isBinaryExp =isBinary; this.isBinaryExp =isBinary;
} }
public String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
}
@Override @Override
public void visit(Block block) { public void visit(Block block) {
for (Statement stmt : block.getStatements()) { for (Statement stmt : block.getStatements()) {
stmt.accept(this); stmt.accept(this);
if(stmt instanceof MethodCall) { if(stmt instanceof MethodCall) {
String ret = getResolvedType(((MethodCall) stmt).getType()); String ret = resolver.getResolvedType(((MethodCall) stmt).getType());
if(!ret.equals("void")) if(!ret.equals(CONSTANTS.VOID))
mv.visitInsn(Opcodes.POP); mv.visitInsn(Opcodes.POP);
} }
} }
@@ -217,7 +210,7 @@ public class BytecodeGenMethod implements StatementVisitor {
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name)); mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(localVar.name));
if (isBinaryExp) { if (isBinaryExp) {
doUnboxing(getResolvedType(localVar.getType())); doUnboxing(resolver.getResolvedType(localVar.getType()));
} }
} }
@@ -245,16 +238,20 @@ public class BytecodeGenMethod implements StatementVisitor {
} else { } else {
assign.rightSide.accept(this); assign.rightSide.accept(this);
} }
statement = new AssignStmt(assign.rightSide);
isBinaryExp = statement.isExprBinary();
if (isBinaryExp) { if (isBinaryExp) {
BinaryExpr binary = (BinaryExpr) assign.rightSide; BinaryExpr binary = (BinaryExpr) assign.rightSide;
String binaryType = getResolvedType(binary.getType()); String binaryType = resolver.getResolvedType(binary.getType());
doBoxing(binaryType); doBoxing(binaryType);
isBinaryExp = false; isBinaryExp = false;
} }
System.out.println("ASSIGN TYPE R: " + getResolvedType(assign.rightSide.getType())); System.out.println("ASSIGN TYPE R: " + resolver.getResolvedType(assign.rightSide.getType()));
String typeOfRightSide = getResolvedType(assign.rightSide.getType()); String typeOfRightSide = resolver.getResolvedType(assign.rightSide.getType());
if(typeOfRightSide.contains("<")) { if(typeOfRightSide.contains(CONSTANTS.ANGLEBRACKET)) {
mv.visitTypeInsn(Opcodes.CHECKCAST, typeOfRightSide.substring(0, typeOfRightSide.indexOf('<'))); mv.visitTypeInsn(Opcodes.CHECKCAST, typeOfRightSide.substring(0, typeOfRightSide.indexOf('<')));
} }
assign.lefSide.accept(this); assign.lefSide.accept(this);
@@ -265,11 +262,11 @@ public class BytecodeGenMethod implements StatementVisitor {
@Override @Override
public void visit(BinaryExpr binary) { public void visit(BinaryExpr binary) {
isParentBinary = true; isParentBinary = true;
String lexpType = getResolvedType(binary.lexpr.getType()); String lexpType = resolver.getResolvedType(binary.lexpr.getType());
String rexpType = getResolvedType(binary.rexpr.getType()); String rexpType = resolver.getResolvedType(binary.rexpr.getType());
String largerType = getLargerType(lexpType, rexpType); String largerType = getLargerType(lexpType, rexpType);
String typeOfBinary = getResolvedType(binary.getType()); String typeOfBinary = resolver.getResolvedType(binary.getType());
if (typeOfBinary.equals(Type.getInternalName(String.class))) { if (typeOfBinary.equals(Type.getInternalName(String.class))) {
mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(StringBuilder.class)); mv.visitTypeInsn(Opcodes.NEW, Type.getInternalName(StringBuilder.class));
@@ -288,6 +285,11 @@ public class BytecodeGenMethod implements StatementVisitor {
binary.lexpr.accept(this); binary.lexpr.accept(this);
if(lexpType.equals(Type.getInternalName(String.class))) {
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append",
"(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
}
if (!lexpType.equals(rexpType) && !lexpType.equals(largerType)) if (!lexpType.equals(rexpType) && !lexpType.equals(largerType))
doCast(lexpType, largerType); doCast(lexpType, largerType);
@@ -295,7 +297,10 @@ public class BytecodeGenMethod implements StatementVisitor {
needDUP = true; needDUP = true;
binary.rexpr.accept(this); binary.rexpr.accept(this);
if(rexpType.equals(Type.getInternalName(String.class))) {
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append",
"(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
}
isParentBinary = false; isParentBinary = false;
if (!lexpType.equals(rexpType) && !rexpType.equals(largerType)) if (!lexpType.equals(rexpType) && !rexpType.equals(largerType))
@@ -359,11 +364,11 @@ public class BytecodeGenMethod implements StatementVisitor {
private void doCast(String sourceType, String dest) { private void doCast(String sourceType, String dest) {
switch (dest) { switch (dest) {
case "java/lang/Long": case CONSTANTS.REFTYPE_LONG:
mv.visitInsn(Opcodes.I2L); mv.visitInsn(Opcodes.I2L);
break; break;
case "java/lang/Double": case CONSTANTS.REFTYPE_DOUBLE:
if (sourceType.equals(Type.getInternalName(Long.class))) { if (sourceType.equals(Type.getInternalName(Long.class))) {
mv.visitInsn(Opcodes.L2D); mv.visitInsn(Opcodes.L2D);
} else if (sourceType.equals(Type.getInternalName(Float.class))) { } else if (sourceType.equals(Type.getInternalName(Float.class))) {
@@ -373,15 +378,15 @@ public class BytecodeGenMethod implements StatementVisitor {
} }
break; break;
case "java/lang/Float": case CONSTANTS.REFTYPE_FLOAT:
if (sourceType.equals(Type.getInternalName(Long.class))) { if (sourceType.equals(Type.getInternalName(Long.class))) {
mv.visitInsn(Opcodes.L2F); mv.visitInsn(Opcodes.L2F);
} else { } else {
mv.visitInsn(Opcodes.I2F); mv.visitInsn(Opcodes.I2F);
} }
break; break;
// braucht man eigentlic nicht, muss getestet werden // braucht man eigentlich nicht, muss getestet werden
case "java/lang/String": case CONSTANTS.REFTYPE_STRING:
if (sourceType.equals(Type.getInternalName(Double.class))) { if (sourceType.equals(Type.getInternalName(Double.class))) {
mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf", mv.visitMethodInsn(Opcodes.INVOKESTATIC, Type.getInternalName(String.class), "valueOf",
"(D)Ljava/lang/String;", false); "(D)Ljava/lang/String;", false);
@@ -404,15 +409,15 @@ public class BytecodeGenMethod implements StatementVisitor {
private void doVisitRelOpInsn(Operator op, String typeOfBinary, Label branchLabel, Label endLabel) { private void doVisitRelOpInsn(Operator op, String typeOfBinary, Label branchLabel, Label endLabel) {
System.out.println("TypeOfBinary: " + typeOfBinary); System.out.println("TypeOfBinary: " + typeOfBinary);
switch (typeOfBinary) { switch (typeOfBinary) {
case "java/lang/Long": case CONSTANTS.REFTYPE_LONG:
mv.visitInsn(Opcodes.LCMP); mv.visitInsn(Opcodes.LCMP);
doVisitIfInRelOp(op, branchLabel, endLabel); doVisitIfInRelOp(op, branchLabel, endLabel);
break; break;
case "java/lang/Double": case CONSTANTS.REFTYPE_DOUBLE:
mv.visitInsn(Opcodes.DCMPG); mv.visitInsn(Opcodes.DCMPG);
doVisitIfInRelOp(op, branchLabel, endLabel); doVisitIfInRelOp(op, branchLabel, endLabel);
break; break;
case "java/lang/Float": case CONSTANTS.REFTYPE_FLOAT:
mv.visitInsn(Opcodes.FCMPG); mv.visitInsn(Opcodes.FCMPG);
doVisitIfInRelOp(op, branchLabel, endLabel); doVisitIfInRelOp(op, branchLabel, endLabel);
break; break;
@@ -476,13 +481,13 @@ public class BytecodeGenMethod implements StatementVisitor {
private void doVisitModOpInsn(String typeOfBinary) { private void doVisitModOpInsn(String typeOfBinary) {
switch (typeOfBinary) { switch (typeOfBinary) {
case "java/lang/Long": case CONSTANTS.REFTYPE_LONG:
mv.visitInsn(Opcodes.LREM); mv.visitInsn(Opcodes.LREM);
break; break;
case "java/lang/Double": case CONSTANTS.REFTYPE_DOUBLE:
mv.visitInsn(Opcodes.DREM); mv.visitInsn(Opcodes.DREM);
break; break;
case "java/lang/Float": case CONSTANTS.REFTYPE_FLOAT:
mv.visitInsn(Opcodes.FREM); mv.visitInsn(Opcodes.FREM);
break; break;
default: default:
@@ -493,13 +498,13 @@ public class BytecodeGenMethod implements StatementVisitor {
private void doVisitDivOpInsn(String typeOfBinary) { private void doVisitDivOpInsn(String typeOfBinary) {
switch (typeOfBinary) { switch (typeOfBinary) {
case "java/lang/Long": case CONSTANTS.REFTYPE_LONG:
mv.visitInsn(Opcodes.LDIV); mv.visitInsn(Opcodes.LDIV);
break; break;
case "java/lang/Double": case CONSTANTS.REFTYPE_DOUBLE:
mv.visitInsn(Opcodes.DDIV); mv.visitInsn(Opcodes.DDIV);
break; break;
case "java/lang/Float": case CONSTANTS.REFTYPE_FLOAT:
mv.visitInsn(Opcodes.FDIV); mv.visitInsn(Opcodes.FDIV);
break; break;
default: default:
@@ -510,13 +515,13 @@ public class BytecodeGenMethod implements StatementVisitor {
private void doVisitMulOpInsn(String typeOfBinary) { private void doVisitMulOpInsn(String typeOfBinary) {
switch (typeOfBinary) { switch (typeOfBinary) {
case "java/lang/Long": case CONSTANTS.REFTYPE_LONG:
mv.visitInsn(Opcodes.LMUL); mv.visitInsn(Opcodes.LMUL);
break; break;
case "java/lang/Double": case CONSTANTS.REFTYPE_DOUBLE:
mv.visitInsn(Opcodes.DMUL); mv.visitInsn(Opcodes.DMUL);
break; break;
case "java/lang/Float": case CONSTANTS.REFTYPE_FLOAT:
mv.visitInsn(Opcodes.FMUL); mv.visitInsn(Opcodes.FMUL);
break; break;
default: default:
@@ -527,13 +532,13 @@ public class BytecodeGenMethod implements StatementVisitor {
private void doVisitSubOpInsn(String typeOfBinary) { private void doVisitSubOpInsn(String typeOfBinary) {
switch (typeOfBinary) { switch (typeOfBinary) {
case "java/lang/Long": case CONSTANTS.REFTYPE_LONG:
mv.visitInsn(Opcodes.LSUB); mv.visitInsn(Opcodes.LSUB);
break; break;
case "java/lang/Double": case CONSTANTS.REFTYPE_DOUBLE:
mv.visitInsn(Opcodes.DSUB); mv.visitInsn(Opcodes.DSUB);
break; break;
case "java/lang/Float": case CONSTANTS.REFTYPE_FLOAT:
mv.visitInsn(Opcodes.FSUB); mv.visitInsn(Opcodes.FSUB);
break; break;
default: default:
@@ -545,24 +550,28 @@ public class BytecodeGenMethod implements StatementVisitor {
private void doVisitAddOpInsn(String typeOfBinary) { private void doVisitAddOpInsn(String typeOfBinary) {
switch (typeOfBinary) { switch (typeOfBinary) {
case "java/lang/Byte": case CONSTANTS.REFTYPE_BYTE:
mv.visitInsn(Opcodes.IADD); mv.visitInsn(Opcodes.IADD);
break; break;
case "java/lang/Short": case CONSTANTS.REFTYPE_SHORT:
mv.visitInsn(Opcodes.IADD); mv.visitInsn(Opcodes.IADD);
break; break;
case "java/lang/Integer": case CONSTANTS.REFTYPE_INTEGER:
mv.visitInsn(Opcodes.IADD); mv.visitInsn(Opcodes.IADD);
break; break;
case "java/lang/Long": case CONSTANTS.REFTYPE_LONG:
mv.visitInsn(Opcodes.LADD); mv.visitInsn(Opcodes.LADD);
break; break;
case "java/lang/Double": case CONSTANTS.REFTYPE_DOUBLE:
mv.visitInsn(Opcodes.DADD); mv.visitInsn(Opcodes.DADD);
break; break;
case "java/lang/Float": case CONSTANTS.REFTYPE_FLOAT:
mv.visitInsn(Opcodes.FADD); mv.visitInsn(Opcodes.FADD);
break; break;
case CONSTANTS.REFTYPE_STRING:
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", CONSTANTS.TO_STRING, "()Ljava/lang/String;",
false);
break;
default: default:
break; break;
} }
@@ -572,16 +581,9 @@ public class BytecodeGenMethod implements StatementVisitor {
public void visit(LambdaExpression lambdaExpression) { public void visit(LambdaExpression lambdaExpression) {
this.lamCounter++; this.lamCounter++;
String typeErasure = "("; String typeErasure = createDescriptorWithTypeErasure(lambdaExpression);
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
while (itr.hasNext()) {
itr.next();
typeErasure += "L" + Type.getInternalName(Object.class) + ";";
}
typeErasure += ")L" + Type.getInternalName(Object.class) + ";"; ByteCodeForFunNGenerator.generateBCForFunN(lambdaExpression, typeErasure,path);
generateBCForFunN(lambdaExpression, typeErasure);
Lambda lam = new Lambda(lambdaExpression); Lambda lam = new Lambda(lambdaExpression);
@@ -594,7 +596,7 @@ public class BytecodeGenMethod implements StatementVisitor {
Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory", Handle bootstrap = new Handle(Opcodes.H_INVOKESTATIC, "java/lang/invoke/LambdaMetafactory", "metafactory",
mt.toMethodDescriptorString(), false); mt.toMethodDescriptorString(), false);
String methodName = "lambda$new$" + this.lamCounter; String desugaredMethodName = CONSTANTS.DESUGAREDMETHODNAME + this.lamCounter;
// Für die Parameter-Typen und Return-Typ braucht man die Bounds (für die // Für die Parameter-Typen und Return-Typ braucht man die Bounds (für die
// Typlöschung) // Typlöschung)
@@ -605,37 +607,22 @@ public class BytecodeGenMethod implements StatementVisitor {
// real Type // real Type
Type arg3 = Type.getMethodType(lamDesc); Type arg3 = Type.getMethodType(lamDesc);
int staticOrSpecial = 0; int staticOrSpecial, staticOrInstance = 0, indexOfFirstParamLam = 0;
int staticOrInstance = 0;
int indexOfFirstParamLam = 0;
this.kindOfLambda = new KindOfLambda(lambdaExpression); this.kindOfLambda = new KindOfLambda(lambdaExpression);
if (kindOfLambda.isInstanceCapturingLambda()) { if (kindOfLambda.isInstanceCapturingLambda()) {
// if(!kindOfLambda.getArgumentList().contains(BytecodeGen.THISTYPE))
// kindOfLambda.getArgumentList().add(0, BytecodeGen.THISTYPE);
mv.visitVarInsn(Opcodes.ALOAD, 0); mv.visitVarInsn(Opcodes.ALOAD, 0);
for(String v : kindOfLambda.getUsedVars()) { loadUsedVarsInLambda();
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(v));
}
staticOrSpecial = Opcodes.H_INVOKESPECIAL; staticOrSpecial = Opcodes.H_INVOKESPECIAL;
indexOfFirstParamLam = 1; indexOfFirstParamLam = 1;
} else { } else {
staticOrSpecial = Opcodes.H_INVOKESTATIC; staticOrSpecial = Opcodes.H_INVOKESTATIC;
staticOrInstance = Opcodes.ACC_STATIC; staticOrInstance = Opcodes.ACC_STATIC;
} }
String newDesc = "("; String newDesc = addUsedVarsToDesugaredMethodDescriptor(lamDesc);
int pos = 0;
if(kindOfLambda.isHasThis()) {
pos = 1;
}
for(int i=pos;i<kindOfLambda.getArgumentList().size();i++) {
String t = "L" + getResolvedType(kindOfLambda.getArgumentList().get(i)) + ";";
newDesc += t;
}
newDesc += lamDesc.substring(1);
// first check if capturing lambda then invokestatic or invokespecial // first check if capturing lambda then invokestatic or invokespecial
Handle arg2 = new Handle(staticOrSpecial, this.className, methodName, newDesc, false); Handle arg2 = new Handle(staticOrSpecial, this.className, desugaredMethodName, newDesc, false);
// Descriptor of functional interface methode // Descriptor of functional interface methode
SamMethod samMethod = new SamMethod(kindOfLambda.getArgumentList(), lambdaExpression.getType()); SamMethod samMethod = new SamMethod(kindOfLambda.getArgumentList(), lambdaExpression.getType());
// Desc: (this/nothing)TargetType // Desc: (this/nothing)TargetType
@@ -643,11 +630,11 @@ public class BytecodeGenMethod implements StatementVisitor {
mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap, arg1, arg2, arg3); mv.visitInvokeDynamicInsn("apply", fiMethodDesc, bootstrap, arg1, arg2, arg3);
if(constructorPos<2) { if(constructorPos<2) {
MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE + staticOrInstance + Opcodes.ACC_SYNTHETIC, MethodVisitor mvLambdaBody = cw.visitMethod(Opcodes.ACC_PRIVATE + staticOrInstance + Opcodes.ACC_SYNTHETIC,
methodName, newDesc, null, null); desugaredMethodName, newDesc, null, null);
ArrayList<String> usedVars = kindOfLambda.getUsedVars(); ArrayList<String> usedVars = kindOfLambda.getUsedVars();
new BytecodeGenMethod(lambdaExpression, usedVars,this.resultSet, mvLambdaBody, indexOfFirstParamLam, isInterface, new BytecodeGenMethod(className, cw,lambdaExpression, usedVars,this.resultSet, mvLambdaBody, indexOfFirstParamLam, isInterface,
classFiles,this.path, lamCounter, sf, genericsAndBoundsMethod, classFiles,this.path, lamCounter, sf, genericsAndBoundsMethod,
genericsAndBounds); genericsAndBounds);
@@ -659,48 +646,40 @@ public class BytecodeGenMethod implements StatementVisitor {
// generateBCForFunN(lambdaExpression, typeErasure); // generateBCForFunN(lambdaExpression, typeErasure);
} }
private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) { private String addUsedVarsToDesugaredMethodDescriptor(String lamDesc) {
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); String newDesc = "(";
int pos = 0;
if(kindOfLambda.isThisUsed()) {
pos = 1;
}
SignatureWriter methSig = new SignatureWriter(); for(int i=pos;i<kindOfLambda.getArgumentList().size();i++) {
String t = "L" + resolver.getResolvedType(kindOfLambda.getArgumentList().get(i)) + ";";
newDesc += t;
}
newDesc += lamDesc.substring(1);
return newDesc;
}
int numberOfParams = 0; private void loadUsedVarsInLambda() {
SignatureVisitor paramVisitor = methSig.visitParameterType(); for(String v : kindOfLambda.getUsedVars()) {
mv.visitVarInsn(Opcodes.ALOAD, paramsAndLocals.get(v));
}
}
private String createDescriptorWithTypeErasure(LambdaExpression lambdaExpression) {
String typeErasure = "(";
Iterator<FormalParameter> itr = lambdaExpression.params.iterator(); Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
while (itr.hasNext()) { while (itr.hasNext()) {
numberOfParams++;
// getBounds
paramVisitor.visitTypeVariable("T" + numberOfParams);
itr.next(); itr.next();
} typeErasure += "L" + Type.getInternalName(Object.class) + ";";
methSig.visitReturnType().visitTypeVariable("R");
// ")"+lam.getReturn.getBounds
Signature sig = new Signature(lambdaExpression, numberOfParams);
String name = "Fun" + numberOfParams + "$$";
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
Type.getInternalName(Object.class), null);
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc,
methSig.toString(), null);
mvApply.visitEnd();
writeClassFile(classWriter.toByteArray(), name);
} }
public void writeClassFile(byte[] bytecode, String name) { typeErasure += ")L" + Type.getInternalName(Object.class) + ";";
FileOutputStream output; return typeErasure;
try {
System.out.println("generating " + name + ".class file...");
output = new FileOutputStream(
new File(path + name + ".class"));
output.write(bytecode);
output.close();
System.out.println(name + ".class file generated");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} }
}
@Override @Override
public void visit(CastExpr castExpr) { public void visit(CastExpr castExpr) {
@@ -727,11 +706,11 @@ public class BytecodeGenMethod implements StatementVisitor {
fieldVar.receiver.accept(this); fieldVar.receiver.accept(this);
// test (if) // test (if)
if (!fieldVar.receiver.getClass().equals(StaticClassName.class)) { if (!fieldVar.receiver.getClass().equals(StaticClassName.class)) {
mv.visitFieldInsn(Opcodes.GETFIELD, getResolvedType(fieldVar.receiver.getType()), fieldName, fieldDesc); mv.visitFieldInsn(Opcodes.GETFIELD, resolver.getResolvedType(fieldVar.receiver.getType()), fieldName, fieldDesc);
} }
if (isBinaryExp) { if (isBinaryExp) {
doUnboxing(getResolvedType(fieldVar.getType())); doUnboxing(resolver.getResolvedType(fieldVar.getType()));
} }
// mv.visitFieldInsn(Opcodes.GETSTATIC, // mv.visitFieldInsn(Opcodes.GETSTATIC,
// fieldVar.receiver.getType().toString().replace(".", "/"), // fieldVar.receiver.getType().toString().replace(".", "/"),
@@ -750,7 +729,7 @@ public class BytecodeGenMethod implements StatementVisitor {
isBinaryExp = statement.isExprBinary(); isBinaryExp = statement.isExprBinary();
ifStmt.expr.accept(this); ifStmt.expr.accept(this);
if(!(ifStmt.expr instanceof BinaryExpr)) { if(!(ifStmt.expr instanceof BinaryExpr)) {
doUnboxing(getResolvedType(ifStmt.expr.getType())); doUnboxing(resolver.getResolvedType(ifStmt.expr.getType()));
Label branchLabel = new Label(); Label branchLabel = new Label();
Label endLabel = new Label(); Label endLabel = new Label();
mv.visitJumpInsn(Opcodes.IFEQ, branchLabel); mv.visitJumpInsn(Opcodes.IFEQ, branchLabel);
@@ -768,11 +747,15 @@ public class BytecodeGenMethod implements StatementVisitor {
public void visit(MethodCall methodCall) { public void visit(MethodCall methodCall) {
boolean parentBinary = isParentBinary; boolean parentBinary = isParentBinary;
System.out.println("In MethodCall = " + methodCall.name); System.out.println("In MethodCall = " + methodCall.name);
String receiverName = getResolvedType(methodCall.receiver.getType()); String receiverName = resolver.getResolvedType(methodCall.receiver.getType());
System.out.println("Methods of " + receiverName + " "); System.out.println("Methods of " + receiverName + " ");
java.lang.reflect.Method methodRefl = null; java.lang.reflect.Method methodRefl = null;
String clazz = receiverName.replace("/", "."); String clazz = receiverName.replace("/", ".");
// if(!receiverName.equals(className)) {
String mDesc = "";
MethodCallHelper helper = new MethodCallHelper(methodCall, sf, resultSet, path);
ClassLoader cLoader = ClassLoader.getSystemClassLoader(); ClassLoader cLoader = ClassLoader.getSystemClassLoader();
// This will be used if the class is not standard class (not in API) // This will be used if the class is not standard class (not in API)
ClassLoader cLoader2; ClassLoader cLoader2;
@@ -780,64 +763,53 @@ public class BytecodeGenMethod implements StatementVisitor {
String methCallType = resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor()); String methCallType = resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor());
String[] typesOfParams = getTypes(methodCall.arglist.getArguments()); String[] typesOfParams = getTypes(methodCall.arglist.getArguments());
try { try {
if(receiverName.contains("<")) { clazz = getRawClassName(receiverName, clazz);
clazz = clazz.substring(0, receiverName.indexOf("<"));
}
java.lang.reflect.Method[] methods = cLoader.loadClass(clazz).getMethods(); java.lang.reflect.Method[] methods = cLoader.loadClass(clazz).getMethods();
System.out.println("Methods of " + receiverName + " "); System.out.println("Methods of " + receiverName + " ");
methodRefl = getMethod(methodCall.name, methodCall.arglist.getArguments().size(), methods); methodRefl = getMethod(methodCall.name, methodCall.arglist.getArguments().size(), methods);
} catch (Exception e) { } catch (Exception e) {
// try {
// cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)});
// java.lang.reflect.Method[] methods = cLoader2.loadClass(clazz).getMethods();
// System.out.println("Methods of " + receiverName + " ");
// for(int i = 0; i<methods.length; i++) {
// System.out.println(methods[i]);
// }
// methodRefl = getMethod(methodCall.name,methodCall.arglist.getArguments().size(),methCallType, typesOfParams,methods);
// }catch (Exception e2) {
String superClass = ""; String superClass = "";
// TODO: Test SubMatrix.jav
while(true) { while(true) {
for(ClassOrInterface cl : sf.getClasses()) { try {
if(receiverName.equals(cl.getClassName().toString())) { superClass = helper.getSuperClass(receiverName);
superClass = cl.getSuperClass().getName().toString();
break;
}
}
System.out.println(superClass);
if(superClass.equals(""))
break;
try { try {
String superClazz = superClass.replace("/", "."); String superClazz = superClass.replace("/", ".");
if(superClass.contains("<")) { superClazz = getRawClassName(superClass, superClazz);
superClazz = superClazz.substring(0, superClass.indexOf("<"));
}
java.lang.reflect.Method[] methods = cLoader.loadClass(superClazz).getMethods(); java.lang.reflect.Method[] methods = cLoader.loadClass(superClazz).getMethods();
System.out.println("Methods of " + superClass + " "); System.out.println("Methods of " + superClass + " ");
for(java.lang.reflect.Method m : methods) { methodRefl = getMethod(methodCall.name, methodCall.arglist.getArguments().size(), methods);
if(methodCall.name.equals(m.getName())) {
methodRefl = m;
break;
}
}
break; break;
} catch (Exception e3) { } catch (Exception e3) {
receiverName = superClass; receiverName = superClass;
continue; continue;
} }
} catch (NotInCurrentPackageException e2) {
break;
}
} }
// }
} }
if(methodRefl == null) { if(methodRefl == null) {
boolean toCreate = !receiverName.equals(className) && helper.isInCurrPkg(clazz);
if(toCreate) {
try {
mDesc = helper.getDesc(clazz);
} catch (NotInCurrentPackageException | NotFoundException e) {
e.printStackTrace();
}
} else if(!helper.isInCurrPkg(clazz)){
if(clazz.contains(CONSTANTS.$$)) {
mDesc = helper.getDescriptorOfApplyMethod(methCallType);
helper.generateBCForFunN(mDesc);
// mDesc = helper.generateBCForFunN(methCallType,typesOfParams);
}else {
try { try {
cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)}); cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)});
java.lang.reflect.Method[] methods = cLoader2.loadClass(clazz).getMethods(); java.lang.reflect.Method[] methods = cLoader2.loadClass(clazz).getMethods();
@@ -848,32 +820,70 @@ public class BytecodeGenMethod implements StatementVisitor {
methodRefl = getMethod(methodCall.name,methodCall.arglist.getArguments().size(),methCallType, typesOfParams,methods); methodRefl = getMethod(methodCall.name,methodCall.arglist.getArguments().size(),methCallType, typesOfParams,methods);
} }
catch (Exception e2) { catch (Exception e2) {
System.out.println(""); e2.printStackTrace();
//do nothing
} }
} }
// } }
}
methodCall.receiver.accept(this); methodCall.receiver.accept(this);
System.out.println("Methodcall type : " + resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor())); System.out.println("Methodcall type : " + resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor()));
String mDesc = "";
List<Boolean> argListMethCall = new LinkedList<>(); List<Boolean> argListMethCall = new LinkedList<>();
String receiverRefl=""; String receiverRefl="";
if(methodRefl == null) { if(methodRefl == null && receiverName.equals(className)) {
MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(), MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(),
receiverName, genericsAndBoundsMethod, genericsAndBounds); receiverName, genericsAndBoundsMethod, genericsAndBounds);
mDesc = method.accept(new DescriptorToString(resultSet)); mDesc = method.accept(new DescriptorToString(resultSet));
methodCall.arglist.accept(this); methodCall.arglist.accept(this);
} else { } else if(methodRefl != null) {
System.out.println(methodCall.name + " -> Refl != null"); System.out.println(methodCall.name + " -> Refl != null");
receiverRefl = methodRefl.getAnnotatedReceiverType().getType().toString(); receiverRefl = methodRefl.getAnnotatedReceiverType().getType().toString();
getBoolListOfType(methodRefl, argListMethCall);
System.out.println("Receiver = " + methodRefl.getAnnotatedReceiverType().getType().toString());
mDesc = getMethodDesc(methodRefl);
visitArgumentListOfMethodCallFromStandardAPI(methodCall, argListMethCall);
} else {
methodCall.arglist.accept(this);
}
System.out.println("Methodcall ("+ methodCall.name +") Desc : " + mDesc);
// methodCall.arglist.accept(this);
visitInvokeInsn(methodCall, receiverName, methodRefl, clazz, mDesc, receiverRefl);
if(methodRefl != null && !methodRefl.getReturnType().isPrimitive()) {
if(methodRefl.getReturnType().equals(Object.class)) {
helper.createCheckCast(methodCall,mv);
}
/*if(isBinaryExp) {
doUnboxing(resolver.getResolvedType(methodCall.getType()));
}*/
if(parentBinary || isBinaryExp) {
doUnboxing(resolver.getResolvedType(methodCall.getType()));
}
} else if(receiverName.contains(CONSTANTS.$$) && !methCallType.equals(Type.getInternalName(Object.class))) {
helper.createCheckCast(methodCall,mv);
}
System.out.println("ISParent Binary = "+isParentBinary +" -> " + parentBinary);
if(methodRefl == null && (parentBinary || !isReturnStmt)) {
if(isBinaryExp)
doUnboxing(resolver.getResolvedType(methodCall.getType()));
}
}
private void getBoolListOfType(java.lang.reflect.Method methodRefl, List<Boolean> argListMethCall) {
for(Parameter p:methodRefl.getParameters()) { for(Parameter p:methodRefl.getParameters()) {
System.out.println(p.getName() + " und is Primitive = " + p.getType().isPrimitive()); System.out.println(p.getName() + " und is Primitive = " + p.getType().isPrimitive());
argListMethCall.add(p.getType().isPrimitive()); argListMethCall.add(p.getType().isPrimitive());
} }
System.out.println("Receiver = " + methodRefl.getAnnotatedReceiverType().getType().toString()); }
mDesc = getMethodDesc(methodRefl);
private void visitArgumentListOfMethodCallFromStandardAPI(MethodCall methodCall, List<Boolean> argListMethCall) {
for (Expression al : methodCall.arglist.getArguments()) { for (Expression al : methodCall.arglist.getArguments()) {
statement = new ArgumentExpr(al); statement = new ArgumentExpr(al);
ArgumentVisitor argV = new ArgumentVisitor(argListMethCall,this); ArgumentVisitor argV = new ArgumentVisitor(argListMethCall,this);
@@ -882,45 +892,29 @@ public class BytecodeGenMethod implements StatementVisitor {
} }
} }
System.out.println("Methodcall ("+ methodCall.name +") Desc : " + mDesc); private void visitInvokeInsn(MethodCall methodCall, String receiverName, java.lang.reflect.Method methodRefl, String clazz, String mDesc, String receiverRefl) {
// methodCall.arglist.accept(this);
// is methodCall.receiver functional Interface)? // is methodCall.receiver functional Interface)?
if (varsFunInterface.contains(methodCall.receiver.getType()) || (methodRefl!= null && receiverRefl.contains("interface"))) { if (varsFunInterface.contains(methodCall.receiver.getType()) || (methodRefl!= null && receiverRefl.contains("interface")) ||
receiverName.contains(CONSTANTS.$$)) {
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, clazz.replace(".", "/"), methodCall.name, mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, clazz.replace(".", "/"), methodCall.name,
mDesc, true); mDesc, true);
} else { } else {
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, clazz.replace(".", "/"), methodCall.name, mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, clazz.replace(".", "/"), methodCall.name,
mDesc, isInterface); mDesc, isInterface);
} }
if(methodRefl != null && !methodRefl.getReturnType().isPrimitive()) {
if(methodRefl.getReturnType().equals(Object.class)) {
String checkCast = getResolvedType(methodCall.getType());
if(!checkCast.contains("TPH ")) {
int pos = checkCast.length();
if(checkCast.contains("<"))
pos = checkCast.indexOf("<");
mv.visitTypeInsn(Opcodes.CHECKCAST,checkCast.substring(0,pos));
}
}
if(isBinaryExp)
doUnboxing(getResolvedType(methodCall.getType()));
}
System.out.println("ISParent Binary = "+isParentBinary +" -> " + parentBinary);
if(methodRefl == null && (parentBinary || !isReturnStmt)) {
if(isBinaryExp)
doUnboxing(getResolvedType(methodCall.getType()));
} }
private String getRawClassName(String receiverName, String clazz) {
if (receiverName.contains(CONSTANTS.ANGLEBRACKET)) {
clazz = clazz.substring(0, receiverName.indexOf(CONSTANTS.ANGLEBRACKET));
}
return clazz;
} }
private String[] getTypes(List<Expression> arguments) { private String[] getTypes(List<Expression> arguments) {
String[] types = new String[arguments.size()]; String[] types = new String[arguments.size()];
for(int i = 0; i<arguments.size(); ++i) { for(int i = 0; i<arguments.size(); ++i) {
String t = getResolvedType(arguments.get(i).getType()); String t = resolver.getResolvedType(arguments.get(i).getType());
types[i] = t; types[i] = t;
} }
return types; return types;
@@ -1023,15 +1017,24 @@ public class BytecodeGenMethod implements StatementVisitor {
mv.visitInsn(Opcodes.DUP); mv.visitInsn(Opcodes.DUP);
// creates Descriptor // creates Descriptor
methodCall.arglist.accept(this); methodCall.arglist.accept(this);
String d = "("; String d = createDescriptorForInitMethod(methodCall);
for (Expression e : methodCall.arglist.getArguments()) {
d = d + "L" + getResolvedType(e.getType()) + ";";
}
d += ")V";
mv.visitMethodInsn(Opcodes.INVOKESPECIAL, methodCall.name.replace(".", "/"), "<init>", d, isInterface); mv.visitMethodInsn(Opcodes.INVOKESPECIAL, methodCall.name.replace(".", "/"), "<init>", d, isInterface);
} }
private String createDescriptorForInitMethod(NewClass methodCall) {
String d = "(";
for (Expression e : methodCall.arglist.getArguments()) {
String type = resolver.getResolvedType(e.getType());
if(type.contains("TPH ")){
type = Type.getInternalName(Object.class);
}
d = d + "L" + type + ";";
}
d += ")V";
return d;
}
@Override @Override
public void visit(NewArray newArray) { public void visit(NewArray newArray) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
@@ -1048,7 +1051,7 @@ public class BytecodeGenMethod implements StatementVisitor {
unaryExpr.expr.accept(this); unaryExpr.expr.accept(this);
Operation op = unaryExpr.operation; Operation op = unaryExpr.operation;
String typeOfUnary = getResolvedType(unaryExpr.getType()); String typeOfUnary = resolver.getResolvedType(unaryExpr.getType());
boolean isIncOrDec = false; boolean isIncOrDec = false;
@@ -1092,13 +1095,13 @@ public class BytecodeGenMethod implements StatementVisitor {
private void doVisitNegIns(String typeOfUnary) { private void doVisitNegIns(String typeOfUnary) {
switch (typeOfUnary) { switch (typeOfUnary) {
case "java/lang/Long": case CONSTANTS.REFTYPE_LONG:
mv.visitInsn(Opcodes.LNEG); mv.visitInsn(Opcodes.LNEG);
break; break;
case "java/lang/Double": case CONSTANTS.REFTYPE_DOUBLE:
mv.visitInsn(Opcodes.DNEG); mv.visitInsn(Opcodes.DNEG);
break; break;
case "java/lang/Float": case CONSTANTS.REFTYPE_FLOAT:
mv.visitInsn(Opcodes.FNEG); mv.visitInsn(Opcodes.FNEG);
break; break;
default: default:
@@ -1142,7 +1145,7 @@ public class BytecodeGenMethod implements StatementVisitor {
if (isBinary) { if (isBinary) {
BinaryExpr binary = (BinaryExpr) aReturn.retexpr; BinaryExpr binary = (BinaryExpr) aReturn.retexpr;
doBoxing(getResolvedType(binary.getType())); doBoxing(resolver.getResolvedType(binary.getType()));
// isBinaryExp = false; // isBinaryExp = false;
} }
@@ -1198,7 +1201,7 @@ public class BytecodeGenMethod implements StatementVisitor {
@Override @Override
public void visit(Literal literal) { public void visit(Literal literal) {
Object value = literal.value; Object value = literal.value;
String typeOfLiteral = getResolvedType(literal.getType()); String typeOfLiteral = resolver.getResolvedType(literal.getType());
System.out.println("typeOfLiteral :=> "+ typeOfLiteral); System.out.println("typeOfLiteral :=> "+ typeOfLiteral);
// Der Wert des Literals wird auf den Stack geladen und // Der Wert des Literals wird auf den Stack geladen und
// geboxt, wenn es nötig ist. // geboxt, wenn es nötig ist.
@@ -1208,31 +1211,31 @@ public class BytecodeGenMethod implements StatementVisitor {
// Unboxing: RefType -> prim // Unboxing: RefType -> prim
public void doUnboxing(String type) { public void doUnboxing(String type) {
switch (type) { switch (type) {
case "java/lang/String": // case "java/lang/String":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append", // mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, Type.getInternalName(StringBuilder.class), "append",
"(Ljava/lang/String;)Ljava/lang/StringBuilder;", false); // "(Ljava/lang/String;)Ljava/lang/StringBuilder;", false);
//
break; // break;
case "java/lang/Boolean": case "java/lang/Boolean":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
break; break;
case "java/lang/Byte": case CONSTANTS.REFTYPE_BYTE:
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CONSTANTS.REFTYPE_BYTE, "byteValue", "()B", false);
break; break;
case "java/lang/Short": case CONSTANTS.REFTYPE_SHORT:
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Short", "shortValue", "()S", false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CONSTANTS.REFTYPE_SHORT, "shortValue", "()S", false);
break; break;
case "java/lang/Integer": case "java/lang/Integer":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Integer", "intValue", "()I", false);
break; break;
case "java/lang/Long": case CONSTANTS.REFTYPE_LONG:
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Long", "longValue", "()J", false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CONSTANTS.REFTYPE_LONG, "longValue", "()J", false);
break; break;
case "java/lang/Float": case CONSTANTS.REFTYPE_FLOAT:
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Float", "floatValue", "()F", false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CONSTANTS.REFTYPE_FLOAT, "floatValue", "()F", false);
break; break;
case "java/lang/Double": case CONSTANTS.REFTYPE_DOUBLE:
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Double", "doubleValue", "()D", false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, CONSTANTS.REFTYPE_DOUBLE, "doubleValue", "()D", false);
break; break;
case "java/lang/Character": case "java/lang/Character":
break; break;
@@ -1245,17 +1248,23 @@ public class BytecodeGenMethod implements StatementVisitor {
private void loadValue(String type, Object value, boolean isOperator) { private void loadValue(String type, Object value, boolean isOperator) {
switch (type) { switch (type) {
case "java/lang/String": case CONSTANTS.REFTYPE_STRING:
mv.visitLdcInsn(String.valueOf(value)); mv.visitLdcInsn(String.valueOf(value));
break; break;
case "java/lang/Boolean": case "java/lang/Boolean":
visitBooleanLiteral((Boolean) value); visitBooleanLiteral((Boolean) value);
break; break;
case "java/lang/Byte": case CONSTANTS.REFTYPE_BYTE:
if(value instanceof Double)
visitByteLiteral(((Double) value).byteValue(), false); visitByteLiteral(((Double) value).byteValue(), false);
if(value instanceof Integer)
visitByteLiteral(((Integer) value).byteValue(), false);
break; break;
case "java/lang/Short": case CONSTANTS.REFTYPE_SHORT:
if(value instanceof Double)
visitShortLiteral(((Double) value).shortValue(), false); visitShortLiteral(((Double) value).shortValue(), false);
if(value instanceof Integer)
visitShortLiteral(((Integer) value).shortValue(), false);
break; break;
case "java/lang/Integer": case "java/lang/Integer":
// zweite Argument isLong // zweite Argument isLong
@@ -1265,13 +1274,19 @@ public class BytecodeGenMethod implements StatementVisitor {
if(value instanceof Integer) if(value instanceof Integer)
visitIntegerLiteral(((Integer) value).intValue(), false); visitIntegerLiteral(((Integer) value).intValue(), false);
break; break;
case "java/lang/Long": case CONSTANTS.REFTYPE_LONG:
if(value instanceof Double)
visitLongLiteral(((Double) value).longValue(), true);
if(value instanceof Integer)
visitLongLiteral(((Integer) value).longValue(), true); visitLongLiteral(((Integer) value).longValue(), true);
break; break;
case "java/lang/Float": case CONSTANTS.REFTYPE_FLOAT:
if(value instanceof Double)
visitFloatLiteral(((Double) value).floatValue()); visitFloatLiteral(((Double) value).floatValue());
if(value instanceof Integer)
visitFloatLiteral(((Integer) value).floatValue());
break; break;
case "java/lang/Double": case CONSTANTS.REFTYPE_DOUBLE:
if(value instanceof Double) if(value instanceof Double)
visitDoubleLiteral((Double) value); visitDoubleLiteral((Double) value);
if(value instanceof Integer) if(value instanceof Integer)
@@ -1287,7 +1302,7 @@ public class BytecodeGenMethod implements StatementVisitor {
break; break;
} }
// Boxing // Boxing
if (!type.equals("java/lang/String") && !type.equals("java/lang/Boolean")) { if (!type.equals(CONSTANTS.REFTYPE_STRING) && !type.equals("java/lang/Boolean")) {
if (!this.isBinaryExp && !isOperator) if (!this.isBinaryExp && !isOperator)
doBoxing(type); doBoxing(type);
} }
@@ -1297,30 +1312,30 @@ public class BytecodeGenMethod implements StatementVisitor {
// Boxing: prim -> RefType // Boxing: prim -> RefType
public void doBoxing(String type) { public void doBoxing(String type) {
switch (type) { switch (type) {
case "java/lang/String": // case "java/lang/String":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;", // mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;",
false); // false);
break; // break;
case "java/lang/Boolean": case "java/lang/Boolean":
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Boolean", "valueOf", "(Z)Ljava/lang/Boolean;", false);
break; break;
case "java/lang/Byte": case CONSTANTS.REFTYPE_BYTE:
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Byte", "valueOf", "(B)Ljava/lang/Byte;", false); mv.visitMethodInsn(Opcodes.INVOKESTATIC, CONSTANTS.REFTYPE_BYTE, "valueOf", "(B)Ljava/lang/Byte;", false);
break; break;
case "java/lang/Short": case CONSTANTS.REFTYPE_SHORT:
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Short", "valueOf", "(S)Ljava/lang/Short;", false); mv.visitMethodInsn(Opcodes.INVOKESTATIC, CONSTANTS.REFTYPE_SHORT, "valueOf", "(S)Ljava/lang/Short;", false);
break; break;
case "java/lang/Integer": case "java/lang/Integer":
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false); mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Integer", "valueOf", "(I)Ljava/lang/Integer;", false);
break; break;
case "java/lang/Long": case CONSTANTS.REFTYPE_LONG:
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Long", "valueOf", "(J)Ljava/lang/Long;", false); mv.visitMethodInsn(Opcodes.INVOKESTATIC, CONSTANTS.REFTYPE_LONG, "valueOf", "(J)Ljava/lang/Long;", false);
break; break;
case "java/lang/Float": case CONSTANTS.REFTYPE_FLOAT:
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Float", "valueOf", "(F)Ljava/lang/Float;", false); mv.visitMethodInsn(Opcodes.INVOKESTATIC, CONSTANTS.REFTYPE_FLOAT, "valueOf", "(F)Ljava/lang/Float;", false);
break; break;
case "java/lang/Double": case CONSTANTS.REFTYPE_DOUBLE:
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Double", "valueOf", "(D)Ljava/lang/Double;", false); mv.visitMethodInsn(Opcodes.INVOKESTATIC, CONSTANTS.REFTYPE_DOUBLE, "valueOf", "(D)Ljava/lang/Double;", false);
break; break;
case "java/lang/Character": case "java/lang/Character":
mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;", mv.visitMethodInsn(Opcodes.INVOKESTATIC, "java/lang/Character", "valueOf", "(C)Ljava/lang/Character;",
@@ -1417,7 +1432,7 @@ public class BytecodeGenMethod implements StatementVisitor {
//TODO: teste, ob man das für unary braucht //TODO: teste, ob man das für unary braucht
if (isBinaryExp) { if (isBinaryExp) {
BinaryExpr binary = (BinaryExpr) al; BinaryExpr binary = (BinaryExpr) al;
String binaryType = getResolvedType(binary.getType()); String binaryType = resolver.getResolvedType(binary.getType());
doBoxing(binaryType); doBoxing(binaryType);
} }
statement = null; statement = null;
@@ -1443,8 +1458,8 @@ public class BytecodeGenMethod implements StatementVisitor {
fDesc +=";"; fDesc +=";";
System.out.println("Receiver = " + getResolvedType(assignLeftSide.field.receiver.getType())); System.out.println("Receiver = " + resolver.getResolvedType(assignLeftSide.field.receiver.getType()));
mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()), mv.visitFieldInsn(Opcodes.PUTFIELD, resolver.getResolvedType(assignLeftSide.field.receiver.getType()),
assignLeftSide.field.fieldVarName, fDesc); assignLeftSide.field.fieldVarName, fDesc);
} }

View File

@@ -0,0 +1,19 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.Exception;
/**
* @author fayez
*
*/
public class BytecodeGeneratorError extends RuntimeException {
/**
* @param message
*/
public BytecodeGeneratorError(String message) {
super(message);
}
}

View File

@@ -0,0 +1,25 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.Exception;
/**
* @author fayez
*
*/
public class NotFoundException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* @param message
*/
public NotFoundException(String message) {
super(message);
}
}

View File

@@ -0,0 +1,26 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.Exception;
/**
* @author fayez
*
*/
public class NotInCurrentPackageException extends Exception {
/**
*
*/
private static final long serialVersionUID = 1L;
/**
* @param message
*/
public NotInCurrentPackageException(String message) {
super(message);
}
}

View File

@@ -5,21 +5,33 @@ package de.dhbwstuttgart.bytecode;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint; import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH; import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
import de.dhbwstuttgart.bytecode.utilities.MethodUtility;
import de.dhbwstuttgart.bytecode.utilities.Resolver;
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker; import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Constructor; import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.Field;
import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.statement.LocalVar; import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl; import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.GenericInsertPair; import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
import de.dhbwstuttgart.typeinference.result.ResultPair;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
/** /**
@@ -29,16 +41,18 @@ import de.dhbwstuttgart.typeinference.result.ResultSet;
public class TPHExtractor extends AbstractASTWalker { public class TPHExtractor extends AbstractASTWalker {
// Alle TPHs der Felder werden iKopf der Klasse definiert // Alle TPHs der Felder werden iKopf der Klasse definiert
// alle TPHs der Klasse: (TPH, is in Method?) // alle TPHs der Klasse: (TPH, is in Method?)
final HashMap<TypePlaceholder, Boolean> allTPHS = new HashMap<>(); public final HashMap<String, Boolean> allTPHS = new HashMap<>();
public final List<String> tphsClass = new ArrayList<>();
MethodAndTPH methodAndTph; MethodAndTPH methodAndTph;
Boolean inMethod = false; Boolean inMethod = false;
boolean inLocalOrParam = false; boolean inLocalOrParamOrReturn = false;
public final ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>(); public final ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>();
final ArrayList<GenericInsertPair> allPairs = new ArrayList<>(); final ArrayList<ResultPair<TypePlaceholder, TypePlaceholder>> allPairs = new ArrayList<>();
public final ArrayList<TPHConstraint> allCons = new ArrayList<>(); public final ArrayList<TPHConstraint> allCons = new ArrayList<>();
private ResultSet resultSet; private ResultSet resultSet;
private Resolver resolver;
public TPHExtractor() { public TPHExtractor() {
@@ -46,31 +60,108 @@ public class TPHExtractor extends AbstractASTWalker {
public void setResultSet(ResultSet resultSet) { public void setResultSet(ResultSet resultSet) {
this.resultSet = resultSet; this.resultSet = resultSet;
this.resolver = new Resolver(resultSet);
} }
public Resolver getResolver() {
return resolver;
}
// @Override
// public void visit(ClassOrInterface classOrInterface) {
// inMethod = false;
// classOrInterface.getfieldInitializations().ifPresent(c->c.block.accept(this));
// super.visit(classOrInterface);
// inMethod = true;
// }
@Override @Override
public void visit(TypePlaceholder tph) { public void visit(TypePlaceholder tph) {
if (resultSet.resolveType(tph).resolvedType instanceof TypePlaceholder) { if (resultSet.resolveType(tph).resolvedType instanceof TypePlaceholder) {
TypePlaceholder resolvedTPH = (TypePlaceholder) resultSet.resolveType(tph).resolvedType; TypePlaceholder resolvedTPH = (TypePlaceholder) resultSet.resolveType(tph).resolvedType;
if (inMethod) { if (inMethod) {
methodAndTph.getTphs().add(resolvedTPH.getName()); methodAndTph.getTphs().add(resolvedTPH.getName());
if (inLocalOrParam) if (inLocalOrParamOrReturn)
methodAndTph.getLocalTphs().add(resolvedTPH.getName()); methodAndTph.getLocalTphs().add(resolvedTPH.getName());
}else {
tphsClass.add(resolvedTPH.getName());
} }
allTPHS.put(resolvedTPH, inMethod); allTPHS.put(resolvedTPH.getName(), inMethod);
resultSet.resolveType(tph).additionalGenerics.forEach(ag -> { // final List<TPHConstraint> cons = new ArrayList<>();
if (ag.contains(resolvedTPH) && ag.TA1.equals(resolvedTPH) && !contains(allPairs, ag)) { // resultSet.resolveType(tph).additionalGenerics.forEach(ag -> {
// TPHConstraint con = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS);
// cons.add(con);
// });
//
// Map<TPHConstraint, Boolean> visitMap = new HashMap<>();
// for(TPHConstraint cc : cons) {
// visitMap.put(cc, false);
// }
//
// String left = resolvedTPH.getName();
// for (TPHConstraint cc : visitMap.keySet()) {
//
// if(visitMap.get(cc))
// continue;
//
// if (cc.getLeft().equals(left)) {
// allCons.add(cc);
// List<TPHConstraint> toVisit = getToVisitCons(cons,cc.getRight(), visitMap);
// }
// }
//resultSet.resolveType(tph).getAdditionalGenerics().forEach(ag -> {
resultSet.genIns.forEach(ag -> {
// if (ag.contains(resolvedTPH) /* && ag.TA1.equals(resolvedTPH) */ && !contains(allPairs, ag)) {
if (inMethod) if (inMethod)
methodAndTph.getPairs().add(ag); methodAndTph.getPairs().add(ag);
allPairs.add(ag); allPairs.add(ag);
TPHConstraint con = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS); TPHConstraint con = new ExtendsConstraint(ag.getLeft().getName(), ag.getRight().getName());
if(!containsConstraint(allCons,con))
allCons.add(con); allCons.add(con);
} // }
}); });
} else if (resultSet.resolveType(tph).resolvedType instanceof RefType) {
RefType rt = (RefType) resultSet.resolveType(tph).resolvedType;
rt.accept(this);
} }
} }
private static boolean containsConstraint(ArrayList<TPHConstraint> allCons, TPHConstraint c) {
for(TPHConstraint con:allCons) {
if(c.getLeft().equals(con.getLeft()) && c.getRight().equals(con.getRight())) {
return true;
}
}
return false;
}
private List<TPHConstraint> getToVisitCons(List<TPHConstraint> cons, String right, Map<TPHConstraint, Boolean> visitMap) {
List<TPHConstraint> res = new ArrayList<>();
for(TPHConstraint cc : cons) {
if(cc.getLeft().equals(right)) {
res.add(cc);
if(visitMap.get(cc))
visitMap.replace(cc, false);
}
}
return res;
}
@Override
public void visit(GenericRefType genericRefType) {
String name = genericRefType.getParsedName();
if (inMethod) {
methodAndTph.getTphs().add(name);
if (inLocalOrParamOrReturn)
methodAndTph.getLocalTphs().add(name);
}else {
tphsClass.add(name);
}
allTPHS.put(name, inMethod);
}
private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) { private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) {
for (int i = 0; i < pairs.size(); ++i) { for (int i = 0; i < pairs.size(); ++i) {
GenericInsertPair p = pairs.get(i); GenericInsertPair p = pairs.get(i);
@@ -83,8 +174,17 @@ public class TPHExtractor extends AbstractASTWalker {
@Override @Override
public void visit(Method method) { public void visit(Method method) {
inMethod = true; inMethod = true;
methodAndTph = new MethodAndTPH(method.name); String id = MethodUtility.createID(resolver,method);
super.visit(method); methodAndTph = new MethodAndTPH(id);
inLocalOrParamOrReturn = true;
method.getReturnType().accept(this);
method.getParameterList().accept(this);
inLocalOrParamOrReturn = false;
if(method.block != null)
method.block.accept(this);
inMethod = false; inMethod = false;
ListOfMethodsAndTph.add(methodAndTph); ListOfMethodsAndTph.add(methodAndTph);
} }
@@ -92,29 +192,32 @@ public class TPHExtractor extends AbstractASTWalker {
@Override @Override
public void visit(Constructor cons) { public void visit(Constructor cons) {
inMethod = false; inMethod = false;
super.visit(cons); //super.visit(cons);
cons.getParameterList().accept(this);
if(cons.block != null)
cons.block.accept(this);
inMethod = true; inMethod = true;
} }
@Override @Override
public void visit(LocalVarDecl localVarDecl) { public void visit(LocalVarDecl localVarDecl) {
inLocalOrParam = true; // inLocalOrParamOrReturn = inMethod;
super.visit(localVarDecl); super.visit(localVarDecl);
inLocalOrParam = false; // inLocalOrParamOrReturn = false;
} }
@Override @Override
public void visit(LocalVar localVar) { public void visit(LocalVar localVar) {
inLocalOrParam = true; // inLocalOrParamOrReturn = inMethod;
super.visit(localVar); super.visit(localVar);
inLocalOrParam = false; // inLocalOrParamOrReturn = false;
} }
@Override @Override
public void visit(ParameterList formalParameters) { public void visit(ParameterList formalParameters) {
inLocalOrParam = true; inLocalOrParamOrReturn = inMethod;
super.visit(formalParameters); super.visit(formalParameters);
inLocalOrParam = false; inLocalOrParamOrReturn = false;
} }
} }

View File

@@ -2,8 +2,8 @@ package de.dhbwstuttgart.bytecode.constraint;
public class EqualConstraint extends TPHConstraint { public class EqualConstraint extends TPHConstraint {
public EqualConstraint(String left, String right, Relation rel) { public EqualConstraint(String left, String right) {
super(left, right, rel); super(left, right, Relation.EQUAL);
} }
} }

View File

@@ -2,8 +2,8 @@ package de.dhbwstuttgart.bytecode.constraint;
public class ExtendsConstraint extends TPHConstraint { public class ExtendsConstraint extends TPHConstraint {
public ExtendsConstraint(String left, String right, Relation rel) { public ExtendsConstraint(String left, String right) {
super(left, right, rel); super(left, right, Relation.EXTENDS);
} }
} }

View File

@@ -44,6 +44,10 @@ public class TPHConstraint {
return left.equals(tph)||right.equals(tph); return left.equals(tph)||right.equals(tph);
} }
public boolean equalConstraint(TPHConstraint constraint) {
return rel == constraint.getRel() && left.equals(constraint.getLeft()) && right.equals(constraint.getRight());
}
@Override @Override
public String toString() { public String toString() {
if(rel == Relation.EXTENDS) { if(rel == Relation.EXTENDS) {

View File

@@ -1,30 +1,29 @@
package de.dhbwstuttgart.bytecode.descriptor; package de.dhbwstuttgart.bytecode.descriptor;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import de.dhbwstuttgart.bytecode.utilities.*;
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
import de.dhbwstuttgart.bytecode.utilities.Lambda;
import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
import de.dhbwstuttgart.bytecode.utilities.SamMethod;
import de.dhbwstuttgart.syntaxtree.FormalParameter; import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.statement.Expression; import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
public class DescriptorToString implements DescriptorVisitor{ public class DescriptorToString implements DescriptorVisitor, CONSTANTS {
ResultSet resultSet; ResultSet resultSet;
public DescriptorToString() {
}
public DescriptorToString(ResultSet resultSet) { public DescriptorToString(ResultSet resultSet) {
this.resultSet = resultSet; this.resultSet = resultSet;
} }
private String addReturnType(String desc, RefTypeOrTPHOrWildcardOrGeneric returnType, ResultSet resultSet) { private String addReturnType(String desc, RefTypeOrTPHOrWildcardOrGeneric returnType, ResultSet resultSet) {
if(resultSet.resolveType(returnType).resolvedType.toString().equals("void")){ if(resultSet.resolveType(returnType).resolvedType.toString().equals(CONSTANTS.VOID)){
desc = desc + ")V"; desc = desc + ")V";
}else { }else {
desc = desc + ")" + "L"+resultSet.resolveType(returnType).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; desc = desc + ")" + "L"+resultSet.resolveType(returnType).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
@@ -44,30 +43,41 @@ public class DescriptorToString implements DescriptorVisitor{
if(method.hasGen()) { if(method.hasGen()) {
String fpDesc = fp.getType().acceptTV(new TypeToDescriptor()); String fpDesc = fp.getType().acceptTV(new TypeToDescriptor());
if(method.getGenericsAndBoundsMethod().containsKey(fpDesc)) { if(method.getGenericsAndBoundsMethod().containsKey(fpDesc)) {
desc += "L"+method.getGenericsAndBoundsMethod().get(fpDesc)+ ";"; String bound = getBound(fpDesc, method.getGenericsAndBoundsMethod());
desc += "L"+bound+ ";";
}else if(method.getGenericsAndBounds().containsKey(fpDesc)){ }else if(method.getGenericsAndBounds().containsKey(fpDesc)){
desc += "L"+method.getGenericsAndBounds().get(fpDesc)+ ";"; String bound = getBound(fpDesc, method.getGenericsAndBounds());
desc += "L"+bound+ ";";
}else { }else {
// desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; // desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
String resType = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()); String resType = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
if(resType.subSequence(0, 4).equals("TPH ")) { if(resType.contains(CONSTANTS.TPH)/*resType.subSequence(0, 4).equals("TPH ")*/) {
// Bound ist immer Object // Bound ist immer Object
desc += "L"+Type.getInternalName(Object.class)+ ";"; desc += "L"+Type.getInternalName(Object.class)+ ";";
} else {
// TODO::
if(method.getGenericsAndBounds().containsKey(resType)) {
String bound = getBound(resType, method.getGenericsAndBounds());
desc += "L"+bound+ ";";
}else if(method.getGenericsAndBoundsMethod().containsKey(resType)) {
String bound = getBound(resType, method.getGenericsAndBoundsMethod());
desc += "L"+bound+ ";";
} else { } else {
desc += "L"+resType+ ";"; desc += "L"+resType+ ";";
} }
} }
} }
}
//TODO: generate a class java%% ... %% //TODO: generate a class java%% ... %%
else if(resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()).contains("<")){ else if(resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()).contains(CONSTANTS.ANGLEBRACKET)){
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "$$").replace("<", "$$$").replace(">", "$$$")+ ";"; desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.toString().replace(".", "$$").replace(CONSTANTS.ANGLEBRACKET, "$$$").replace(">", "$$$")+ ";";
} }
else { else {
desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
} }
} }
if(resultSet.resolveType(method.getReturnType()).resolvedType.toString().equals("void")) { if(resultSet.resolveType(method.getReturnType()).resolvedType.toString().equals(CONSTANTS.VOID)) {
desc += ")V"; desc += ")V";
}else { }else {
if(method.hasGen()) { if(method.hasGen()) {
@@ -78,11 +88,21 @@ public class DescriptorToString implements DescriptorVisitor{
desc += ")L"+method.getGenericsAndBounds().get(ret)+ ";"; desc += ")L"+method.getGenericsAndBounds().get(ret)+ ";";
}else { }else {
String resType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor()); String resType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
if(resType.subSequence(0, 4).equals("TPH ")) { if(resType.contains(CONSTANTS.TPH)/*resType.subSequence(0, 4).equals("TPH ")*/) {
// desc += ")" + "L"+method.getGenericsAndBoundsMethod().get(resType.substring(4)+"$")+ ";"; // desc += ")" + "L"+method.getGenericsAndBoundsMethod().get(resType.substring(4)+"$")+ ";";
desc += ")" + "L"+Type.getInternalName(Object.class)+ ";"; desc += ")" + "L"+Type.getInternalName(Object.class)+ ";";
} else { } else {
desc += ")" + "L"+resType+ ";"; // TODO::
if(method.getGenericsAndBounds().containsKey(resType)) {
String bound = getBound(resType, method.getGenericsAndBounds());
desc += ")L"+bound+ ";";
}else if(method.getGenericsAndBoundsMethod().containsKey(resType)) {
String bound = getBound(resType, method.getGenericsAndBoundsMethod());
desc += ")L"+bound+ ";";
} else {
desc += ")L"+resType+ ";";
}
// desc += ")" + "L"+resType+ ";";
} }
} }
}else { }else {
@@ -93,6 +113,15 @@ public class DescriptorToString implements DescriptorVisitor{
return desc; return desc;
} }
private String getBound(String fpDesc, HashMap<String, String> genericsAndBounds) {
String start = genericsAndBounds.get(fpDesc);
while(genericsAndBounds.containsKey(start)) {
start = genericsAndBounds.get(start);
}
return start;
}
@Override @Override
public String visit(NormalConstructor constructor) { public String visit(NormalConstructor constructor) {
String desc = "("; String desc = "(";
@@ -108,7 +137,7 @@ public class DescriptorToString implements DescriptorVisitor{
}else { }else {
// desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";"; // desc += "L"+resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+ ";";
String resType = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()); String resType = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
if(resType.subSequence(0, 4).equals("TPH ")) { if(resType.subSequence(0, 4).equals(CONSTANTS.TPH)) {
// Bound ist immer Object // Bound ist immer Object
desc += "L"+Type.getInternalName(Object.class)+ ";"; desc += "L"+Type.getInternalName(Object.class)+ ";";
} else { } else {
@@ -131,7 +160,7 @@ public class DescriptorToString implements DescriptorVisitor{
while(itr.hasNext()) { while(itr.hasNext()) {
FormalParameter fp = itr.next(); FormalParameter fp = itr.next();
String d = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()); String d = resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor());
if(d.substring(0, 4).equals("TPH ") ||d.contains("<")) { if(d.contains(CONSTANTS.TPH) ||d.contains(CONSTANTS.ANGLEBRACKET)) {
desc += "L"+Type.getInternalName(Object.class)+ ";"; desc += "L"+Type.getInternalName(Object.class)+ ";";
}else { }else {
desc = desc + "L"+ d + ";"; desc = desc + "L"+ d + ";";
@@ -140,7 +169,7 @@ public class DescriptorToString implements DescriptorVisitor{
String retType = resultSet.resolveType(lambdaExpression.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor()); String retType = resultSet.resolveType(lambdaExpression.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<")){ if(retType.contains(CONSTANTS.TPH)|| retType.contains(CONSTANTS.ANGLEBRACKET)){
desc += ")L"+Type.getInternalName(Object.class)+ ";"; desc += ")L"+Type.getInternalName(Object.class)+ ";";
}else { }else {
desc = desc + ")"+"L"+retType+";"; desc = desc + ")"+"L"+retType+";";
@@ -156,7 +185,7 @@ public class DescriptorToString implements DescriptorVisitor{
RefTypeOrTPHOrWildcardOrGeneric rt = itr.next(); RefTypeOrTPHOrWildcardOrGeneric rt = itr.next();
String d = resultSet.resolveType(rt).resolvedType.acceptTV(new TypeToDescriptor()); String d = resultSet.resolveType(rt).resolvedType.acceptTV(new TypeToDescriptor());
if(d.substring(0, 4).equals("TPH ") ||d.contains("<")) { if(d.contains(CONSTANTS.TPH) ||d.contains(CONSTANTS.ANGLEBRACKET)) {
desc += "L"+Type.getInternalName(Object.class)+ ";"; desc += "L"+Type.getInternalName(Object.class)+ ";";
}else { }else {
desc += "L"+ d + ";"; desc += "L"+ d + ";";
@@ -165,7 +194,7 @@ public class DescriptorToString implements DescriptorVisitor{
} }
String retType = resultSet.resolveType(samMethod.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor()); String retType = resultSet.resolveType(samMethod.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<")){ if(retType.contains(CONSTANTS.TPH)|| retType.contains(CONSTANTS.ANGLEBRACKET)){
desc += ")L"+Type.getInternalName(Object.class)+ ";"; desc += ")L"+Type.getInternalName(Object.class)+ ";";
}else { }else {
desc = desc + ")"+"L"+retType+";"; desc = desc + ")"+"L"+retType+";";
@@ -179,7 +208,7 @@ public class DescriptorToString implements DescriptorVisitor{
for(Expression e : methodFromMethodCall.getArgList().getArguments()) { for(Expression e : methodFromMethodCall.getArgList().getArguments()) {
String d = resultSet.resolveType(e.getType()).resolvedType.acceptTV(new TypeToDescriptor()); String d = resultSet.resolveType(e.getType()).resolvedType.acceptTV(new TypeToDescriptor());
if(d.substring(0, 4).equals("TPH ") ||d.contains("<") || methodFromMethodCall.getReceiverName().contains("$$")) { if(d.contains(CONSTANTS.TPH) ||d.contains(CONSTANTS.ANGLEBRACKET) || methodFromMethodCall.getReceiverName().contains("$$")) {
desc += "L"+Type.getInternalName(Object.class)+ ";"; desc += "L"+Type.getInternalName(Object.class)+ ";";
}else { }else {
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(d)) { if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(d)) {
@@ -194,9 +223,9 @@ public class DescriptorToString implements DescriptorVisitor{
} }
String retType = resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor()); String retType = resultSet.resolveType(methodFromMethodCall.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
System.out.println("DescriptorToString retType = " + retType); System.out.println("DescriptorToString retType = " + retType);
if(retType.equals("void")) { if(retType.equals(CONSTANTS.VOID)) {
desc += ")V"; desc += ")V";
}else if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<") || methodFromMethodCall.getReceiverName().contains("$$")){ }else if(retType.contains(CONSTANTS.TPH)|| retType.contains(CONSTANTS.ANGLEBRACKET) || methodFromMethodCall.getReceiverName().contains("$$")){
desc += ")L"+Type.getInternalName(Object.class)+ ";"; desc += ")L"+Type.getInternalName(Object.class)+ ";";
}else { }else {
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(retType)) { if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(retType)) {
@@ -211,4 +240,20 @@ public class DescriptorToString implements DescriptorVisitor{
return desc; return desc;
} }
@Override
public String createDescForFunN(ArgumentList argumentList, String returnType) {
Iterator<Expression> itr1 = argumentList.getArguments().iterator();
String methDesc = "(";
while(itr1.hasNext()) {
methDesc += "L" + Type.getInternalName(Object.class) + ";";
itr1.next();
}
if (returnType.equals(CONSTANTS.VOID)){
methDesc += ")V";
} else {
methDesc += ")L" + Type.getInternalName(Object.class) + ";";
}
return methDesc;
}
} }

View File

@@ -5,11 +5,13 @@ import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor; import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
import de.dhbwstuttgart.bytecode.utilities.NormalMethod; import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
import de.dhbwstuttgart.bytecode.utilities.SamMethod; import de.dhbwstuttgart.bytecode.utilities.SamMethod;
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
public interface DescriptorVisitor { public interface DescriptorVisitor {
public String visit(NormalMethod method); String visit(NormalMethod method);
public String visit(NormalConstructor constructor); String visit(NormalConstructor constructor);
public String visit(Lambda lambdaExpression); String visit(Lambda lambdaExpression);
public String visit(SamMethod samMethod); String visit(SamMethod samMethod);
public String visit(MethodFromMethodCall methodFromMethodCall); String visit(MethodFromMethodCall methodFromMethodCall);
String createDescForFunN(ArgumentList argumentList, String returnType);
} }

View File

@@ -0,0 +1,53 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGenerator;
import java.util.List;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.NameReplacementResult;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
/**
* This class represents the result of the constraints simplifier.
*
* @author fayez
*
*/
public class ConstraintsSimplierResult {
private List<GenericsGeneratorResult> genericsGenResults;
private List<NameReplacementResult> nameReplacementResults;
/**
* @param genericsGenResults
*/
public ConstraintsSimplierResult(List<GenericsGeneratorResult> genericsGenResults,
List<NameReplacementResult> nameReplacementResults) {
this.genericsGenResults = genericsGenResults;
this.setNameReplacementResults(nameReplacementResults);
}
/**
* @return the genericsGenResults
*/
public List<GenericsGeneratorResult> getGenericsGenResults() {
return genericsGenResults;
}
/**
* @param genericsGenResults the genericsGenResults to set
*/
public void setGenericsGenResults(List<GenericsGeneratorResult> genericsGenResults) {
this.genericsGenResults = genericsGenResults;
}
/**
* @return the nameReplacementResults
*/
public List<NameReplacementResult> getNameReplacementResults() {
return nameReplacementResults;
}
/**
* @param nameReplacementResults the nameReplacementResults to set
*/
public void setNameReplacementResults(List<NameReplacementResult> nameReplacementResults) {
this.nameReplacementResults = nameReplacementResults;
}
}

View File

@@ -0,0 +1,137 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGenerator;
import java.util.*;
import de.dhbwstuttgart.bytecode.TPHExtractor;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.*;
/**
* @author fayez
*
*/
public class ConstraintsSimplifier {
public static ConstraintsSimplierResult simplifyConstraints(final TPHExtractor tphExtractor, final List<GenericsGeneratorResult> genericsGeneratorResults, final List<String> tphsClass) {
List<TPHConstraint> allCons = tphExtractor.allCons;
List<TPHConstraint> equalCons = new ArrayList<>();
/* Step 1 */
List<ConstraintsWithSameLeftSide> foundCons = GenericsGeneratorUtility.findConstraintsWithLeftSameLeftSide(allCons);
if(!foundCons.isEmpty()) {
List<TPHConstraint> equalCons2 = new ArrayList<>();
GenericsGeneratorUtility.simplifyConstraintsWithSameLeftSide(foundCons,tphExtractor,tphsClass,equalCons2);
equalCons.addAll(equalCons2);
}
// if(!simpleCycles.isEmpty()) {
// handleSimpleCycles(allCons, simpleCycles,tphExtractor);
// equalCons.addAll(GenericsGeneratorUtility.getEqualConstraints(allCons));
// }
//
List<Cycle> cycles = findCycles(allCons);
if(!cycles.isEmpty()) {
handleCycle(genericsGeneratorResults, allCons, cycles,tphExtractor);
}
/* The right hand side of equal constraint is the new name in name replacement result */
List<NameReplacementResult> nameReplacementResults = GenericsGeneratorUtility.createNameReplacementResultsFromEqualConstraints(equalCons);
getEqualsFromNameReplacementResults(genericsGeneratorResults,nameReplacementResults);
ConstraintsSimplierResult result = new ConstraintsSimplierResult(genericsGeneratorResults, nameReplacementResults);
return result;
}
private static void getEqualsFromNameReplacementResults(List<GenericsGeneratorResult> genericsGeneratorResults,
List<NameReplacementResult> nameReplacementResults) {
genericsGeneratorResults.forEach(g->{
String tph = g.getConstraint().getLeft();
if (!nameReplacementResults.isEmpty()) {
collectAllEquals(nameReplacementResults, g, tph);
}
if (!nameReplacementResults.isEmpty()) {
collectAllEquals(nameReplacementResults, g);
}
});
}
private static void collectAllEquals(List<NameReplacementResult> nameReplacementResults, GenericsGeneratorResult g) {
Set<String> equalsTPHs = g.getEqualsTPHs();
Set<String> tphsToAdd = getAllEqualTphs(equalsTPHs, nameReplacementResults);
while (!tphsToAdd.isEmpty()){
equalsTPHs.addAll(tphsToAdd);
tphsToAdd = getAllEqualTphs(equalsTPHs, nameReplacementResults);
}
}
private static Set<String> getAllEqualTphs(Set<String> equalsTPHs, List<NameReplacementResult> nameReplacementResults) {
Set<String> tphsToAdd = new HashSet<>();
equalsTPHs.forEach(e->{
collectAllEquals(nameReplacementResults, tphsToAdd,e);
});
return tphsToAdd;
}
public static void collectAllEquals(List<NameReplacementResult> nameReplacementResults, Set<String> tphsToAdd,
String tph) {
List<NameReplacementResult> toRemoveList = new ArrayList<>();
Optional<NameReplacementResult> nameReplacementResult = nameReplacementResults.stream().filter(n->n.getName().equals(tph)).findFirst();
nameReplacementResult.ifPresent(toRemove->{
tphsToAdd.addAll(toRemove.getOldNames());
toRemoveList.add(toRemove);
});
if(!toRemoveList.isEmpty()){
nameReplacementResults.remove(toRemoveList.get(0));
toRemoveList.clear();
}
}
/**
* @param nameReplacementResults
* @param g
* @param tph
*/
public static void collectAllEquals(List<NameReplacementResult> nameReplacementResults, GenericsGeneratorResult g,
String tph) {
List<NameReplacementResult> toRemoveList = new ArrayList<>();
Optional<NameReplacementResult> nameReplacementResult = nameReplacementResults.stream().filter(n->n.getName().equals(tph)).findFirst();
nameReplacementResult.ifPresent(toRemove->{
g.getEqualsTPHs().addAll(toRemove.getOldNames());
toRemoveList.add(toRemove);
});
if(!toRemoveList.isEmpty()){
nameReplacementResults.remove(toRemoveList.get(0));
toRemoveList.clear();
}
}
/**
* @param genericsGeneratorResults
* @param allCons
* @param cycles
* @param tphExtractor
*/
public static void handleCycle(List<GenericsGeneratorResult> genericsGeneratorResults,
List<TPHConstraint> allCons, List<Cycle> cycles, TPHExtractor tphExtractor) {
GenericsGeneratorUtility.modifyRelationForConstraintsInCycle(cycles);
List<NameReplacementResult> nameReplacementResults = GenericsGeneratorUtility.substituteTPHSFormCycle(allCons, cycles,tphExtractor);
GenericsGeneratorUtility.createResults(genericsGeneratorResults,nameReplacementResults);
GenericsGeneratorUtility.removeEqualConstraints(allCons);
}
/**
* @param allCons
* @return
*/
public static List<Cycle> findCycles(List<TPHConstraint> allCons) {
/* find all cycles */
CyclesFinder cyclesFinder = new CyclesFinder(allCons);
List<Cycle> cycles = cyclesFinder.findCycles();
return cycles;
}
}

View File

@@ -0,0 +1,106 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGenerator;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.Cycle;
/**
* @author fayez
*
*/
public class CyclesFinder {
private final List<TPHConstraint> allCons;
public CyclesFinder(List<TPHConstraint> allCons) {
this.allCons = allCons;
}
public List<Cycle> findCycles() {
List<TPHConstraint> vistedConstraints = new ArrayList<>(allCons.size());
List<Cycle> cycles = new ArrayList<>();
for (TPHConstraint constraint : allCons) {
if(constraint.getRel()==Relation.EQUAL)
continue;
if (!vistedConstraints.contains(constraint)) {
vistedConstraints.add(constraint);
checkConstraint(constraint, vistedConstraints, cycles);
}
}
return cycles;
}
private void checkConstraint(TPHConstraint constraint, List<TPHConstraint> vistedConstraints,
List<Cycle> cycles) {
List<String> tphsInRelation = new LinkedList<>();
List<TPHConstraint> maybeCycle = new ArrayList<>();
maybeCycle.add(constraint);
tphsInRelation.add(constraint.getLeft());
tphsInRelation.add(constraint.getRight());
Optional<TPHConstraint> nextConstraint = getConstraintInRelation(tphsInRelation, maybeCycle);
while (nextConstraint.isPresent()) {
if(containsInLongCycle(nextConstraint.get(), cycles)) {
break;
}
if (isCycle(tphsInRelation)) {
addAllToVisitedConstraints(vistedConstraints, maybeCycle);
Cycle cycle = new Cycle(maybeCycle);
cycles.add(cycle);
return;
}
nextConstraint = getConstraintInRelation(tphsInRelation, maybeCycle);
}
// addAllToVisitedConstraints(vistedConstraints, maybeCycle);
}
private boolean containsInLongCycle(TPHConstraint c, List<Cycle> cycles) {
for(Cycle cycle : cycles) {
if(cycle.containConstraint(c))
return true;
}
return false;
}
private void addAllToVisitedConstraints(List<TPHConstraint> vistedConstraints, List<TPHConstraint> maybeCycle) {
for (TPHConstraint con : maybeCycle) {
if (!vistedConstraints.contains(con))
vistedConstraints.add(con);
}
}
private Optional<TPHConstraint> getConstraintInRelation(List<String> tphsInRelation,
List<TPHConstraint> maybeCycle) {
TPHConstraint constraint = getConstraintByLeftSide(tphsInRelation.get(tphsInRelation.size()-1),maybeCycle);
Optional<TPHConstraint> nextConstraint = Optional.ofNullable(constraint);
if(nextConstraint.isPresent()) {
maybeCycle.add(constraint);
tphsInRelation.add(constraint.getRight());
}
return nextConstraint;
}
private TPHConstraint getConstraintByLeftSide(String left, List<TPHConstraint> maybeCycle) {
for(TPHConstraint constraint : allCons) {
if(constraint.getRel()==Relation.EQUAL)
continue;
if(maybeCycle.contains(constraint))
continue;
if(constraint.getLeft().equals(left))
return constraint;
}
return null;
}
private boolean isCycle(List<String> tphsInRelation) {
return tphsInRelation.get(0).equals(tphsInRelation.get(tphsInRelation.size() - 1));
}
}

View File

@@ -0,0 +1,674 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGenerator;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Optional;
import de.dhbwstuttgart.bytecode.TPHExtractor;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGenratorResultForSourceFile;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResultForClass;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.MethodAndConstraints;
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
import de.dhbwstuttgart.bytecode.utilities.MethodUtility;
import de.dhbwstuttgart.bytecode.utilities.Resolver;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.ASTVisitor;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.Field;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
import de.dhbwstuttgart.syntaxtree.statement.Assign;
import de.dhbwstuttgart.syntaxtree.statement.AssignToField;
import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr;
import de.dhbwstuttgart.syntaxtree.statement.Block;
import de.dhbwstuttgart.syntaxtree.statement.CastExpr;
import de.dhbwstuttgart.syntaxtree.statement.DoStmt;
import de.dhbwstuttgart.syntaxtree.statement.EmptyStmt;
import de.dhbwstuttgart.syntaxtree.statement.ExpressionReceiver;
import de.dhbwstuttgart.syntaxtree.statement.FieldVar;
import de.dhbwstuttgart.syntaxtree.statement.ForStmt;
import de.dhbwstuttgart.syntaxtree.statement.IfStmt;
import de.dhbwstuttgart.syntaxtree.statement.InstanceOf;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
import de.dhbwstuttgart.syntaxtree.statement.Literal;
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl;
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
import de.dhbwstuttgart.syntaxtree.statement.NewArray;
import de.dhbwstuttgart.syntaxtree.statement.NewClass;
import de.dhbwstuttgart.syntaxtree.statement.Return;
import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid;
import de.dhbwstuttgart.syntaxtree.statement.StaticClassName;
import de.dhbwstuttgart.syntaxtree.statement.Super;
import de.dhbwstuttgart.syntaxtree.statement.SuperCall;
import de.dhbwstuttgart.syntaxtree.statement.This;
import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr;
import de.dhbwstuttgart.syntaxtree.statement.WhileStmt;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.ResultSet;
/**
* @author fayez
*
*/
public class GeneratedGenericsFinder implements ASTVisitor {
private final TPHExtractor tphExtractor = new TPHExtractor();
private Collection<ResultSet> listOfResultSets;
private SourceFile sf;
private List<String> tphsClass;
private GenericGenratorResultForSourceFile generatedGenericsForSF;
private ResultSet resultSet;
private final List<String> methodNameAndParamsT = new ArrayList<>();
private String pkgName;
private String className;
private Resolver resolver;
/**
* @param sf
* @param listOfResultSets
*/
public GeneratedGenericsFinder(SourceFile sf, Collection<ResultSet> listOfResultSets) {
this.sf = sf;
this.listOfResultSets = listOfResultSets;
}
public GenericGenratorResultForSourceFile findGeneratedGenerics() {
sf.accept(this);
return generatedGenericsForSF;
}
/*
* (non-Javadoc)
*
* @see
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
* SourceFile)
*/
@Override
public void visit(SourceFile sourceFile) {
pkgName = sf.getPkgName();
generatedGenericsForSF = new GenericGenratorResultForSourceFile(pkgName);
for (ClassOrInterface cl : sourceFile.getClasses()) {
cl.accept(this);
}
}
/*
* (non-Javadoc)
*
* @see
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
* ClassOrInterface)
*/
@Override
public void visit(ClassOrInterface classOrInterface) {
className = classOrInterface.getClassName().toString();
List<ResultSet> listOfResultSetsList = new ArrayList<>(listOfResultSets);
boolean isVisited = false;
ConstraintsSimplierResult simplifiedConstraints = null;
GenericsGeneratorResultForClass ggResult = null;
for (int i = 0; i < listOfResultSetsList.size(); i++) {
resultSet = listOfResultSetsList.get(i);
tphExtractor.setResultSet(resultSet);
resolver = new Resolver(resultSet);
classOrInterface.accept(tphExtractor);
tphsClass = tphExtractor.tphsClass;
simplifiedConstraints = GenericsGenerator.simplifyConstraints(tphExtractor, tphsClass);
if(!isVisited) {
ggResult = GenericsGenerator.generateConstraints(className, tphExtractor, tphsClass,simplifiedConstraints);
isVisited = true;
}
for(Method m : classOrInterface.getMethods()) {
addMethodConstraints(simplifiedConstraints, ggResult, m);
}
if(ggResult != null)
generatedGenericsForSF.addGenericGeneratorResultClass(ggResult);
}
}
/**
* @param simplifiedConstraints
* @param ggResult
* @param m
*/
public void addMethodConstraints(ConstraintsSimplierResult simplifiedConstraints,
GenericsGeneratorResultForClass ggResult, Method m) {
String id = MethodUtility.createID(resolver, m);
boolean isInGGResult = (ggResult != null) && ggResult.contains(id);
if(methodNameAndParamsT.contains(id) || isInGGResult)
return;
methodNameAndParamsT.add(id);
Optional<MethodAndTPH> methodAndTPH = GenericsGeneratorUtility.getMethodAndTphs(tphExtractor.ListOfMethodsAndTph,id);
methodAndTPH.ifPresent(mt->{
MethodAndConstraints methodConstraints = GenericsGenerator.generateConstraintsForMethod(tphExtractor.allCons, mt , simplifiedConstraints, tphsClass);
ggResult.getMethodsAndTheirConstraints().getMethodsAndConstraints().add(methodConstraints);
});
}
/*
* (non-Javadoc)
*
* @see
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
* Method)
*/
@Override
public void visit(Method method) {
}
/*
* (non-Javadoc)
*
* @see
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
* ParameterList)
*/
@Override
public void visit(ParameterList formalParameters) {
}
/*
* (non-Javadoc)
*
* @see
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
* Constructor)
*/
@Override
public void visit(Constructor field) {
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.ArgumentList)
*/
@Override
public void visit(ArgumentList argumentList) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.LambdaExpression)
*/
@Override
public void visit(LambdaExpression lambdaExpression) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.Assign)
*/
@Override
public void visit(Assign assign) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.BinaryExpr)
*/
@Override
public void visit(BinaryExpr binary) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.Block)
*/
@Override
public void visit(Block block) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.CastExpr)
*/
@Override
public void visit(CastExpr castExpr) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.EmptyStmt)
*/
@Override
public void visit(EmptyStmt emptyStmt) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.FieldVar)
*/
@Override
public void visit(FieldVar fieldVar) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.ForStmt)
*/
@Override
public void visit(ForStmt forStmt) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.IfStmt)
*/
@Override
public void visit(IfStmt ifStmt) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.InstanceOf)
*/
@Override
public void visit(InstanceOf instanceOf) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.LocalVar)
*/
@Override
public void visit(LocalVar localVar) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.LocalVarDecl)
*/
@Override
public void visit(LocalVarDecl localVarDecl) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.MethodCall)
*/
@Override
public void visit(MethodCall methodCall) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.NewClass)
*/
@Override
public void visit(NewClass methodCall) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.NewArray)
*/
@Override
public void visit(NewArray newArray) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.Return)
*/
@Override
public void visit(Return aReturn) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.ReturnVoid)
*/
@Override
public void visit(ReturnVoid aReturn) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.StaticClassName)
*/
@Override
public void visit(StaticClassName staticClassName) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.Super)
*/
@Override
public void visit(Super aSuper) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.This)
*/
@Override
public void visit(This aThis) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.WhileStmt)
*/
@Override
public void visit(WhileStmt whileStmt) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.DoStmt)
*/
@Override
public void visit(DoStmt whileStmt) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.AssignToField)
*/
@Override
public void visit(AssignToField assignLeftSide) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.parser.
* SyntaxTreeGenerator.AssignToLocal)
*/
@Override
public void visit(AssignToLocal assignLeftSide) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.SuperCall)
*/
@Override
public void visit(SuperCall superCall) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.ExpressionReceiver)
*/
@Override
public void visit(ExpressionReceiver expressionReceiver) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.UnaryExpr)
*/
@Override
public void visit(UnaryExpr unaryExpr) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.
* syntaxtree.statement.Literal)
*/
@Override
public void visit(Literal literal) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
* GenericTypeVar)
*/
@Override
public void visit(GenericTypeVar genericTypeVar) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
* FormalParameter)
*/
@Override
public void visit(FormalParameter formalParameter) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
* GenericDeclarationList)
*/
@Override
public void visit(GenericDeclarationList genericTypeVars) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.
* Field)
*/
@Override
public void visit(Field field) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.type
* .RefType)
*/
@Override
public void visit(RefType refType) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.type
* .SuperWildcardType)
*/
@Override
public void visit(SuperWildcardType superWildcardType) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.type
* .TypePlaceholder)
*/
@Override
public void visit(TypePlaceholder typePlaceholder) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.type
* .ExtendsWildcardType)
*/
@Override
public void visit(ExtendsWildcardType extendsWildcardType) {
// TODO Auto-generated method stub
}
/*
* (non-Javadoc)
*
* @see
* de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.type
* .GenericRefType)
*/
@Override
public void visit(GenericRefType genericRefType) {
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,255 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGenerator;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.*;
import org.objectweb.asm.Type;
import de.dhbwstuttgart.bytecode.TPHExtractor;
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
/**
* @author fayez
*
*/
public class GenericsGenerator {
/*TODO: When generating generics for a class if we have the following:
tphClass < tphMeth1 < tphMeth2
then we have to convert tphMeth1, tphMeth2 to tph class and generate the following
class constraints: tphClass < tphMeth1, tphMeth1 < tphMeth2, tphMeth2 < Object
*/
public static GenericsGeneratorResultForClass generateConstraints(final String className, final TPHExtractor tphExtractor,
final List<String> tphsClass, final ConstraintsSimplierResult simplifiedConstraints) {
List<GenericsGeneratorResult> classConstraints = generateConstraintsForClass(tphExtractor,
simplifiedConstraints, tphsClass);
// GenericGeneratorResultsForAllMethods methodsAndConstraints = generateConstraintsForAllMethods(tphExtractor,
// simplifiedConstraints, tphsClass);
GenericGeneratorResultsForAllMethods methodsAndConstraints = new GenericGeneratorResultsForAllMethods(new ArrayList<>());
return new GenericsGeneratorResultForClass(className, classConstraints, methodsAndConstraints);
}
/**
* @param tphExtractor
* @param tphsClass
* @return
*/
public static ConstraintsSimplierResult simplifyConstraints(final TPHExtractor tphExtractor,
final List<String> tphsClass) {
final List<GenericsGeneratorResult> genericsGeneratorResults = new ArrayList<>();
ConstraintsSimplierResult simplifiedConstraints = ConstraintsSimplifier.simplifyConstraints(tphExtractor,
genericsGeneratorResults, tphsClass);
return simplifiedConstraints;
}
private static List<GenericsGeneratorResult> generateConstraintsForClass(final TPHExtractor tphExtractor,
final ConstraintsSimplierResult simplifiedConstraints, final List<String> tphsClass) {
final List<GenericsGeneratorResult> constraints = new ArrayList<>();
if (tphsClass.isEmpty())
return constraints;
final List<TPHConstraint> allCons = tphExtractor.allCons;
final Set<String> visitedTPHs = new HashSet<>();
final List<String> methodTPHs = tphExtractor.ListOfMethodsAndTph.stream().map(m -> m.getLocalTphs())
.flatMap(l -> l.stream()).collect(Collectors.toList());
createConstraintsForClassTphs(simplifiedConstraints, tphsClass, constraints, allCons, visitedTPHs, methodTPHs);
GenericsGeneratorUtility.addTPHsToClassTPHs(constraints, tphsClass);
GenericsGeneratorUtility.removeClassTPHsFromMethodTPHs(tphsClass, tphExtractor);
generateGGConstraintsForTPH(tphsClass, constraints, simplifiedConstraints);
return constraints;
}
private static void createConstraintsForClassTphs(ConstraintsSimplierResult simplifiedConstraints, List<String> tphsClass, List<GenericsGeneratorResult> constraints, List<TPHConstraint> allCons, Set<String> visitedTPHs, List<String> methodTPHs) {
List<String> classAndMethodTphs = new ArrayList<>(tphsClass);
classAndMethodTphs.addAll(methodTPHs);
for (String tph : tphsClass) {
if (visitedTPHs.contains(tph))
continue;
final LinkedList<String> tphsInRel = GenericsGeneratorUtility
.createLinkedListForTPHsInRelationClass(allCons, tphsClass, methodTPHs, visitedTPHs, tph);
generateConstraintsForClassFromList(tphsInRel,simplifiedConstraints,classAndMethodTphs,constraints);
}
}
private static void generateConstraintsForClassFromList(LinkedList<String> tphsInRel, ConstraintsSimplierResult simplifiedConstraints, List<String> classAndMethodTphs, List<GenericsGeneratorResult> constraints) {
if(tphsInRel.isEmpty())
return;
List<GenericsGeneratorResult> resultConstraints = new ArrayList<>();
String subType = tphsInRel.getFirst();
String superType = GenericsGeneratorUtility.getNextClassTph(classAndMethodTphs, tphsInRel);
int idxOfSuper = tphsInRel.indexOf(superType);
int size = tphsInRel.size();
while (size > 2 && idxOfSuper < size-1){
GenericsGeneratorResult genericsGeneratorResult = getGenericsGeneratorResultForClass(simplifiedConstraints, subType, superType);
constraints.add(genericsGeneratorResult);
tphsInRel = new LinkedList<>(tphsInRel.subList(idxOfSuper, size));
subType = tphsInRel.getFirst();
superType = GenericsGeneratorUtility.getNextClassTph(classAndMethodTphs, tphsInRel);
idxOfSuper = tphsInRel.indexOf(superType);
size = tphsInRel.size();
}
GenericsGeneratorResult genericsGeneratorResult = getGenericsGeneratorResultForClass(simplifiedConstraints, subType, superType);
constraints.add(genericsGeneratorResult);
}
private static GenericsGeneratorResult getGenericsGeneratorResultForClass(ConstraintsSimplierResult simplifiedConstraints, String subType, String superType) {
TPHConstraint constraint = new ExtendsConstraint(subType, superType);
Set<String> equalSet = GenericsGeneratorUtility
.createEqualSet(simplifiedConstraints.getNameReplacementResults(), subType);
return new GenericsGeneratorResult(constraint, equalSet);
}
/* TODO Remove this methoda*/
private static GenericsGeneratorResult generateGGResultForClass(LinkedList<String> tphsInRel,
ConstraintsSimplierResult simplifiedConstraints, List<String> tphsClass) {
String subType = tphsInRel.getFirst();
String superType = GenericsGeneratorUtility.getNextClassTph(tphsClass, tphsInRel);
TPHConstraint constraint = new ExtendsConstraint(subType, superType);
Set<String> equalSet = GenericsGeneratorUtility
.createEqualSet(simplifiedConstraints.getNameReplacementResults(), subType);
return new GenericsGeneratorResult(constraint, equalSet);
}
private static GenericGeneratorResultsForAllMethods generateConstraintsForAllMethods(
final TPHExtractor tphExtractor, ConstraintsSimplierResult simplifiedConstraints, List<String> tphsClass) {
final List<MethodAndConstraints> methodsAndConstraints = new ArrayList<>();
final GenericGeneratorResultsForAllMethods results = new GenericGeneratorResultsForAllMethods(
methodsAndConstraints);
tphExtractor.ListOfMethodsAndTph.forEach(m -> {
MethodAndConstraints methAndCons = generateConstraintsForMethod(tphExtractor.allCons, m,
simplifiedConstraints, tphsClass);
methodsAndConstraints.add(methAndCons);
});
return results;
}
public static MethodAndConstraints generateConstraintsForMethod(final List<TPHConstraint> allCons,
final MethodAndTPH m, final ConstraintsSimplierResult simplifiedConstraints, List<String> tphsClass) {
final List<String> localTphs = m.getLocalTphs();
List<GenericsGeneratorResult> constraints = new ArrayList<>();
MethodAndConstraints result = new MethodAndConstraints(m.getId(), constraints);
if (localTphs.isEmpty())
return result;
if (localTphs.size() == 1 && tphsClass.isEmpty()) {
generateGGConstraintsForTPH(localTphs, constraints, simplifiedConstraints);
return result;
}
final Set<String> visitedTPHs = new HashSet<>();
for (String tph : localTphs) {
if (visitedTPHs.contains(tph))
continue;
final LinkedList<String> tphsInRel = GenericsGeneratorUtility.createLinkedListForTPHsInRelation(allCons,
localTphs, tphsClass, visitedTPHs, tph);
if (!tphsInRel.isEmpty()) {
GenericsGeneratorUtility.removeNotLocalTphs(tphsInRel, localTphs, tphsClass);
if (!GenericsGeneratorUtility.isInResult(tphsInRel.getFirst(), constraints)) {
GenericsGeneratorResult constraint = generateGGResult(tphsInRel, simplifiedConstraints);
constraints.add(constraint);
}
}
}
generateGGConstraintsForTPH(localTphs, constraints, simplifiedConstraints);
return result;
}
private static void generateGGConstraintsForTPH(List<String> localTphs,
final List<GenericsGeneratorResult> constraints, final ConstraintsSimplierResult simplifiedConstraints) {
localTphs.forEach(tph -> {
boolean isInSimplifiedConstraints = GenericsGeneratorUtility.isTPHInGenericGeneratorResult(simplifiedConstraints.getGenericsGenResults(), tph);
if (isInSimplifiedConstraints) {
GenericsGeneratorResult ggResult = GenericsGeneratorUtility.getGenericGeneratorResult(simplifiedConstraints.getGenericsGenResults(), tph).get();
// GenericsGeneratorUtility.removeGenericGeneratorResult(simplifiedConstraints.getGenericsGenResults(),ggResult);
constraints.add(ggResult);
} else {
boolean isInConstraints = GenericsGeneratorUtility.isTPHInGenericGeneratorResult(constraints, tph);
if (!isInConstraints) {
GenericsGeneratorResult ggResult = generateGGResult(tph, simplifiedConstraints.getNameReplacementResults());
constraints.add(ggResult);
}
}
});
}
private static GenericsGeneratorResult generateGGResult(String tph,
List<NameReplacementResult> nameReplacementResults) {
String superType = Type.getInternalName(Object.class);
TPHConstraint constraint = new ExtendsConstraint(tph, superType);
Set<String> equalSet = GenericsGeneratorUtility.createEqualSet(nameReplacementResults, tph);
return new GenericsGeneratorResult(constraint, equalSet);
}
private static GenericsGeneratorResult generateGGResult(final LinkedList<String> tphsInRel,
final ConstraintsSimplierResult simplifiedConstraints) {
String subType = tphsInRel.getFirst();
if (tphsInRel.size() == 1) {
Optional<GenericsGeneratorResult> constraintFromSimplifiedCon = simplifiedConstraints
.getGenericsGenResults().stream().filter(g -> g.getConstraint().getLeft().equals(subType))
.findFirst();
if (constraintFromSimplifiedCon.isPresent())
return constraintFromSimplifiedCon.get();
}
String superType = tphsInRel.size() > 1 ? tphsInRel.getLast() : Type.getInternalName(Object.class);
TPHConstraint constraint = new ExtendsConstraint(subType, superType);
Set<String> equalSet = GenericsGeneratorUtility
.createEqualSet(simplifiedConstraints.getNameReplacementResults(), subType);
return new GenericsGeneratorResult(constraint, equalSet);
}
}

View File

@@ -0,0 +1,571 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGenerator;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.*;
import org.objectweb.asm.Type;
import de.dhbwstuttgart.bytecode.TPHExtractor;
import de.dhbwstuttgart.bytecode.constraint.EqualConstraint;
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.utilities.ConstraintsFinder;
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
import de.dhbwstuttgart.bytecode.utilities.NameReplacer;
/**
* @author fayez
*
*/
public class GenericsGeneratorUtility {
/**
* Returns a list of type placeholders names of a specified method
*
* @param methodID The id of the method ReturnTypeMethodName(ParameterTypes)
* @param listOfMethodsAndTph List of all methods
* @return a list of type placehoders names
*/
public static List<String> getMethodTPHS(String methodID, ArrayList<MethodAndTPH> listOfMethodsAndTph) {
return listOfMethodsAndTph.stream().filter(mt->mt.getId().equals(methodID)).findAny().get().getTphs();
}
/**
* Returns a reverse constraint of a specified constraint which is given by its left and right
* side
*
* @param allCons List of all constraints
* @param left The left side of the given constraint
* @param right The right side of the given constraint
* @return An Optional object which contains the reverse constraint if it is exist
*/
public static Optional<TPHConstraint> getReverseConstraint(List<TPHConstraint> allCons, String left, String right) {
return allCons.stream().filter(c->{
return c.getRight().equals(left) && c.getLeft().equals(right);
}).findAny();
}
/**
* Substitutes the old name by the new name in all constraints
*
* @param allCons List of all constraints
* @param oldName The name to be replaced
* @param newName The new name
*/
public static void substituteTPH(List<TPHConstraint> allCons, String oldName, String newName) {
allCons.stream()
.filter(c->c.getRel()==Relation.EXTENDS)
.forEach(c->{
if(c.getLeft().equals(oldName))
c.setLeft(newName);
if(c.getRight().equals(oldName))
c.setRight(newName);
});
}
public static List<ConstraintsWithSameLeftSide> findConstraintsWithLeftSameLeftSide(List<TPHConstraint> allCons) {
// finder looks for constraints that have the same left hand side
// and put them in a list
ConstraintsFinder finder = new ConstraintsFinder(allCons);
List<ConstraintsWithSameLeftSide> foundCons = finder.findConstraints();
return foundCons;
}
public static void simplifyConstraintsWithSameLeftSide(List<ConstraintsWithSameLeftSide> consWithSameLeftSide,
List<TPHConstraint> allCons, List<String> methodTPHS) {
List<TPHConstraint> eqCons = new ArrayList<>();
for (ConstraintsWithSameLeftSide list : consWithSameLeftSide) {
NameReplacementResult replRes = modifyNames(allCons, methodTPHS, list);
createEqualConstraintsForNames(replRes.getName(), replRes.getOldNames(),eqCons);
for (TPHConstraint c : allCons) {
if (c.getRel() == Relation.EQUAL && replRes.getName().equals(c.getRight())) {
eqCons.add(c);
}
}
updateEqualCons(replRes, eqCons);
TPHConstraint c = list.getConstraints().get(0);
allCons.removeAll(list.getConstraints());
allCons.add(c);
}
}
public static void simplifyConstraintsWithSameLeftSide(List<ConstraintsWithSameLeftSide> consWithSameLeftSide,
TPHExtractor tphExtractor, List<String> tphsClass, List<TPHConstraint> equalCons) {
List<TPHConstraint> allCons = tphExtractor.allCons;
for (ConstraintsWithSameLeftSide list : consWithSameLeftSide) {
if(!stillWithSameLeftSide(list))
continue;
NameReplacementResult replRes = modifyNames(allCons, list, tphExtractor.ListOfMethodsAndTph,tphsClass);
createEqualConstraintsForNames(replRes.getName(), replRes.getOldNames(),equalCons);
for (TPHConstraint c : allCons) {
if (c.getRel() == Relation.EQUAL && replRes.getName().equals(c.getRight())) {
equalCons.add(c);
}
}
updateEqualCons(replRes, equalCons);
TPHConstraint c = list.getConstraints().get(0);
allCons.removeAll(list.getConstraints());
removeConstraintsWithSameLeftAndRightSide(allCons);
allCons.add(c);
removeDuplicate(allCons);
}
consWithSameLeftSide.clear();
consWithSameLeftSide = findConstraintsWithLeftSameLeftSide(allCons);
if(!consWithSameLeftSide.isEmpty())
simplifyConstraintsWithSameLeftSide(consWithSameLeftSide,tphExtractor,tphsClass,equalCons);
}
private static void removeDuplicate(List<TPHConstraint> allCons) {
List<TPHConstraint> visited = new ArrayList<>();
List<Integer> toRemove = new ArrayList<>();
checkForDuplicate(allCons, visited, toRemove);
removeConstraintsByIndex(allCons, toRemove);
}
private static void removeConstraintsByIndex(List<TPHConstraint> allCons, List<Integer> toRemove) {
for(int index : toRemove)
allCons.remove(index);
}
private static void checkForDuplicate(List<TPHConstraint> allCons, List<TPHConstraint> visited, List<Integer> toRemove) {
for(int i = 0;i<allCons.size();++i){
markConstraintIfDuplicate(allCons, visited, toRemove, i);
}
}
private static void markConstraintIfDuplicate(List<TPHConstraint> allCons, List<TPHConstraint> visited, List<Integer> toRemove, int i) {
TPHConstraint constraint = allCons.get(i);
if(containsInList(visited,constraint.getLeft(),constraint.getRight())){
toRemove.add(i);
} else {
visited.add(constraint);
}
}
private static boolean containsInList(List<TPHConstraint> allConstraints, String left, String right) {
for(TPHConstraint constraint : allConstraints)
if(constraint.getLeft().equals(left) && constraint.getRight().equals(right))
return true;
return false;
}
private static void addNewConstraintsWithSameLeftSide(ConstraintsWithSameLeftSide constraintsWithSameLeftSide, List<TPHConstraint> allCons) {
allCons.forEach(c->{
if (constraintsWithSameLeftSide.getConstraints().get(0).getLeft().equals(c.getLeft())){
if(!constraintsWithSameLeftSide.getConstraints().contains(c))
constraintsWithSameLeftSide.getConstraints().add(c);
}
});
}
private static void checkForNewConstraintsWithSameLeftSide(List<ConstraintsWithSameLeftSide> consWithSameLeftSide, List<TPHConstraint> allCons) {
allCons.forEach(c->{
Optional<ConstraintsWithSameLeftSide> constraintsWithSameLeftSide = getConstraintsWithSameLeftSide(consWithSameLeftSide, c.getLeft());
constraintsWithSameLeftSide.ifPresent(cls->{
if(!cls.getConstraints().contains(c))
cls.getConstraints().add(c);
});
});
}
private static Optional<ConstraintsWithSameLeftSide> getConstraintsWithSameLeftSide(List<ConstraintsWithSameLeftSide> consWithSameLeftSide, String left) {
return consWithSameLeftSide.stream().filter(csl->isContainedInConsWithLeftSide(csl,left)).findAny();
}
private static boolean isContainedInConsWithLeftSide(ConstraintsWithSameLeftSide csl, String left) {
return csl.getConstraints().get(0).getLeft().equals(left);
}
private static boolean stillWithSameLeftSide(ConstraintsWithSameLeftSide constraints) {
removeUnvalidConstraints(constraints);
return constraints.getConstraints().size()>1;
}
private static void removeUnvalidConstraints(ConstraintsWithSameLeftSide constraints) {
List<TPHConstraint> toRemove = new ArrayList<>();
constraints.getConstraints().forEach(c->{
if(c.getLeft().equals(c.getRight()))
toRemove.add(c);
});
if(!toRemove.isEmpty())
constraints.getConstraints().removeAll(toRemove);
}
private static void removeConstraintsWithSameLeftAndRightSide(List<TPHConstraint> allCons) {
List<TPHConstraint> toRemove = new ArrayList<>();
allCons.forEach(c->{
if(c.getLeft().equals(c.getRight()))
toRemove.add(c);
});
allCons.removeAll(toRemove);
}
private static void createEqualConstraintsForNames(String name, List<String> equalNames, List<TPHConstraint> eqCons) {
// create an equal constraint for each value in repres
for (String eName : equalNames) {
EqualConstraint ec = new EqualConstraint(eName, name);
eqCons.add(ec);
}
}
/**
* @param allCons
* @param methodTPHS
* @param list
* @return
*/
public static NameReplacementResult modifyNames(List<TPHConstraint> allCons, List<String> methodTPHS,
ConstraintsWithSameLeftSide list) {
// generate a new name and replace the right hand side for each constraint
// in list with the new name
NameReplacer replacer = new NameReplacer(list.getConstraints(), allCons, methodTPHS);
// new name -> [all old names]
NameReplacementResult replRes = replacer.replaceNames();
return replRes;
}
public static NameReplacementResult modifyNames(List<TPHConstraint> allCons, ConstraintsWithSameLeftSide list, List<MethodAndTPH> methodAndTPHs, List<String> tphsClass) {
// generate a new name and replace the right hand side for each constraint
// in list with the new name
NameReplacer replacer = new NameReplacer(list.getConstraints(), allCons, methodAndTPHs, tphsClass);
// new name -> [all old names]
NameReplacementResult replRes = replacer.replaceNames();
return replRes;
}
public static void updateEqualCons(NameReplacementResult nameReplacementResult, List<TPHConstraint> eqCons) {
List<String> oldNames = nameReplacementResult.getOldNames();
String newName = nameReplacementResult.getName();
for (TPHConstraint c : eqCons) {
// if(oldNames.contains(c.getLeft()))
// c.setLeft(newName);
if (oldNames.contains(c.getRight()))
c.setRight(newName);
}
}
public static void modifyRelationForConstraintsInCycle(List<Cycle> cycles) {
cycles.stream().map(lc->lc.getConstraints()).flatMap(e->e.stream()).forEach(c->c.setRel(Relation.EQUAL));
}
public static List<NameReplacementResult> substituteTPHSFormCycle(List<TPHConstraint> allCons, List<Cycle> cycles, TPHExtractor tphExtractor) {
List<NameReplacementResult> results = new ArrayList<>();
cycles.forEach(lc->{
Set<String> names = getNamesFromCycle(lc);
String newName = names.stream().findFirst().get();
List<String> equalNames = new ArrayList<>(names);
Stream<ArrayList<String>> tphsOfMethods = tphExtractor.ListOfMethodsAndTph.stream().map(m->m.getTphs());
Stream<ArrayList<String>> localTphsOfMethods = tphExtractor.ListOfMethodsAndTph.stream().map(m->m.getLocalTphs());
replaceOldNames(newName, equalNames, tphsOfMethods);
replaceOldNames(newName, equalNames, localTphsOfMethods);
NameReplacementResult res = new NameReplacementResult(newName, equalNames);
results.add(res);
substituteAll(allCons,names,newName);
});
return results;
}
/**
* @param newName
* @param names
* @param tphsOfMethods
*/
public static void replaceOldNames(final String newName, final List<String> names, Stream<ArrayList<String>> tphsOfMethods) {
tphsOfMethods.forEach(tphsMethod->{
if(tphsMethod.removeAll(names))
tphsMethod.add(newName);
});
}
public static void substituteAll(List<TPHConstraint> allCons, Set<String> names, String newName) {
allCons.stream()
.filter(c-> c.getRel()==Relation.EXTENDS)
.forEach(c->{
if(names.contains(c.getLeft())) {
c.setLeft(newName);
} else if(names.contains(c.getRight())) {
c.setRight(newName);
}
});
}
public static Set<String> getNamesFromCycle(Cycle lc) {
Set<String> names = new HashSet<>();
lc.getConstraints().forEach(c->names.add(c.getLeft()));
return names;
}
public static void createResults(List<GenericsGeneratorResult> genericsGeneratorResults,
List<NameReplacementResult> nameReplacementResults) {
nameReplacementResults.forEach(n->{
Set<String> equals = new HashSet<>(n.getOldNames());
TPHConstraint cons = new ExtendsConstraint(n.getName(), Type.getInternalName(Object.class));
GenericsGeneratorResult ggRes = new GenericsGeneratorResult(cons, equals);
genericsGeneratorResults.add(ggRes);
});
}
public static void removeEqualConstraints(List<TPHConstraint> allCons) {
List<TPHConstraint> equalConstraints = getEqualConstraints(allCons);
allCons.removeAll(equalConstraints);
}
public static List<TPHConstraint> getEqualConstraints(List<TPHConstraint> allCons) {
return allCons.stream().filter(c->c.getRel()==Relation.EQUAL).collect(Collectors.toList());
}
public static List<NameReplacementResult> createNameReplacementResultsFromEqualConstraints(
List<TPHConstraint> equalCons) {
List<NameReplacementResult> nameReplacementResults = new ArrayList<>();
equalCons.forEach(c->{
if(isInNameReplacementResults(nameReplacementResults,c.getRight())) {
getNameReplacementByName(nameReplacementResults,c.getRight()).getOldNames().add(c.getLeft());
} else {
List<String> oldNames = new ArrayList<>();
oldNames.add(c.getLeft());
NameReplacementResult nrRes = new NameReplacementResult(c.getRight(), oldNames);
nameReplacementResults.add(nrRes);
}
});
return nameReplacementResults;
}
private static NameReplacementResult getNameReplacementByName(List<NameReplacementResult> nameReplacementResults,
String name) {
return nameReplacementResults.stream().filter(n->n.getName().equals(name)).findFirst().get();
}
public static boolean isInNameReplacementResults(List<NameReplacementResult> nameReplacementResults,String name){
if(nameReplacementResults.isEmpty())
return false;
return nameReplacementResults.stream().map(r->r.getName()).filter(n->name.equals(n)).findFirst().isPresent();
}
public static Optional<TPHConstraint> getConstraintByLeftSide(List<TPHConstraint> allCons, String tph) {
return allCons.stream().filter(c->c.getLeft().equals(tph)).findFirst();
}
public static Optional<TPHConstraint> getConstraintByRightSide(List<TPHConstraint> allCons, String tph) {
return allCons.stream().filter(c->c.getRight().equals(tph)).findFirst();
}
public static boolean isTPHInGenericGeneratorResult(final List<GenericsGeneratorResult> constraints, final String tph) {
return constraints.stream().filter(g->g.getConstraint().getLeft().equals(tph)).findFirst().isPresent();
}
/**
* @param allCons
* @param tphsMethod
* @param tphsClass
* @param visitedTPHs
* @param tph
* @return
*/
public static LinkedList<String> createLinkedListForTPHsInRelation(final List<TPHConstraint> allCons,
List<String> tphsMethod, List<String> tphsClass, final Set<String> visitedTPHs, String tph) {
final LinkedList<String> tphsInRel = new LinkedList<>();
List<String> tphsList = new ArrayList<>(tphsMethod);
tphsList.addAll(tphsClass);
boolean isNextSuperTypeFound = findNextSuperTyp(allCons,tphsList ,visitedTPHs, tph, tphsInRel);
if(!isNextSuperTypeFound)
findNextSubType(allCons, tphsList,visitedTPHs, tph, tphsInRel);
return tphsInRel;
}
public static boolean findNextSubType(List<TPHConstraint> allCons, List<String> tphsList, Set<String> visitedTPHs, String tph,
LinkedList<String> tphsInRel) {
Optional<TPHConstraint> con = getConstraintByRightSide(allCons, tph);
while (con.isPresent()) {
String left = con.get().getLeft();
String right = con.get().getRight();
addTPHsToListFromLeft(tphsInRel, left, right);
markAsVisited(visitedTPHs, left);
if(tphsList.contains(left))
return true;
con = getConstraintByRightSide(allCons, left);
}
return false;
}
public static void addTPHsToListFromLeft(LinkedList<String> tphsInRel, String left, String right) {
if (tphsInRel.isEmpty())
tphsInRel.add(right);
tphsInRel.addFirst(left);
}
/**
* @param allCons
* @param tphsList
* @param visitedTPHs
* @param tph
* @param tphsInRel
* @return
*/
public static boolean findNextSuperTyp(final List<TPHConstraint> allCons, List<String> tphsList, final Set<String> visitedTPHs, String tph,
final LinkedList<String> tphsInRel) {
Optional<TPHConstraint> con = getConstraintByLeftSide(allCons, tph);
markAsVisited(visitedTPHs, tph);
while (con.isPresent()) {
String left = con.get().getLeft();
String right = con.get().getRight();
addTPHsToList(tphsInRel, left, right);
if(tphsList.contains(right))
return true;
markAsVisited(visitedTPHs, right);
con = getConstraintByLeftSide(allCons, right);
}
return false;
}
public static void markAsVisited(Set<String> visitedTPHs, String left) {
visitedTPHs.add(left);
}
/**
* @param visitedTPHs
* @param right
* @param left
*/
public static void markAsVisited(final Set<String> visitedTPHs, String left, String right) {
visitedTPHs.add(left);
visitedTPHs.add(right);
}
/**
* @param tphsInRel
* @param right
* @param left
*/
public static void addTPHsToList(final LinkedList<String> tphsInRel, String left, String right) {
if (tphsInRel.isEmpty())
tphsInRel.add(left);
tphsInRel.add(right);
}
public static void removeNotLocalTphs(final LinkedList<String> tphsInRel, final List<String> localTphs,
List<String> tphsClass) {
while (!localTphs.contains(tphsInRel.peek())) {
tphsInRel.removeFirst();
}
String last = tphsInRel.peekLast();
while (!localTphs.contains(last) && !tphsClass.contains(last)) {
tphsInRel.removeLast();
last = tphsInRel.peekLast();
}
}
/**
* @param nameReplacementResults
* @param subType
* @return
*/
public static Set<String> createEqualSet(final List<NameReplacementResult> nameReplacementResults, String subType) {
Optional<NameReplacementResult> equals = nameReplacementResults.stream()
.filter(n -> n.getName().equals(subType)).findFirst();
Set<String> equalSet = equals.isPresent() ? new HashSet<>(equals.get().getOldNames()) : new HashSet<>();
return equalSet;
}
public static String getNextClassTph(List<String> tphsClass, LinkedList<String> tphsInRel) {
for(int i = 1;i<tphsInRel.size();++i) {
String next = tphsInRel.get(i);
if(tphsClass.contains(next))
return next;
}
return tphsInRel.getLast();
}
public static void addTPHsToClassTPHs(final List<GenericsGeneratorResult> constraints, final List<String> tphsClass) {
List<String> lefts = constraints.stream().map(r->r.getConstraint()).map(c->c.getLeft()).collect(Collectors.toList());
List<String> rights = constraints.stream().map(r->r.getConstraint()).map(c->c.getRight()).collect(Collectors.toList());
List<String> leftsAndRights = new ArrayList<>(lefts);
leftsAndRights.addAll(rights);
List<String> shouldBeClassTphs = leftsAndRights.stream().distinct().collect(Collectors.toList());
for(String tph : shouldBeClassTphs) {
if(!tphsClass.contains(tph))
tphsClass.add(tph);
}
}
public static void removeClassTPHsFromMethodTPHs(List<String> tphsClass, TPHExtractor tphExtractor) {
tphExtractor.ListOfMethodsAndTph.stream().map(m->m.getTphs()).forEach(tphs->{
tphs.removeAll(tphsClass);
});
tphExtractor.ListOfMethodsAndTph.stream().map(m->m.getLocalTphs()).forEach(tphs->{
tphs.removeAll(tphsClass);
});
}
public static LinkedList<String> createLinkedListForTPHsInRelationClass(List<TPHConstraint> allCons,
List<String> tphsClass, List<String> methodTPHs, Set<String> visitedTPHs, String tph) {
final LinkedList<String> tphsInRel = new LinkedList<>();
boolean isNextSuperTypeFound = findNextSuperTyp(allCons,tphsClass ,visitedTPHs, tph, tphsInRel);
if(!tphsInRel.isEmpty() && !isNextSuperTypeFound && !methodTPHs.contains(tphsInRel.getLast()))
findNextSubType(allCons, tphsClass,visitedTPHs, tph, tphsInRel);
return tphsInRel;
}
public static boolean isInResult(String first, List<GenericsGeneratorResult> constraints) {
return constraints.stream().map(r->r.getConstraint()).filter(c->c.getLeft().equals(first)).findFirst().isPresent();
}
public static Optional<GenericsGeneratorResult> getGenericGeneratorResult(List<GenericsGeneratorResult> list,
String tph) {
return list.stream().filter(g->g.getConstraint().getLeft().equals(tph)).findFirst();
}
public static void removeGenericGeneratorResult(List<GenericsGeneratorResult> genericsGenResults,
GenericsGeneratorResult ggResult) {
genericsGenResults.remove(ggResult);
}
public static Optional<MethodAndTPH> getMethodAndTphs(ArrayList<MethodAndTPH> listOfMethodsAndTph, String id) {
return listOfMethodsAndTph.stream().filter(m->m.getId().equals(id)).findFirst();
}
}

View File

@@ -0,0 +1,35 @@
package de.dhbwstuttgart.bytecode.genericsGeneratorTypes;
import java.util.List;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
public class ConstraintsWithSameLeftSide {
private List<TPHConstraint> constraints;
/**
* @param constraints
*/
public ConstraintsWithSameLeftSide(List<TPHConstraint> constraints) {
this.constraints = constraints;
}
/**
* @return the constraints
*/
public List<TPHConstraint> getConstraints() {
return constraints;
}
/**
* @param constraints the constraints to set
*/
public void setConstraints(List<TPHConstraint> constraints) {
this.constraints = constraints;
}
@Override
public String toString() {
return "[" + constraints.toString() + "]";
}
}

View File

@@ -0,0 +1,46 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGeneratorTypes;
import java.util.List;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
/**
* @author fayez
*
*/
public class Cycle {
private final List<TPHConstraint> constraints;
/**
* @param constraints
*/
public Cycle(List<TPHConstraint> constraints) {
this.constraints = constraints;
}
/**
* @return the constraints
*/
public List<TPHConstraint> getConstraints() {
return constraints;
}
public boolean containConstraint(TPHConstraint constraint) {
for(TPHConstraint c : constraints) {
if(c.equalConstraint(constraint))
return true;
}
return false;
}
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
constraints.forEach(c->sb.append(c.getLeft()+" -> "));
sb.append(constraints.get(constraints.size()-1).getRight());
return sb.toString();
}
}

View File

@@ -0,0 +1,33 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGeneratorTypes;
import java.util.Collections;
import java.util.List;
/**
* @author fayez
*
*/
public class GenericGeneratorResultsForAllMethods {
private final List<MethodAndConstraints> methodsAndConstraints;
public GenericGeneratorResultsForAllMethods() {
this(Collections.emptyList());
}
/**
* @param methodsAndConstraints
*/
public GenericGeneratorResultsForAllMethods(List<MethodAndConstraints> methodsAndConstraints) {
this.methodsAndConstraints = methodsAndConstraints;
}
/**
* @return the methodsAndConstraints
*/
public List<MethodAndConstraints> getMethodsAndConstraints() {
return methodsAndConstraints;
}
}

View File

@@ -0,0 +1,51 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGeneratorTypes;
import java.util.ArrayList;
import java.util.List;
import java.util.NoSuchElementException;
/**
* The simplify results of a source file (package)
*
* @author fayez
*
*/
public class GenericGenratorResultForSourceFile {
private String pkgName;
private final List<GenericsGeneratorResultForClass> genericGeneratorResultForAllClasses = new ArrayList<>();
/**
* @param pkgName
*/
public GenericGenratorResultForSourceFile(String pkgName) {
this.pkgName = pkgName;
}
public List<GenericsGeneratorResultForClass> getGenericGeneratorResultForAllClasses() {
return genericGeneratorResultForAllClasses;
}
/**
* Appends the simplify results of a class to simplifyResForSF
*
* @param sResClass simplify results of a class to added
*/
public void addGenericGeneratorResultClass(GenericsGeneratorResultForClass sResClass) {
genericGeneratorResultForAllClasses.add(sResClass);
}
public GenericsGeneratorResultForClass getSimplifyResultsByName(String pkgName, String name) {
if (this.pkgName.equals(pkgName)) {
return genericGeneratorResultForAllClasses.stream()
.filter(sr -> sr.getClassName().equals(name))
.findAny()
.orElseThrow(() -> new NoSuchElementException(
"Simplify results for the class " + pkgName + "." + name + " are not found"));
}
throw new NoSuchElementException("Simplify results for the class " + pkgName + "." + name + " are not found");
}
}

View File

@@ -0,0 +1,55 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGeneratorTypes;
import java.util.Set;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
/**
* @author fayez
*
*/
public class GenericsGeneratorResult {
private TPHConstraint constraint;
/**
* contains the names of all type placeholders which are equals to the left side of
* the constraint {@link #constraint}.
*/
private Set<String> equalsTPHs;
/**
* @param constraint
* @param equalsTPHs
*/
public GenericsGeneratorResult(TPHConstraint constraint, Set<String> equalsTPHs) {
this.constraint = constraint;
this.equalsTPHs = equalsTPHs;
}
/**
* @return the constraint
*/
public TPHConstraint getConstraint() {
return constraint;
}
/**
* @param constraint the constraint to set
*/
public void setConstraint(TPHConstraint constraint) {
this.constraint = constraint;
}
/**
* @return the equalsTPHs
*/
public Set<String> getEqualsTPHs() {
return equalsTPHs;
}
/**
* @param equalsTPHs the equalsTPHs to set
*/
public void setEqualsTPHs(Set<String> equalsTPHs) {
this.equalsTPHs = equalsTPHs;
}
}

View File

@@ -0,0 +1,67 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGeneratorTypes;
import java.util.Collections;
import java.util.List;
/**
* @author fayez
*
*/
public class GenericsGeneratorResultForClass {
private final String className;
private final List<GenericsGeneratorResult> classConstraints;
private final GenericGeneratorResultsForAllMethods methodsAndTheirConstraints;
public GenericsGeneratorResultForClass(String className) {
this(className, Collections.emptyList(), new GenericGeneratorResultsForAllMethods());
}
/**
* @param className
* @param classConstraints
* @param methodsAndTheirConstraints
*/
public GenericsGeneratorResultForClass(String className, List<GenericsGeneratorResult> classConstraints,
GenericGeneratorResultsForAllMethods methodsAndTheirConstraints) {
this.className = className;
this.classConstraints = classConstraints;
this.methodsAndTheirConstraints = methodsAndTheirConstraints;
}
/**
* @return the className
*/
public String getClassName() {
return className;
}
/**
* @return the classConstraints
*/
public List<GenericsGeneratorResult> getClassConstraints() {
return classConstraints;
}
/**
* @return the methodsAndTheirConstraints
*/
public GenericGeneratorResultsForAllMethods getMethodsAndTheirConstraints() {
return methodsAndTheirConstraints;
}
public boolean contains(String id) {
return methodsAndTheirConstraints.getMethodsAndConstraints().stream().map(mc -> mc.getMethodID())
.anyMatch(i -> i.equals(id));
}
public List<GenericsGeneratorResult> getMethodConstraintsByID(String id) {
return methodsAndTheirConstraints.getMethodsAndConstraints().stream().filter(mc -> mc.getMethodID().equals(id))
.findFirst().get().getConstraints();
}
}

View File

@@ -0,0 +1,36 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGeneratorTypes;
import java.util.List;
/**
* @author fayez
*
*/
public class MethodAndConstraints {
private final String methodID;
private final List<GenericsGeneratorResult> constraints;
/**
* @param methodID
* @param constraints
*/
public MethodAndConstraints(String methodID, List<GenericsGeneratorResult> constraints) {
this.methodID = methodID;
this.constraints = constraints;
}
/**
* @return the methodID
*/
public String getMethodID() {
return methodID;
}
/**
* @return the constraints
*/
public List<GenericsGeneratorResult> getConstraints() {
return constraints;
}
}

View File

@@ -0,0 +1,49 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.genericsGeneratorTypes;
import java.util.List;
/**
* @author fayez
*
*/
public class NameReplacementResult {
private String name;
private List<String> oldNames;
/**
* @param name
* @param oldNames
*/
public NameReplacementResult(String name, List<String> oldNames) {
this.name = name;
this.oldNames = oldNames;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
/**
* @return the oldNames
*/
public List<String> getOldNames() {
return oldNames;
}
/**
* @param oldNames the oldNames to set
*/
public void setOldNames(List<String> oldNames) {
this.oldNames = oldNames;
};
}

View File

@@ -1,93 +1,166 @@
package de.dhbwstuttgart.bytecode.signature; package de.dhbwstuttgart.bytecode.signature;
import java.util.ArrayList; import java.util.*;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureVisitor; import org.objectweb.asm.signature.SignatureVisitor;
import org.objectweb.asm.signature.SignatureWriter; import org.objectweb.asm.signature.SignatureWriter;
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor; import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
import de.dhbwstuttgart.bytecode.utilities.Simplify; import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.Constructor; import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType; import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.WildcardType;
import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
import de.dhbwstuttgart.typeinference.result.ResolvedType;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
public class Signature { public class Signature {
private static final char SUPER_CHAR = '-';
private static final char EXTENDS_CHAR = '+';
private static final String SPECIAL_CHAR_FOR_FUN = "$$";
private static final String SPECIAL_CHAR = "$";
private ClassOrInterface classOrInterface; private ClassOrInterface classOrInterface;
private HashMap<String, String> genericsAndBounds; private HashMap<String, String> genericsAndBounds;
private HashMap<String, String> genericsAndBoundsMethod; private HashMap<String, String> genericsAndBoundsMethod;
private SignatureWriter sw; private final SignatureWriter sw = new SignatureWriter();;
private Constructor constructor; private Constructor constructor;
private Method method; private Method method;
private HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes; private HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes;
private ResultSet resultSet; private ResultSet resultSet;
private ArrayList<GenericInsertPair> commonPairs; private Map<TPHConstraint, Set<String>> methodConstraints;
private HashMap<TPHConstraint,HashSet<String>> methodConstraints; private List<GenericsGeneratorResult> consClass;
private ArrayList<TypePlaceholder> tphsClass; private List<GenericsGeneratorResult> constraints;
private ArrayList<TPHConstraint> consClass;
public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds, // public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds,
ArrayList<GenericInsertPair> commonPairs, ArrayList<TypePlaceholder> tphsClass, ArrayList<TPHConstraint> consClass) { // List<TPHConstraint> consClass) {
this.classOrInterface = classOrInterface; // this.classOrInterface = classOrInterface;
this.genericsAndBounds = genericsAndBounds; // this.genericsAndBounds = genericsAndBounds;
this.commonPairs = commonPairs; // this.consClass = consClass;
this.tphsClass = tphsClass; // sw = new SignatureWriter();
this.consClass = consClass; // createSignatureForClassOrInterface();
sw = new SignatureWriter(); // }
createSignatureForClassOrInterface();
}
public Signature(Constructor constructor, HashMap<String, String> genericsAndBounds, public Signature(HashMap<String, String> genericsAndBounds,
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes, ResultSet resultSet, HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes, ResultSet resultSet,
HashMap<TPHConstraint,HashSet<String>> methodConstraints) { List<GenericsGeneratorResult> constraints) {
this.constructor = constructor; //this.constructor = constructor;
this.genericsAndBounds = genericsAndBounds; this.genericsAndBounds = genericsAndBounds;
this.methodParamsAndTypes = methodParamsAndTypes; this.methodParamsAndTypes = methodParamsAndTypes;
this.resultSet = resultSet; this.resultSet = resultSet;
this.methodConstraints = methodConstraints; this.constraints = constraints;
sw = new SignatureWriter();
createSignatureForConsOrMethod(this.constructor,true);
} }
public Signature(Method method, HashMap<String, String> genericsAndBoundsMethod,HashMap<String, String> genericsAndBounds, public Signature(int numberOfParams) {
createSignatureForFunN(numberOfParams);
}
public Signature(int numberOfParams, String to, String[] paramTypes) {
createSignatureForFunN(numberOfParams, to, paramTypes);
}
public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds,
List<GenericsGeneratorResult> consClass) {
this.classOrInterface = classOrInterface;
this.genericsAndBounds = genericsAndBounds;
this.consClass = consClass;
}
public Signature(HashMap<String, String> genericsAndBoundsMethod,
HashMap<String, String> genericsAndBounds,
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes, ResultSet resultSet, HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes, ResultSet resultSet,
HashMap<TPHConstraint,HashSet<String>> methodConstraints) { List<GenericsGeneratorResult> constraints,List<GenericsGeneratorResult> consClass) {
this.method = method;
this.genericsAndBoundsMethod = genericsAndBoundsMethod; this.genericsAndBoundsMethod = genericsAndBoundsMethod;
this.genericsAndBounds = genericsAndBounds; this.genericsAndBounds = genericsAndBounds;
this.methodParamsAndTypes = methodParamsAndTypes; this.methodParamsAndTypes = methodParamsAndTypes;
this.resultSet = resultSet; this.resultSet = resultSet;
this.methodConstraints = methodConstraints; this.constraints = constraints;
sw = new SignatureWriter(); this.consClass = consClass;
createSignatureForConsOrMethod(this.method,false);
} }
public Signature(LambdaExpression lambdaExpression,int numberOfParams) { public String createSignatureForConstructor(Constructor constructor) {
sw = new SignatureWriter(); visitParams();
createSignatureForFunN(lambdaExpression, numberOfParams); sw.visitReturnType().visitBaseType('V');
return sw.toString();
} }
private void createSignatureForFunN(LambdaExpression lambdaExpression, int numberOfParams) { public String createSignatureForMethod(Method method) {
defineGenerics(method);
// sw.visitClassBound().visitEnd(); String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
visitParams();
visitReturnType(method, ret);
return sw.toString();
}
/**
* @param method
* @param ret
*/
private void visitReturnType(Method method, String ret) {
if (ret.equals("V")) {
sw.visitReturnType().visitBaseType('V');
} else {
RefTypeOrTPHOrWildcardOrGeneric returnType = method.getReturnType();
SignatureVisitor sv = sw.visitReturnType();
doVisitParamsOrReturn(returnType, sv);
}
}
/**
*
*/
private void visitParams() {
for (String paramName : methodParamsAndTypes.keySet()) {
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
SignatureVisitor sv = sw.visitParameterType();
doVisitParamsOrReturn(t, sv);
}
}
/**
*
* @param method
*/
private void defineGenerics(Method method) {
method.getGenerics().forEach(g -> {
visitTypeVarsAndTheirBounds(g, genericsAndBoundsMethod);
});
defineGenericsFromConstraints(constraints,genericsAndBoundsMethod);
}
private void createSignatureForFunN(int numberOfParams, String to, String[] paramTypes) {
defineTypeVariablesForParametersOfFunN(numberOfParams);
sw.visitFormalTypeParameter("R");
visitClassBound(to);
// TODO: prüfe ob Return-Type = void,
sw.visitSuperclass().visitClassType(Type.getInternalName(Object.class));
sw.visitEnd();
}
private void createSignatureForFunN(int numberOfParams) {
defineTypeVariablesForParametersOfFunN(numberOfParams);
sw.visitFormalTypeParameter("R");
// getBounds vom Return-Type
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
sw.visitClassBound().visitEnd();
// TODO: prüfe ob Return-Type = void,
sw.visitSuperclass().visitClassType(Type.getInternalName(Object.class));
sw.visitEnd();
}
private void defineTypeVariablesForParametersOfFunN(int numberOfParams) {
for (int i = 0; i < numberOfParams; i++) { for (int i = 0; i < numberOfParams; i++) {
int j = i + 1; int j = i + 1;
sw.visitFormalTypeParameter("T" + j); sw.visitFormalTypeParameter("T" + j);
@@ -95,375 +168,212 @@ public class Signature {
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class)); sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
sw.visitClassBound().visitEnd(); sw.visitClassBound().visitEnd();
} }
sw.visitFormalTypeParameter("R");
// getBounds vom Return-Type
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
sw.visitClassBound().visitEnd();
// TODO: prüfe ob Return-Type = void,
sw.visitSuperclass().visitClassType(Type.getInternalName(Object.class));;
sw.visitEnd();
}
/**
* Creates signature for a method or constructor with @see {@link SignatureWriter}
* Signature looks like:
* <typevaliables (K:Ljava/lang/Object "Bounds")>(params L.. OR T.. Or basistape)ReturnType
*
* @param method method or constructor
* @param isConstructor true if constructor
*/
private void createSignatureForConsOrMethod(Method method, boolean isConstructor) {
Iterator<? extends GenericTypeVar> itr = method.getGenerics().iterator();
// visits all formal type parameter and visits their bounds <T:...;B:...;...>
while(itr.hasNext()) {
System.out.println("HAS GENERICS!!");
GenericTypeVar g = itr.next();
getBoundsOfTypeVar(g,genericsAndBoundsMethod);
}
// Wenn die RückgabeType eine TPH ist, wird als generic behandelt
// z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object
if(!isConstructor) {
String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
ArrayList<TPHConstraint> allConsBeforeSimplify = new ArrayList<>();
HashMap<TPHConstraint,HashSet<String>> allConstraints = new HashMap<>();
if(ret.contains("<")) {
allConsBeforeSimplify = getAllConstraints((RefType) resultSet.resolveType(method.getReturnType()).resolvedType);
}
for(String paramName : methodParamsAndTypes.keySet()) {
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
String pT = t.acceptTV(new TypeToSignature());
if(pT.contains("<"))
allConsBeforeSimplify = getAllConstraints((RefType) t);
}
boolean doSimplify = false;
if(!allConsBeforeSimplify.isEmpty()) {
addConstraintsToMap(allConstraints,allConsBeforeSimplify);
doSimplify = true;
}
createTypeVars(allConstraints, doSimplify);
if(!ret.equals("V")) {
if(ret.contains("$") && !ret.contains("$$") && !ret.contains("<")) {
if(genericsAndBounds.containsKey(ret)) {
genericsAndBoundsMethod.put(ret.substring(1), genericsAndBounds.get(ret.substring(1)));
}
}
}
}
// visit each method-parameter to create the signature
for(String paramName : methodParamsAndTypes.keySet()) {
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
// parameter type deswegen ist true
doVisitParamsOrReturn(t,true);
}
if(isConstructor ||
resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature()).equals("V")) {
sw.visitReturnType().visitBaseType('V');
}else {
RefTypeOrTPHOrWildcardOrGeneric returnType = method.getReturnType();
// return type deswegen ist false
doVisitParamsOrReturn(returnType, false);
}
// sw.visitEnd();
}
private void addConstraintsToMap(HashMap<TPHConstraint, HashSet<String>> allConstraints,
ArrayList<TPHConstraint> allConsBeforeSimplify) {
for(TPHConstraint tphCons : allConsBeforeSimplify) {
allConstraints.put(tphCons, null);
}
}
private String getEqualTPH(HashMap<TPHConstraint, HashSet<String>> methodConstraints, String tph) {
for(TPHConstraint cons : methodConstraints.keySet()) {
if(methodConstraints.get(cons) != null) {
if(methodConstraints.get(cons).contains(tph)) {
return cons.getLeft();
}
}
}
return tph;
}
private void createTypeVars(HashMap<TPHConstraint, HashSet<String>> allConstraints, boolean doSimplify) {
allConstraints.putAll(methodConstraints);
HashMap<TPHConstraint, HashSet<String>> simplifiedConstraints;
if(doSimplify) {
simplifiedConstraints = Simplify.simplifyContraints(allConstraints);
}else {
simplifiedConstraints = allConstraints;
}
for(TPHConstraint cons : simplifiedConstraints.keySet()) {
// need subst.
String sub = cons.getLeft()+"$";
if(!genericsAndBoundsMethod.containsKey(sub) && !genericsAndBounds.containsKey(sub)) {
sw.visitFormalTypeParameter(sub);
String bound = cons.getRight();
if(bound.equals(Type.getInternalName(Object.class))) {
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
sw.visitClassBound().visitEnd();
genericsAndBoundsMethod.put(sub, bound);
} else {
String boundName = bound+"$";
sw.visitClassBound().visitTypeVariable(boundName);
genericsAndBoundsMethod.put(sub, boundName);
}
}
}
}
private ArrayList<TPHConstraint> getAllConstraints(RefType ref) {
final ArrayList<TPHConstraint> res = new ArrayList<>();
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
ResolvedType resType;
if(p instanceof WildcardType) {
resType = resultSet.resolveType(((WildcardType) p).getInnerType());
}else {
resType = resultSet.resolveType(p);
}
RefTypeOrTPHOrWildcardOrGeneric resolved = resType.resolvedType;
if(resolved instanceof TypePlaceholder) {
resType.additionalGenerics.forEach(ag ->{
TPHConstraint constr = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS);
if(!contains(res,constr)) {
res.add(constr);
}
});
}
if(resolved instanceof WildcardType) {
WildcardType resWC = (WildcardType) resolved;
ResolvedType resType2 = resultSet.resolveType(resWC.getInnerType());
if(resType2.resolvedType instanceof TypePlaceholder) {
resType2.additionalGenerics.forEach(ag ->{
TPHConstraint constr = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS);
if(!contains(res,constr)) {
res.add(constr);
}
});
}
}
}
System.out.println("RES GIP === " + res.size());
return res;
}
private boolean contains(ArrayList<TPHConstraint> constraints, TPHConstraint constr) {
for(int i=0; i<constraints.size();++i) {
TPHConstraint p = constraints.get(i);
if(constr.getLeft().equals(p.getLeft()) && constr.getRight().equals(p.getRight()))
return true;
}
return false;
} }
/** /**
* Visits parameter type or return type with {@link SignatureVisitor} to create * Visits parameter type or return type with {@link SignatureVisitor} to create
* the method signature * the method signature
*
* @param t type of parameter or return type * @param t type of parameter or return type
* @param isParameterType true if t is type of parameter * @param sv true if t is type of parameter
*/ */
private void doVisitParamsOrReturn(RefTypeOrTPHOrWildcardOrGeneric t, boolean isParameterType) { private void doVisitParamsOrReturn(RefTypeOrTPHOrWildcardOrGeneric t, SignatureVisitor sv) {
String type = t.acceptTV(new TypeToString()); String type = t.acceptTV(new TypeToString());
SignatureVisitor sv;
if(isParameterType) {
sv = sw.visitParameterType();
}
else {
sv = sw.visitReturnType();
}
switch (type) { switch (type) {
case "RT": case "RT":
String sig = t.acceptTV(new TypeToSignature()); String sig = t.acceptTV(new TypeToSignature(constraints));
sv.visitClassType(sig.substring(1, sig.length())); sv.visitClassType(sig.substring(1, sig.length()));
break; break;
case "GRT": case "GRT":
GenericRefType g = (GenericRefType) t; GenericRefType g = (GenericRefType) t;
sv.visitTypeVariable(g.acceptTV(new TypeToSignature()).substring(1)); sv.visitTypeVariable(g.acceptTV(new TypeToSignature(constraints)));
break; break;
case "TPH": case "TPH":
RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType; RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType;
// der Fall wenn die Type eine Interface ist, muss betrachtet werden // der Fall wenn der Typ eine Interface ist, muss betrachtet werden
// Deswegen muss in ResutSet noch enthalten werden, ob die Type eine // Deswegen muss in ResutSet noch enthalten werden, ob die Type eine
// Interface oder eine Klasse ist. // Interface oder eine Klasse ist.
// das braucht man nicht es reicht: sv.visitTypeVariable(r.acceptTV(new TypeToSignature()) // das braucht man nicht es reicht: sv.visitTypeVariable(r.acceptTV(new
// TypeToSignature())
// //
String sig2 = r.acceptTV(new TypeToSignature()); String sig2 = r.acceptTV(new TypeToSignature(constraints));
String eqTPH = getEqualTPH(methodConstraints, sig2.substring(1, sig2.length()-1))+"$"; if (r instanceof GenericRefType) {
if(!(r instanceof TypePlaceholder)) { sv.visitTypeVariable(sig2);
if(sig2.contains("$$")) { } else if (!(r instanceof TypePlaceholder)) {
System.out.println(" Signature FUN$$: "+r); if (sig2.contains(SPECIAL_CHAR_FOR_FUN)) {
sv.visitInterface().visitClassType(sig2.substring(1, sig2.length())); sv.visitInterface().visitClassType(sig2.substring(1));
} else { } else {
sv.visitClassType(sig2.substring(1, sig2.length())); // Kann zwischen GenericRefType und RefType nicht unterscheiden
// Deswegen wird immer geprüft, ob der Name in Generic Maps liegt
String n = sig2.substring(1, sig2.length() - 1);
// if(genericsAndBoundsMethod.containsKey(n) || genericsAndBounds.containsKey(n)) {
// sv.visitTypeVariable(n);
// } else {
sv.visitClassType(n);
sv.visitEnd();
// }
// sv.visitClassType(n);
} }
} else { } else {
System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature())); String realName = sig2.substring(1, sig2.length() - 1);
sv.visitTypeVariable(eqTPH); String toVisit = realName+SPECIAL_CHAR;
if(!genericsAndBounds.containsKey(toVisit)) {
Optional<GenericsGeneratorResult> equalTPH = getEqualTPHFromClassConstraints(consClass, realName);
if(equalTPH.isPresent()){
toVisit = equalTPH.get().getConstraint().getLeft() + SPECIAL_CHAR;
} else {
toVisit = getEqualTPH(constraints, realName) + SPECIAL_CHAR;
}
}
sv.visitTypeVariable(toVisit);
} }
break; break;
case "SWC": case "SWC":
System.out.println("SWC---Signature");
SuperWildcardType swc = (SuperWildcardType) t; SuperWildcardType swc = (SuperWildcardType) t;
String sigInner = swc.getInnerType().acceptTV(new TypeToSignature()); String sigInner = swc.getInnerType().acceptTV(new TypeToSignature(constraints));
if(swc.getInnerType() instanceof TypePlaceholder) { int length = sigInner.length();
sv.visitTypeArgument('-').visitTypeVariable(sigInner.substring(1, sigInner.length())); visitWildCard(sv, sigInner, length, swc.getInnerType(), SUPER_CHAR);
} else if(swc.getInnerType() instanceof RefType) {
if(sigInner.contains("$$")) {
sv.visitTypeArgument('-').visitInterface().visitClassType(sigInner.substring(1,sigInner.length()));
}else {
sv.visitTypeArgument('-').visitClassType(sigInner.substring(1,sigInner.length()));
}
}else {
sv.visitTypeArgument('-').visitTypeVariable(sigInner.substring(1));
}
break; break;
case "EWC": case "EWC":
System.out.println("EWC---Signature");
ExtendsWildcardType ewc = (ExtendsWildcardType) t; ExtendsWildcardType ewc = (ExtendsWildcardType) t;
String esigInner = ewc.getInnerType().acceptTV(new TypeToSignature()); String esigInner = ewc.getInnerType().acceptTV(new TypeToSignature(constraints));
System.out.println(esigInner); int lengthEWCSig = esigInner.length();
if(ewc.getInnerType() instanceof TypePlaceholder) { visitWildCard(sv, esigInner, lengthEWCSig, ewc.getInnerType(), EXTENDS_CHAR);
sv.visitTypeArgument('+').visitTypeVariable(esigInner.substring(1, esigInner.length()));
} else if(ewc.getInnerType() instanceof RefType) {
if(esigInner.contains("$$")) {
sv.visitTypeArgument('+').visitInterface().visitClassType(esigInner.substring(1,esigInner.length()));
}else {
// sv.visitClassType(esigInner.substring(1,esigInner.length()));
sv.visitTypeArgument('+').visitClassType(esigInner.substring(1,esigInner.length()));
}
}else {
sv.visitTypeArgument('+').visitTypeVariable(esigInner.substring(1));
}
break; break;
default: default:
if(!isParameterType) // if (!sv)
sv.visitBaseType('V'); // sv.visitBaseType('V');
break; break;
} }
} }
private void visitWildCard(SignatureVisitor sv, String sigInner, int length, RefTypeOrTPHOrWildcardOrGeneric innerType, char superOrExtendsChar) {
if (innerType instanceof TypePlaceholder) {
sv.visitTypeArgument(superOrExtendsChar).visitTypeVariable(sigInner.substring(1, length));
} else if (innerType instanceof RefType) {
checkInnerSignatureOfWildCard(sv, sigInner, length, superOrExtendsChar);
} else {
sv.visitTypeArgument(superOrExtendsChar).visitTypeVariable(sigInner.substring(1));
}
}
private void checkInnerSignatureOfWildCard(SignatureVisitor sv, String sigInner, int length, char superOrExtendsChar) {
if (sigInner.contains(SPECIAL_CHAR_FOR_FUN)) {
sv.visitTypeArgument(superOrExtendsChar).visitInterface().visitClassType(sigInner.substring(1, length));
} else {
sv.visitTypeArgument(superOrExtendsChar).visitClassType(sigInner.substring(1, length));
}
}
private Optional<GenericsGeneratorResult> getEqualTPHFromClassConstraints(List<GenericsGeneratorResult> consClass, String tph) {
return consClass.stream()
.filter(c -> c.getConstraint().getLeft().equals(tph) || c.getEqualsTPHs().contains(tph))
.findFirst();
}
private String getEqualTPH(List<GenericsGeneratorResult> constraints2, String tph) {
return constraints2.stream()
.filter(c -> c.getConstraint().getLeft().equals(tph) || c.getEqualsTPHs().contains(tph))
.findFirst().get().getConstraint().getLeft();
}
/** /**
* Creates signature for class or interface with {@link SignatureWriter} * Creates signature for class or interface with {@link SignatureWriter}
* Signature looks like: * Signature looks like: <typevaliables (K:Ljava/lang/Object
* <typevaliables (K:Ljava/lang/Object "Bounds")>superclass * "Bounds")>superclass
*/ */
private void createSignatureForClassOrInterface() { public String createSignatureForClassOrInterface() {
defineTypeVariablesForClassOrInterface();
defineGenericsFromConstraints(consClass,genericsAndBounds);
String sClass = classOrInterface.getSuperClass().acceptTV(new TypeToSignature());
sw.visitSuperclass().visitClassType(sClass.substring(1, sClass.length() - 1));
sw.visitEnd();
return sw.toString();
}
private void defineTypeVariablesForClassOrInterface() {
Iterator<GenericTypeVar> itr = classOrInterface.getGenerics().iterator(); Iterator<GenericTypeVar> itr = classOrInterface.getGenerics().iterator();
while (itr.hasNext()) { while (itr.hasNext()) {
GenericTypeVar g = itr.next(); GenericTypeVar g = itr.next();
getBoundsOfTypeVar(g,genericsAndBounds); visitTypeVarsAndTheirBounds(g, genericsAndBounds);
}
} }
if(!consClass.isEmpty()) { /**
ArrayList<String> types = new ArrayList<>(); * @param genericsAndBounds2
ArrayList<String> superTypes = new ArrayList<>(); *
*/
private void defineGenericsFromConstraints(List<GenericsGeneratorResult> constraints, HashMap<String,String> genericsAndBounds2) {
constraints.forEach(c -> {
String typeVariable = c.getConstraint().getLeft() + SPECIAL_CHAR;
sw.visitFormalTypeParameter(typeVariable);
for(TPHConstraint cons : consClass) { String bound = c.getConstraint().getRight();
types.add(cons.getLeft()); bound = checkBound(bound);
superTypes.add(cons.getRight()); genericsAndBounds2.put(typeVariable, bound);
});
} }
for(TPHConstraint cons : consClass) { /**
String t = cons.getLeft()+"$"; * @param bound
String bound = cons.getRight()+"$"; * @return
sw.visitFormalTypeParameter(t); */
private String checkBound(String bound) {
if (bound.equals(Type.getInternalName(Object.class))) {
visitClassBound(bound);
} else {
bound += SPECIAL_CHAR;
sw.visitClassBound().visitTypeVariable(bound); sw.visitClassBound().visitTypeVariable(bound);
genericsAndBounds.put(t, bound); }
return bound;
} }
for(TPHConstraint cons : consClass) { /**
if(!types.contains(cons.getRight()) && !genericsAndBounds.keySet().contains(cons.getRight()+"$")) { * @param bound
String t = cons.getRight()+"$"; */
String bound = Type.getInternalName(Object.class); private void visitClassBound(String bound) {
sw.visitFormalTypeParameter(t);
sw.visitClassBound().visitClassType(bound); sw.visitClassBound().visitClassType(bound);
genericsAndBounds.put(t, bound);
sw.visitClassBound().visitEnd(); sw.visitClassBound().visitEnd();
} }
}
}
/*if(!commonPairs.isEmpty()) {
ArrayList<TypePlaceholder> types = new ArrayList<>();
ArrayList<TypePlaceholder> superTypes = new ArrayList<>();
for(GenericInsertPair p : commonPairs) {
types.add(p.TA1);
superTypes.add(p.TA2);
}
for(GenericInsertPair p : commonPairs) {
String t = p.TA1.getName()+"$";
String bound = p.TA2.getName()+"$";
sw.visitFormalTypeParameter(t);
sw.visitClassBound().visitTypeVariable(bound);
genericsAndBounds.put(t, bound);
}
for(GenericInsertPair p : commonPairs) {
if(!types.contains(p.TA2)) {
String t = p.TA2.getName()+"$";
String bound = Type.getInternalName(Object.class);
sw.visitFormalTypeParameter(t);
sw.visitClassBound().visitClassType(bound);
genericsAndBounds.put(t, bound);
sw.visitClassBound().visitEnd();
}
}
}
for(TypePlaceholder t : tphsClass) {
String n = t.getName()+"$";
String bound = Type.getInternalName(Object.class);
sw.visitFormalTypeParameter(n);
sw.visitClassBound().visitClassType(bound);
genericsAndBounds.put(n, bound);
sw.visitClassBound().visitEnd();
}*/
String sClass = classOrInterface.getSuperClass().acceptTV(new TypeToSignature());
sw.visitSuperclass().visitClassType(sClass.substring(1, sClass.length()-1));
sw.visitEnd();
}
/** /**
* Get bounds of type variable * Get bounds of type variable
*
* @param g type variable * @param g type variable
* @param genAndBounds * @param genAndBounds
*/ */
private void getBoundsOfTypeVar(GenericTypeVar g, HashMap<String, String> genAndBounds) { private void visitTypeVarsAndTheirBounds(GenericTypeVar g, HashMap<String, String> genAndBounds) {
sw.visitFormalTypeParameter(g.getName()); sw.visitFormalTypeParameter(g.getName());
Iterator<? extends RefTypeOrTPHOrWildcardOrGeneric> bItr = g.getBounds().iterator(); Iterator<? extends RefTypeOrTPHOrWildcardOrGeneric> bItr = g.getBounds().iterator();
while (bItr.hasNext()) { while (bItr.hasNext()) {
RefTypeOrTPHOrWildcardOrGeneric b = bItr.next(); RefTypeOrTPHOrWildcardOrGeneric b = bItr.next();
String boundDesc = b.acceptTV(new TypeToDescriptor()); String boundDesc = b.acceptTV(new TypeToDescriptor());
// System.out.println("GetBounds: " + boundDesc);
// Ensure that <...> extends java.lang.Object OR ... // Ensure that <...> extends java.lang.Object OR ...
sw.visitClassBound().visitClassType(boundDesc); if (b instanceof GenericRefType) {
sw.visitClassBound().visitTypeVariable(boundDesc);
} else {
visitClassBound(boundDesc);
}
genAndBounds.put(g.getName(), boundDesc); genAndBounds.put(g.getName(), boundDesc);
} }
sw.visitClassBound().visitEnd();
} }
@Override
public String toString() { public String toString() {
if(sw == null)
return super.toString();
return sw.toString(); return sw.toString();
} }
} }

View File

@@ -1,8 +1,11 @@
package de.dhbwstuttgart.bytecode.signature; package de.dhbwstuttgart.bytecode.signature;
import java.util.ArrayList;
import java.util.Iterator; import java.util.Iterator;
import java.util.List;
import java.util.Optional;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType; import de.dhbwstuttgart.syntaxtree.type.RefType;
@@ -12,6 +15,15 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.TypeVisitor; import de.dhbwstuttgart.syntaxtree.type.TypeVisitor;
public class TypeToSignature implements TypeVisitor<String> { public class TypeToSignature implements TypeVisitor<String> {
private List<GenericsGeneratorResult> constraints;
public TypeToSignature() {
this.constraints = new ArrayList<>();
}
public TypeToSignature(List<GenericsGeneratorResult> constraints) {
this.constraints = constraints;
}
@Override @Override
public String visit(RefType refType) { public String visit(RefType refType) {
@@ -33,7 +45,7 @@ public class TypeToSignature implements TypeVisitor<String> {
// } else { // } else {
// params += "L"+param.toString().replace(".", "/"); // params += "L"+param.toString().replace(".", "/");
// } // }
params += param.acceptTV(new TypeToSignature()); params += param.acceptTV(new TypeToSignature(constraints));
if(param instanceof TypePlaceholder) if(param instanceof TypePlaceholder)
params += ";"; params += ";";
@@ -48,7 +60,7 @@ public class TypeToSignature implements TypeVisitor<String> {
@Override @Override
public String visit(SuperWildcardType superWildcardType) { public String visit(SuperWildcardType superWildcardType) {
// throw new NotImplementedException(); // throw new NotImplementedException();
String sig = "-" + superWildcardType.getInnerType().acceptTV(new TypeToSignature()); String sig = "-" + superWildcardType.getInnerType().acceptTV(new TypeToSignature(constraints));
if(superWildcardType.getInnerType() instanceof TypePlaceholder) if(superWildcardType.getInnerType() instanceof TypePlaceholder)
sig += ";"; sig += ";";
return sig; return sig;
@@ -57,13 +69,21 @@ public class TypeToSignature implements TypeVisitor<String> {
@Override @Override
public String visit(TypePlaceholder typePlaceholder) { public String visit(TypePlaceholder typePlaceholder) {
// return typePlaceholder.toString().replace(".", "/"); // return typePlaceholder.toString().replace(".", "/");
return "T" + typePlaceholder.getName() + "$"; String name = typePlaceholder.getName();
if(!constraints.isEmpty()){
Optional<GenericsGeneratorResult> equalName = getEqualTPHFromClassConstraints(constraints, name);
if(equalName.isPresent())
name = equalName.get().getConstraint().getLeft();
}
return "T" + name + "$";
} }
@Override @Override
public String visit(ExtendsWildcardType extendsWildcardType) { public String visit(ExtendsWildcardType extendsWildcardType) {
// throw new NotImplementedException(); // throw new NotImplementedException();
String sig = "+" + extendsWildcardType.getInnerType().acceptTV(new TypeToSignature()); String sig = "+" + extendsWildcardType.getInnerType().acceptTV(new TypeToSignature(constraints));
if(extendsWildcardType.getInnerType() instanceof TypePlaceholder) if(extendsWildcardType.getInnerType() instanceof TypePlaceholder)
sig += ";"; sig += ";";
return sig; return sig;
@@ -74,4 +94,9 @@ public class TypeToSignature implements TypeVisitor<String> {
return genericRefType.getParsedName().replace(".", "/"); return genericRefType.getParsedName().replace(".", "/");
} }
private Optional<GenericsGeneratorResult> getEqualTPHFromClassConstraints(List<GenericsGeneratorResult> listOfConstraints, String tph) {
return listOfConstraints.stream()
.filter(c -> c.getConstraint().getLeft().equals(tph) || c.getEqualsTPHs().contains(tph))
.findFirst();
}
} }

View File

@@ -0,0 +1,94 @@
package de.dhbwstuttgart.bytecode.utilities;
import de.dhbwstuttgart.bytecode.signature.Signature;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.statement.ArgumentList;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import org.objectweb.asm.signature.SignatureVisitor;
import org.objectweb.asm.signature.SignatureWriter;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Iterator;
public class ByteCodeForFunNGenerator {
public static void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc, String path) {
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
SignatureWriter methSig = new SignatureWriter();
int numberOfParams = 0;
SignatureVisitor paramVisitor = methSig.visitParameterType();
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
while (itr.hasNext()) {
numberOfParams++;
// getBounds
paramVisitor.visitTypeVariable(CONSTANTS.T + numberOfParams);
itr.next();
}
methSig.visitReturnType().visitTypeVariable(CONSTANTS.R);
// ")"+lam.getReturn.getBounds
Signature sig = new Signature(numberOfParams);
String name = CONSTANTS.FUN + numberOfParams + CONSTANTS.$$;
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
Type.getInternalName(Object.class), null);
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc,
methSig.toString(), null);
mvApply.visitEnd();
writeClassFile(classWriter.toByteArray(), name, path);
}
public static void generateBCForFunN(ArgumentList argumentList, String methDesc, String path) {
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
SignatureWriter methSig = new SignatureWriter();
int numberOfParams = 0;
SignatureVisitor paramVisitor = methSig.visitParameterType();
Iterator<Expression> itr1 = argumentList.getArguments().iterator();
while(itr1.hasNext()) {
numberOfParams++;
// getBounds
paramVisitor.visitTypeVariable(CONSTANTS.T + numberOfParams);
itr1.next();
}
methSig.visitReturnType().visitTypeVariable(CONSTANTS.R);
// ")"+lam.getReturn.getBounds
Signature sig = new Signature(numberOfParams);
String name = CONSTANTS.FUN + numberOfParams + CONSTANTS.$$;
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
Type.getInternalName(Object.class), null);
MethodVisitor mvApply = classWriter.visitMethod(Opcodes.ACC_PUBLIC + Opcodes.ACC_ABSTRACT, "apply", methDesc,
methSig.toString(), null);
mvApply.visitEnd();
writeClassFile(classWriter.toByteArray(), name, path);
}
public static void writeClassFile(byte[] bytecode, String name, String path) {
FileOutputStream output;
try {
System.out.println("generating " + name + ".class file...");
output = new FileOutputStream(
new File(path + name + CONSTANTS.EXTENSIONCLASS));
output.write(bytecode);
output.close();
System.out.println(name + ".class file generated");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}

View File

@@ -0,0 +1,22 @@
package de.dhbwstuttgart.bytecode.utilities;
public interface CONSTANTS {
String VOID = "void";
String TPH = "TPH ";
String ANGLEBRACKET = "<";
String FUN = "Fun";
String EXTENSIONCLASS = ".class";
String $$ = "$$";
String T = "T";
String R = "R";
String DESUGAREDMETHODNAME = "lambda$new$";
String REFTYPE_BYTE = "java/lang/Byte";
String REFTYPE_SHORT = "java/lang/Short";
String REFTYPE_INTEGER = "java/lang/Integer";
String REFTYPE_LONG = "java/lang/Long";
String REFTYPE_DOUBLE = "java/lang/Double";
String REFTYPE_FLOAT = "java/lang/Float";
String REFTYPE_STRING = "java/lang/String";
String TO_STRING = "toString";
}

View File

@@ -5,25 +5,27 @@ import java.util.List;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.ConstraintsWithSameLeftSide;
public class ConstraintsFinder { public class ConstraintsFinder {
private List<TPHConstraint> allConstaints; private List<TPHConstraint> allConstaints;
public ConstraintsFinder(List<TPHConstraint> allConstaints) { public ConstraintsFinder(List<TPHConstraint> allConstaints) {
super();
this.allConstaints = allConstaints; this.allConstaints = allConstaints;
} }
public List<List<TPHConstraint>> findConstraints() { public List<ConstraintsWithSameLeftSide> findConstraints() {
List<List<TPHConstraint>> result = new ArrayList<>(); List<ConstraintsWithSameLeftSide> result = new ArrayList<>();
List<TPHConstraint> visitedCons = new ArrayList<>(); List<TPHConstraint> visitedCons = new ArrayList<>();
for(TPHConstraint c : allConstaints) { for(TPHConstraint c : allConstaints) {
if(c.getRel() == Relation.EXTENDS) { if(c.getRel() == Relation.EXTENDS) {
// get constraints with the same left side // get constraints with the same left side
List<TPHConstraint> cons = getConstraints(c,visitedCons); List<TPHConstraint> cons = getConstraints(c,visitedCons);
if(cons.size()>1) if(cons.size()>1) {
result.add(cons); ConstraintsWithSameLeftSide consWithSameLeftSide = new ConstraintsWithSameLeftSide(cons);
result.add(consWithSameLeftSide);
}
} }
} }

View File

@@ -1,6 +1,5 @@
package de.dhbwstuttgart.bytecode.utilities; package de.dhbwstuttgart.bytecode.utilities;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import java.util.ArrayList; import java.util.ArrayList;
@@ -19,7 +18,8 @@ public class KindOfLambda implements StatementVisitor{
private boolean isInstanceCapturingLambda = false; private boolean isInstanceCapturingLambda = false;
private List<RefTypeOrTPHOrWildcardOrGeneric> argumentList = new ArrayList<>(); private List<RefTypeOrTPHOrWildcardOrGeneric> argumentList = new ArrayList<>();
private ArrayList<String> usedVars = new ArrayList<>(); private ArrayList<String> usedVars = new ArrayList<>();
private boolean hasThis = false; private ArrayList<String> varsFromInnerLambdas = new ArrayList<>();
private boolean thisUsed = false;
private ArrayList<String> definedLocals = new ArrayList<>(); private ArrayList<String> definedLocals = new ArrayList<>();
public KindOfLambda(LambdaExpression lambdaExpression) { public KindOfLambda(LambdaExpression lambdaExpression) {
@@ -40,19 +40,20 @@ public class KindOfLambda implements StatementVisitor{
return argumentList; return argumentList;
} }
public boolean isHasThis() { public boolean isThisUsed() {
return hasThis; return thisUsed;
} }
@Override @Override
public void visit(ArgumentList argumentList) { public void visit(ArgumentList argumentList) {
// TODO Auto-generated method stub argumentList.getArguments().forEach(a->a.accept(this));
} }
@Override @Override
public void visit(LambdaExpression lambdaExpression) { public void visit(LambdaExpression lambdaExpression) {
lambdaExpression.params.getFormalparalist().forEach(p->varsFromInnerLambdas.add(p.getName()));
lambdaExpression.methodBody.accept(this);
} }
@Override @Override
@@ -111,9 +112,11 @@ public class KindOfLambda implements StatementVisitor{
@Override @Override
public void visit(LocalVar localVar) { public void visit(LocalVar localVar) {
if(!contain(params, localVar.name) && !definedLocals.contains(localVar.name)) { boolean addVar = !contain(params, localVar.name) && !definedLocals.contains(localVar.name) &&
!varsFromInnerLambdas.contains(localVar.name) && !usedVars.contains(localVar.name);
if(addVar) {
argumentList.add(localVar.getType()); argumentList.add(localVar.getType());
if(hasThis) { if(thisUsed) {
usedVars.add(1, localVar.name); usedVars.add(1, localVar.name);
} else { } else {
usedVars.add(0, localVar.name); usedVars.add(0, localVar.name);
@@ -141,12 +144,13 @@ public class KindOfLambda implements StatementVisitor{
@Override @Override
public void visit(MethodCall methodCall) { public void visit(MethodCall methodCall) {
methodCall.receiver.accept(this); methodCall.receiver.accept(this);
methodCall.arglist.accept(this);
} }
@Override @Override
public void visit(NewClass methodCall) { public void visit(NewClass methodCall) {
// TODO Auto-generated method stub methodCall.receiver.accept(this);
methodCall.arglist.accept(this);
} }
@Override @Override
@@ -190,8 +194,8 @@ public class KindOfLambda implements StatementVisitor{
@Override @Override
public void visit(This aThis) { public void visit(This aThis) {
if(!hasThis) { if(!thisUsed) {
hasThis = true; thisUsed = true;
this.argumentList.add(0,aThis.getType()); this.argumentList.add(0,aThis.getType());
} }
if(!isInstanceCapturingLambda) { if(!isInstanceCapturingLambda) {

View File

@@ -2,31 +2,37 @@ package de.dhbwstuttgart.bytecode.utilities;
import java.util.ArrayList; import java.util.ArrayList;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.GenericInsertPair; import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
import de.dhbwstuttgart.typeinference.result.ResultPair;
public class MethodAndTPH { public class MethodAndTPH {
private String name; private String id;
private final ArrayList<String> tphs = new ArrayList<>(); private final ArrayList<String> tphs = new ArrayList<>();
private final ArrayList<GenericInsertPair> pairs = new ArrayList<>(); //private final ArrayList<GenericInsertPair> pairs = new ArrayList<>();
private final ArrayList<ResultPair<TypePlaceholder, TypePlaceholder>> pairs = new ArrayList<>();
// tphs of local variables and parameters // tphs of local variables and parameters
private final ArrayList<String> localTphs = new ArrayList<>(); private final ArrayList<String> localTphs = new ArrayList<>();
public MethodAndTPH(String name) { public MethodAndTPH(String name) {
this.name = name; this.id = name;
} }
public ArrayList<String> getTphs() { public ArrayList<String> getTphs() {
return tphs; return tphs;
} }
public ArrayList<GenericInsertPair> getPairs(){ // public ArrayList<GenericInsertPair> getPairs(){
// return pairs;
// }
public ArrayList<ResultPair<TypePlaceholder, TypePlaceholder>> getPairs(){
return pairs; return pairs;
} }
public String getName() { public String getId() {
return name; return id;
} }
public ArrayList<String> getLocalTphs() { public ArrayList<String> getLocalTphs() {

View File

@@ -0,0 +1,243 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.utilities;
import de.dhbwstuttgart.bytecode.Exception.NotInCurrentPackageException;
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import javassist.NotFoundException;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.util.*;
/**
* @author fayez
*
*/
public class MethodCallHelper {
private MethodCall methCall;
private SourceFile sourceFile;
private ResultSet resultSet;
private String path;
/**
* @param methCall
* @param sourceFile
* @param resultSet
* @param path TODO
*/
public MethodCallHelper(MethodCall methCall, SourceFile sourceFile, ResultSet resultSet, String path) {
this.methCall = methCall;
this.sourceFile = sourceFile;
this.resultSet = resultSet;
this.path = path;
}
public String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
}
public boolean isInCurrPkg(String className) {
for (ClassOrInterface cl : sourceFile.KlassenVektor) {
if (className.equals(cl.getClassName().toString()))
return true;
}
return false;
}
public String getSuperClass(String className) throws NotInCurrentPackageException {
for (ClassOrInterface cl : sourceFile.getClasses()) {
if (className.equals(cl.getClassName().toString())) {
return cl.getSuperClass().getName().toString();
}
}
throw new NotInCurrentPackageException("Class " + className + " is not in the current package.");
}
public ClassOrInterface getClassFromCurrPkg(String className) throws NotInCurrentPackageException {
for (ClassOrInterface cl : sourceFile.KlassenVektor) {
if (className.equals(cl.getClassName().toString()))
return cl;
}
throw new NotInCurrentPackageException("Class of " + className + " is not in the current package.");
}
public String getDesc(String className) throws NotInCurrentPackageException, NotFoundException {
String name = methCall.name;
ClassOrInterface clazz = getClassFromCurrPkg(className);
String retType = getResolvedType(methCall.getType());
ArrayList<String> params = getTypes(methCall.arglist.getArguments());
Map<String, String> genAndBoundsClass = getGenericsAndBounds(clazz.getGenerics());
modifyGenAndBounds(genAndBoundsClass);
for (Method m : clazz.getMethods()) {
if (name.equals(m.getName()) && retType.equals(getResolvedType(m.getReturnType()))) {
ArrayList<String> paramsOfM = getTypes(m.getParameterList());
if(areEquals(params,paramsOfM)) {
Map<String, String> genAndBoundsMethod = getGenericsAndBoundsMethod(m.getGenerics());
modifyGenAndBounds(genAndBoundsMethod);
boolean hasGen = hasGen(m, genAndBoundsClass);
NormalMethod nm = new NormalMethod(m, (HashMap<String, String>) genAndBoundsClass,
(HashMap<String, String>) genAndBoundsMethod, hasGen);
return nm.accept(new DescriptorToString(resultSet));
}
}
}
throw new NotFoundException("Method " + name + " is not found");
}
private boolean areEquals(ArrayList<String> params, ArrayList<String> paramsOfM) {
if(params.size() != paramsOfM.size())
return false;
for(String t : params) {
for(String t2 : paramsOfM) {
if(!t.equals(t2))
return false;
}
}
return true;
}
private ArrayList<String> getTypes(ParameterList parameterList) {
Iterator<FormalParameter> itr = parameterList.iterator();
ArrayList<String> typeList = new ArrayList<>();
while (itr.hasNext()) {
FormalParameter fp = itr.next();
String t = getResolvedType(fp.getType());
typeList.add(t);
}
return typeList;
}
private ArrayList<String> getTypes(List<Expression> arguments) {
ArrayList<String> types = new ArrayList<>();
for(int i = 0; i<arguments.size(); ++i) {
String t = getResolvedType(arguments.get(i).getType());
types.add(t);
}
return types;
}
private boolean hasGen(Method m, Map<String, String> genericsAndBounds) {
String retType = resultSet.resolveType(m.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
/*Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist*/
boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.contains("TPH ") || retType.contains("<");
Map<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes = new HashMap<>();
Iterator<FormalParameter> itr = m.getParameterList().iterator();
while(itr.hasNext()) {
FormalParameter fp = itr.next();
methodParamsAndTypes.put(fp.getName(), resultSet.resolveType(fp.getType()).resolvedType);
}
/*Wenn die Rückgabe-Type eine Typ-variable ist, erzeuge direkt die Signature, wenn nicht,
* prüfe, ob einer der Parameter Typ-Variable als Typ hat*/
if(!hasGenInParameterList) {
for(String paramName : methodParamsAndTypes.keySet()) {
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor());
String sigOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature());
if(genericsAndBounds.containsKey(typeOfParam)||typeOfParam.contains("TPH ")||sigOfParam.contains("<")) {
hasGenInParameterList = true;
break;
}
}
}
return m.getGenerics().iterator().hasNext() || hasGenInParameterList;
}
private Map<String, String> getGenericsAndBoundsMethod(Iterable<? extends GenericTypeVar> generics) {
Map<String, String> genAndBounds = new HashMap<>();
Iterator<? extends GenericTypeVar> itr = generics.iterator();
while (itr.hasNext()) {
GenericTypeVar gtv = itr.next();
getBoundsOfTypeVar(gtv, genAndBounds);
}
return genAndBounds;
}
private void modifyGenAndBounds(Map<String, String> genAndBoundsClass) {
List<String> visited = new ArrayList<>(genAndBoundsClass.size());
Map<String, String> toReplace = new HashMap<>();
for (String tv : genAndBoundsClass.keySet()) {
if (visited.contains(tv))
continue;
List<String> types = new LinkedList<>();
String bound = genAndBoundsClass.get(tv);
types.add(tv);
visited.add(tv);
boolean doReplace = false;
while (genAndBoundsClass.keySet().contains(bound)) {
doReplace = true;
types.add(bound);
visited.add(bound);
bound = genAndBoundsClass.get(bound);
}
if (doReplace) {
for (String tt : types) {
toReplace.put(tt, bound);
}
}
}
for (String key : toReplace.keySet()) {
genAndBoundsClass.replace(key, toReplace.get(key));
}
}
private Map<String, String> getGenericsAndBounds(GenericDeclarationList generics) {
Map<String, String> genAndBounds = new HashMap<>();
Iterator<GenericTypeVar> itr = generics.iterator();
while (itr.hasNext()) {
GenericTypeVar gtv = itr.next();
getBoundsOfTypeVar(gtv, genAndBounds);
}
return genAndBounds;
}
private void getBoundsOfTypeVar(GenericTypeVar g, Map<String, String> genAndBounds) {
Iterator<? extends RefTypeOrTPHOrWildcardOrGeneric> bItr = g.getBounds().iterator();
while (bItr.hasNext()) {
RefTypeOrTPHOrWildcardOrGeneric b = bItr.next();
String boundDesc = b.acceptTV(new TypeToDescriptor());
genAndBounds.put(g.getName(), boundDesc);
}
}
public void generateBCForFunN(String methodDescriptor) {
ByteCodeForFunNGenerator.generateBCForFunN(methCall.arglist,methodDescriptor,path);
}
public String getDescriptorOfApplyMethod(String methodCallType) {
return new DescriptorToString().createDescForFunN(methCall.arglist, methodCallType);
}
/**
* @param methodCall
*/
public void createCheckCast(MethodCall methodCall, MethodVisitor mv) {
String checkCast = getResolvedType(methodCall.getType());
if(!checkCast.contains("TPH ")) {
int pos = checkCast.length();
if(checkCast.contains("<"))
pos = checkCast.indexOf("<");
mv.visitTypeInsn(Opcodes.CHECKCAST,checkCast.substring(0,pos));
}
}
}

View File

@@ -23,6 +23,7 @@ public class MethodFromMethodCall {
this.genericsAndBounds = genericsAndBounds; this.genericsAndBounds = genericsAndBounds;
} }
public ArgumentList getArgList() { public ArgumentList getArgList() {
return argList; return argList;
} }

View File

@@ -0,0 +1,34 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.utilities;
import java.util.Iterator;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.Method;
/**
* @author fayez
*
*/
public class MethodUtility {
/**
* Creates an ID for a method
*
* @param resolver type Resolver
* @param method for which the ID will be generated
* @return ID for the given method.
* ID = ReturntypeMethodname(Parametertypes)
*/
public static String createID(Resolver resolver, Method method) {
String id = resolver.getResolvedType(method.getReturnType()) + method.name + "(";
Iterator<FormalParameter> itr = method.getParameterList().iterator();
while (itr.hasNext()) {
FormalParameter fp = itr.next();
id += resolver.getResolvedType(fp.getType());
}
id += ")";
return id;
}
}

View File

@@ -4,13 +4,18 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Stream;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.NameReplacementResult;
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator; import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
public class NameReplacer { public class NameReplacer {
//TODO rename
private List<TPHConstraint> constraints; private List<TPHConstraint> constraints;
private List<TPHConstraint> allConstraints; private List<TPHConstraint> allConstraints;
private List<MethodAndTPH> methodAndTPHs;
// TODO rename into tphClass
private List<String> tphs; private List<String> tphs;
private List<String> localTphs; private List<String> localTphs;
@@ -22,7 +27,98 @@ public class NameReplacer {
this.localTphs = localTphs; this.localTphs = localTphs;
} }
public Map<String, List<String>> replaceNames() { public NameReplacer(List<TPHConstraint> constraints, List<TPHConstraint> allConstraints,List<String> tphs) {
super();
this.constraints = constraints;
this.allConstraints = allConstraints;
this.tphs = tphs;
}
public NameReplacer(List<TPHConstraint> constraints, List<TPHConstraint> allConstraints) {
this.constraints = constraints;
this.allConstraints = allConstraints;
}
public NameReplacer(List<TPHConstraint> constraints, List<TPHConstraint> allConstraints, List<MethodAndTPH> methodAndTPHs,
List<String> tphsClass) {
this.constraints = constraints;
this.allConstraints = allConstraints;
this.methodAndTPHs = methodAndTPHs;
this.tphs = tphsClass;
}
public NameReplacementResult replaceNames() {
String newName = NameGenerator.makeNewName();
List<String> names = new ArrayList<>();
substituteRightSidesWithNewName(newName, names);
substituteNamesInAllConstraints(newName, names);
Stream<ArrayList<String>> tphsOfMethods = methodAndTPHs.stream().map(m->m.getTphs());
Stream<ArrayList<String>> localTphsOfMethods = methodAndTPHs.stream().map(m->m.getLocalTphs());
replaceOldNames(newName, names, tphsOfMethods);
replaceOldNames(newName, names, localTphsOfMethods);
if(tphs.removeAll(names))
tphs.add(newName);
NameReplacementResult res = new NameReplacementResult(newName, names);
return res;
}
/**
* @param newName
* @param names
* @param tphsOfMethods
*/
public void replaceOldNames(final String newName, final List<String> names, Stream<ArrayList<String>> tphsOfMethods) {
tphsOfMethods.forEach(tphsMethod->{
if(tphsMethod.removeAll(names))
tphsMethod.add(newName);
});
}
public NameReplacementResult replaceNamesLocal() {
String newName = NameGenerator.makeNewName();
List<String> names = new ArrayList<>();
substituteRightSidesWithNewName(newName, names);
substituteNamesInAllConstraints(newName, names);
tphs.removeAll(names);
tphs.add(newName);
NameReplacementResult res = new NameReplacementResult(newName, names);
return res;
}
/**
* @param newName
* @param names
*/
public void substituteNamesInAllConstraints(String newName, List<String> names) {
for(TPHConstraint cons : allConstraints) {
if(names.contains(cons.getLeft()))
cons.setLeft(newName);
if(names.contains(cons.getRight()))
cons.setRight(newName);
}
}
/**
* @param newName
* @param names
*/
public void substituteRightSidesWithNewName(String newName, List<String> names) {
for(TPHConstraint cons : constraints) {
names.add(cons.getRight());
cons.setRight(newName);
}
}
public Map<String, List<String>> replaceNamesWithLocals() {
String newName = NameGenerator.makeNewName(); String newName = NameGenerator.makeNewName();
ArrayList<String> names = new ArrayList<>(); ArrayList<String> names = new ArrayList<>();
for(TPHConstraint cons : constraints) { for(TPHConstraint cons : constraints) {

View File

@@ -0,0 +1,28 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.utilities;
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.typeinference.result.ResultSet;
/**
* @author fayez
*
*/
public class Resolver {
private ResultSet resultSet;
/**
* @param resultSet
*/
public Resolver(ResultSet resultSet) {
this.resultSet = resultSet;
}
public String getResolvedType(RefTypeOrTPHOrWildcardOrGeneric type) {
return resultSet.resolveType(type).resolvedType.acceptTV(new TypeToDescriptor());
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,22 +1,20 @@
//PL 2018-12-19: typeInferenceOld nach typeInference uebertragen //PL 2018-12-19: typeInferenceOld nach typeInference uebertragen
package de.dhbwstuttgart.core; package de.dhbwstuttgart.core;
import de.dhbwstuttgart.bytecode.BytecodeGen; import de.dhbwstuttgart.bytecode.BytecodeGen;
import de.dhbwstuttgart.bytecode.Exception.BytecodeGeneratorError;
import de.dhbwstuttgart.bytecode.genericsGenerator.GeneratedGenericsFinder;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGenratorResultForSourceFile;
import de.dhbwstuttgart.environment.CompilationEnvironment; import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.parser.JavaTXParser; import de.dhbwstuttgart.parser.JavaTXParser;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.GenericsRegistry; import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
import de.dhbwstuttgart.parser.antlr.Java8Parser.CompilationUnitContext; import de.dhbwstuttgart.parser.antlr.Java8Parser.CompilationUnitContext;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.SourceFile; import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter; import de.dhbwstuttgart.syntaxtree.visual.ASTTypePrinter;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
@@ -28,7 +26,6 @@ import de.dhbwstuttgart.typeinference.unify.RuleSet;
import de.dhbwstuttgart.typeinference.unify.TypeUnify; import de.dhbwstuttgart.typeinference.unify.TypeUnify;
import de.dhbwstuttgart.typeinference.unify.distributeVariance; import de.dhbwstuttgart.typeinference.unify.distributeVariance;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure; import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator; import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType; import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
@@ -37,35 +34,36 @@ import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
import de.dhbwstuttgart.typeinference.unify.UnifyResultListener; import de.dhbwstuttgart.typeinference.unify.UnifyResultListener;
import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl; import de.dhbwstuttgart.typeinference.unify.UnifyResultListenerImpl;
import de.dhbwstuttgart.typeinference.unify.UnifyResultModel; import de.dhbwstuttgart.typeinference.unify.UnifyResultModel;
import de.dhbwstuttgart.typeinference.unify.UnifyTaskModel;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer; import java.io.Writer;
import java.util.*; import java.util.*;
import java.util.function.Function; import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.antlr.v4.parse.ANTLRParser.throwsSpec_return;
//import org.apache.commons.io.output.NullOutputStream; //import org.apache.commons.io.output.NullOutputStream;
public class JavaTXCompiler { public class JavaTXCompiler {
public static JavaTXCompiler INSTANCE;
final CompilationEnvironment environment; final CompilationEnvironment environment;
Boolean resultmodel = false; Boolean resultmodel = true;
public final Map<File, SourceFile> sourceFiles = new HashMap<>(); public final Map<File, SourceFile> sourceFiles = new HashMap<>();
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+"src/test/java/logFiles" geschrieben werden soll? Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+"src/test/java/logFiles" geschrieben werden soll?
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException { public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
this(Arrays.asList(sourceFile)); this(Arrays.asList(sourceFile));
INSTANCE = this;
} }
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException { public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
this(sourceFile); this(sourceFile);
this.log = log; this.log = log;
INSTANCE = this;
} }
public JavaTXCompiler(List<File> sources) throws IOException, ClassNotFoundException { public JavaTXCompiler(List<File> sources) throws IOException, ClassNotFoundException {
@@ -73,6 +71,7 @@ public class JavaTXCompiler {
for (File s : sources) { for (File s : sources) {
sourceFiles.put(s, parse(s)); sourceFiles.put(s, parse(s));
} }
INSTANCE = this;
} }
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException { public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException {
@@ -100,16 +99,30 @@ public class JavaTXCompiler {
Set<ClassOrInterface> allClasses = new HashSet<>(); Set<ClassOrInterface> allClasses = new HashSet<>();
/* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt /* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt
for (SourceFile sf : sourceFiles.values()) {
allClasses.addAll(sf.getClasses());
} }
allClasses.addAll(importedClasses);
return new TYPE(sourceFiles.values(), allClasses).getConstraints();
}
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
// PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal
// hinzugefuegt werden
// List<ClassOrInterface> allClasses = new
// ArrayList<>();//environment.getAllAvailableClasses();
Set<ClassOrInterface> allClasses = new HashSet<>();
/*
* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt for
* (SourceFile sf : sourceFiles.values()) { allClasses.addAll(sf.getClasses());
* }
*/ */
List<ClassOrInterface> importedClasses = new ArrayList<>(); List<ClassOrInterface> importedClasses = new ArrayList<>();
for (JavaClassName name : forSourceFile.getImports()) { for (JavaClassName name : forSourceFile.getImports()) {
// TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet // TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
ClassOrInterface importedClass = ASTFactory.createClass( ClassOrInterface importedClass = ASTFactory
ClassLoader.getSystemClassLoader().loadClass(name.toString())); .createClass(ClassLoader.getSystemClassLoader().loadClass(name.toString()));
importedClasses.add(importedClass); importedClasses.add(importedClass);
allClasses.addAll(importedClasses); allClasses.addAll(importedClasses);
} }
@@ -117,168 +130,152 @@ public class JavaTXCompiler {
} }
/* /*
public List<ResultSet> typeInferenceOld() throws ClassNotFoundException { * public List<ResultSet> typeInferenceOld() throws ClassNotFoundException {
List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses(); * List<ClassOrInterface> allClasses = new
//Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC * ArrayList<>();//environment.getAllAvailableClasses(); //Alle Importierten
for(SourceFile sf : this.sourceFiles.values()) { * Klassen in allen geparsten Sourcefiles kommen ins FC for(SourceFile sf :
allClasses.addAll(getAvailableClasses(sf)); * this.sourceFiles.values()) { allClasses.addAll(getAvailableClasses(sf));
allClasses.addAll(sf.getClasses()); * allClasses.addAll(sf.getClasses()); }
} *
* final ConstraintSet<Pair> cons = getConstraints();
final ConstraintSet<Pair> cons = getConstraints(); *
* FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses);
FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses); * System.out.println(finiteClosure); ConstraintSet<UnifyPair> unifyCons =
System.out.println(finiteClosure); * UnifyTypeFactory.convert(cons);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons); *
* TypeUnify unify = new TypeUnify(); Set<Set<UnifyPair>> results = new
TypeUnify unify = new TypeUnify(); * HashSet<>(); try { File logPath = new
Set<Set<UnifyPair>> results = new HashSet<>(); * File(System.getProperty("user.dir")+"/target/logFiles/"); logPath.mkdirs();
try { * FileWriter logFile = new FileWriter(new File(logPath, "log"));
File logPath = new File(System.getProperty("user.dir")+"/target/logFiles/"); * logFile.write("FC:\\" + finiteClosure.toString()+"\n"); for(SourceFile sf :
logPath.mkdirs(); * this.sourceFiles.values()) { logFile.write(ASTTypePrinter.print(sf)); }
FileWriter logFile = new FileWriter(new File(logPath, "log")); * logFile.flush(); Set<List<Constraint<UnifyPair>>> cardProd =
logFile.write("FC:\\" + finiteClosure.toString()+"\n"); * unifyCons.cartesianProduct(); for (List<Constraint<UnifyPair>> xCons :
for(SourceFile sf : this.sourceFiles.values()) { * cardProd ){ Set<UnifyPair> xConsSet = new HashSet<>(); for
logFile.write(ASTTypePrinter.print(sf)); * (Constraint<UnifyPair> constraint : xCons) { xConsSet.addAll(constraint); }
} * //.collect(Collectors.toCollection(ArrayList::new))))
logFile.flush(); * System.out.println(xConsSet); Set<String> methodParaTypeVarNames =
Set<List<Constraint<UnifyPair>>> cardProd = unifyCons.cartesianProduct(); * allClasses.stream().map(x -> x.getMethods().stream().map(y ->
for (List<Constraint<UnifyPair>> xCons : cardProd ){ * y.getParameterList().getFormalparalist() .stream().filter(z -> z.getType()
Set<UnifyPair> xConsSet = new HashSet<>(); * instanceof TypePlaceholder) .map(z ->
for (Constraint<UnifyPair> constraint : xCons) { * ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(
xConsSet.addAll(constraint); * HashSet::new))) .reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return
} * a;}, (a,b) -> { a.addAll(b); return a;} ) ) .reduce(new HashSet<String>(),
//.collect(Collectors.toCollection(ArrayList::new)))) * (a,b) -> { a.addAll(b); return a;} );
System.out.println(xConsSet); *
Set<String> methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist() * Set<String> constructorParaTypeVarNames = allClasses.stream().map(x ->
.stream().filter(z -> z.getType() instanceof TypePlaceholder) * x.getConstructors().stream().map(y ->
.map(z -> ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))) * y.getParameterList().getFormalparalist() .stream().filter(z -> z.getType()
.reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return a;}, (a,b) -> { a.addAll(b); return a;} ) ) * instanceof TypePlaceholder) .map(z ->
.reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return a;} ); * ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(
* HashSet::new))) .reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return
Set<String> constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().stream().map(y -> y.getParameterList().getFormalparalist() * a;}, (a,b) -> { a.addAll(b); return a;} ) ) .reduce(new HashSet<String>(),
.stream().filter(z -> z.getType() instanceof TypePlaceholder) * (a,b) -> { a.addAll(b); return a;} );
.map(z -> ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))) *
.reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return a;}, (a,b) -> { a.addAll(b); return a;} ) ) * Set<String> paraTypeVarNames = methodParaTypeVarNames;
.reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return a;} ); * paraTypeVarNames.addAll(constructorParaTypeVarNames);
*
Set<String> paraTypeVarNames = methodParaTypeVarNames; * Set<String> returnTypeVarNames = allClasses.stream().map(x ->
paraTypeVarNames.addAll(constructorParaTypeVarNames); * x.getMethods().stream().filter(y -> y.getReturnType() instanceof
* TypePlaceholder) .map(z ->
Set<String> returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder) * ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.
.map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get(); * toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;}
* ).get();
Set<String> fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder) *
.map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get(); * Set<String> fieldTypeVarNames = allClasses.stream().map(x ->
* x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof
returnTypeVarNames.addAll(fieldTypeVarNames); * TypePlaceholder) .map(z ->
* ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.
xConsSet = xConsSet.stream().map(x -> { * toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;}
//Hier muss ueberlegt werden, ob * ).get();
//1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs *
// mit disableWildcardtable() werden. * returnTypeVarNames.addAll(fieldTypeVarNames);
//2. alle Typvariablen mit Argument- oder Retuntyp-Variablen *
//in Beziehung auch auf disableWildcardtable() gesetzt werden muessen * xConsSet = xConsSet.stream().map(x -> { //Hier muss ueberlegt werden, ob //1.
//PL 2018-04-23 * alle Argument- und Retuntyp-Variablen in allen UnifyPairs // mit
if ((x.getLhsType() instanceof PlaceholderType)) { * disableWildcardtable() werden. //2. alle Typvariablen mit Argument- oder
if (paraTypeVarNames.contains(x.getLhsType().getName())) { * Retuntyp-Variablen //in Beziehung auch auf disableWildcardtable() gesetzt
((PlaceholderType)x.getLhsType()).setVariance((byte)1); * werden muessen //PL 2018-04-23 if ((x.getLhsType() instanceof
((PlaceholderType)x.getLhsType()).disableWildcardtable(); * PlaceholderType)) { if (paraTypeVarNames.contains(x.getLhsType().getName()))
} * { ((PlaceholderType)x.getLhsType()).setVariance((byte)1);
if (returnTypeVarNames.contains(x.getLhsType().getName())) { * ((PlaceholderType)x.getLhsType()).disableWildcardtable(); } if
((PlaceholderType)x.getLhsType()).setVariance((byte)-1); * (returnTypeVarNames.contains(x.getLhsType().getName())) {
((PlaceholderType)x.getLhsType()).disableWildcardtable(); * ((PlaceholderType)x.getLhsType()).setVariance((byte)-1);
} * ((PlaceholderType)x.getLhsType()).disableWildcardtable(); } } if
} * ((x.getRhsType() instanceof PlaceholderType)) { if
if ((x.getRhsType() instanceof PlaceholderType)) { * (paraTypeVarNames.contains(x.getRhsType().getName())) {
if (paraTypeVarNames.contains(x.getRhsType().getName())) { * ((PlaceholderType)x.getRhsType()).setVariance((byte)1);
((PlaceholderType)x.getRhsType()).setVariance((byte)1); * ((PlaceholderType)x.getRhsType()).disableWildcardtable(); } if
((PlaceholderType)x.getRhsType()).disableWildcardtable(); * (returnTypeVarNames.contains(x.getRhsType().getName())) {
} * ((PlaceholderType)x.getRhsType()).setVariance((byte)-1);
if (returnTypeVarNames.contains(x.getRhsType().getName())) { * ((PlaceholderType)x.getRhsType()).disableWildcardtable(); } } return x;//HIER
((PlaceholderType)x.getRhsType()).setVariance((byte)-1); * DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE JEWEILS
((PlaceholderType)x.getRhsType()).disableWildcardtable(); * ANDERE SEITE }).map( y -> { if ((y.getLhsType() instanceof PlaceholderType)
} * && (y.getRhsType() instanceof PlaceholderType)) { if
} * (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
return x;//HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE JEWEILS ANDERE SEITE * ((PlaceholderType)y.getRhsType()).getVariance() == 0) {
}).map( y -> { * ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType(
if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { * )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0
if (((PlaceholderType)y.getLhsType()).getVariance() != 0 && ((PlaceholderType)y.getRhsType()).getVariance() == 0) { * && ((PlaceholderType)y.getRhsType()).getVariance() != 0) {
((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType()).getVariance()); * ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType(
} * )).getVariance()); } } return y; } )
if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { * .collect(Collectors.toCollection(HashSet::new));
((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType()).getVariance()); * varianceInheritance(xConsSet); Set<Set<UnifyPair>> result =
} * unify.unifySequential(xConsSet, finiteClosure, logFile, log);
} * //Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
return y; } ) * System.out.println("RESULT: " + result); logFile.write("RES: " +
.collect(Collectors.toCollection(HashSet::new)); * result.toString()+"\n"); logFile.flush(); results.addAll(result); }
varianceInheritance(xConsSet); *
Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure, logFile, log); * results = results.stream().map(x -> { Optional<Set<UnifyPair>> res = new
//Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure); * RuleSet().subst(x.stream().map(y -> { if (y.getPairOp() ==
System.out.println("RESULT: " + result); * PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT); return y;
logFile.write("RES: " + result.toString()+"\n"); * //alle Paare a <.? b erden durch a =. b ersetzt
logFile.flush(); * }).collect(Collectors.toCollection(HashSet::new))); if (res.isPresent())
results.addAll(result); * {//wenn subst ein Erg liefert wurde was veraendert return new
} * TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure); } else
* return x; //wenn nichts veraendert wurde wird x zurueckgegeben
results = results.stream().map(x -> { * }).collect(Collectors.toCollection(HashSet::new));
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> { * System.out.println("RESULT Final: " + results); logFile.write("RES_FINAL: " +
if (y.getPairOp() == PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT); * results.toString()+"\n"); logFile.flush(); logFile.write("PLACEHOLDERS: " +
return y; //alle Paare a <.? b erden durch a =. b ersetzt * PlaceholderType.EXISTING_PLACEHOLDERS); logFile.flush(); } catch (IOException
}).collect(Collectors.toCollection(HashSet::new))); * e) { e.printStackTrace(); } return results.stream().map((unifyPairs -> new
if (res.isPresent()) {//wenn subst ein Erg liefert wurde was veraendert * ResultSet(UnifyTypeFactory.convert(unifyPairs,
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure); * generateTPHMap(cons))))).collect(Collectors.toList()); }
}
else return x; //wenn nichts veraendert wurde wird x zurueckgegeben
}).collect(Collectors.toCollection(HashSet::new));
System.out.println("RESULT Final: " + results);
logFile.write("RES_FINAL: " + results.toString()+"\n");
logFile.flush();
logFile.write("PLACEHOLDERS: " + PlaceholderType.EXISTING_PLACEHOLDERS);
logFile.flush();
}
catch (IOException e) {
e.printStackTrace();
}
return results.stream().map((unifyPairs ->
new ResultSet(UnifyTypeFactory.convert(unifyPairs, generateTPHMap(cons))))).collect(Collectors.toList());
}
*/ */
/** /**
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) * Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine
* wenn a eine Variance !=0 hat auf alle Typvariablen in Theta. * Variance !=0 hat auf alle Typvariablen in Theta.
* @param eq The set of constraints *
*
*/ */
/* /*
private void varianceInheritance(Set<UnifyPair> eq) { * private void varianceInheritance(Set<UnifyPair> eq) { Set<PlaceholderType>
Set<PlaceholderType> usedTPH = new HashSet<>(); * usedTPH = new HashSet<>(); Set<PlaceholderType> phSet = eq.stream().map(x ->
Set<PlaceholderType> phSet = eq.stream().map(x -> { * { Set<PlaceholderType> pair = new HashSet<>(); if (x.getLhsType() instanceof
Set<PlaceholderType> pair = new HashSet<>(); * PlaceholderType) pair.add((PlaceholderType)x.getLhsType()); if
if (x.getLhsType() instanceof PlaceholderType) pair.add((PlaceholderType)x.getLhsType()); * (x.getRhsType() instanceof PlaceholderType)
if (x.getRhsType() instanceof PlaceholderType) pair.add((PlaceholderType)x.getRhsType()); * pair.add((PlaceholderType)x.getRhsType()); return pair; }).reduce(new
return pair; * HashSet<>(), (a,b) -> { a.addAll(b); return a;} , (c,d) -> { c.addAll(d);
}).reduce(new HashSet<>(), (a,b) -> { a.addAll(b); return a;} , (c,d) -> { c.addAll(d); return c;}); * return c;});
*
ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet); * ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet);
phSetVariance.removeIf(x -> (x.getVariance() == 0)); * phSetVariance.removeIf(x -> (x.getVariance() == 0));
while(!phSetVariance.isEmpty()) { * while(!phSetVariance.isEmpty()) { PlaceholderType a =
PlaceholderType a = phSetVariance.remove(0); * phSetVariance.remove(0); usedTPH.add(a); //HashMap<PlaceholderType,Integer>
usedTPH.add(a); * ht = new HashMap<>(); //ht.put(a, a.getVariance()); Set<UnifyPair> eq1 = new
//HashMap<PlaceholderType,Integer> ht = new HashMap<>(); * HashSet<>(eq); eq1.removeIf(x -> !(x.getLhsType() instanceof PlaceholderType
//ht.put(a, a.getVariance()); * && ((PlaceholderType)x.getLhsType()).equals(a))); eq1.stream().forEach(x -> {
Set<UnifyPair> eq1 = new HashSet<>(eq); * x.getRhsType().accept(new distributeVariance(), a.getVariance());}); eq1 =
eq1.removeIf(x -> !(x.getLhsType() instanceof PlaceholderType && ((PlaceholderType)x.getLhsType()).equals(a))); * new HashSet<>(eq); eq1.removeIf(x -> !(x.getRhsType() instanceof
eq1.stream().forEach(x -> { x.getRhsType().accept(new distributeVariance(), a.getVariance());}); * PlaceholderType && ((PlaceholderType)x.getRhsType()).equals(a)));
eq1 = new HashSet<>(eq); * eq1.stream().forEach(x -> { x.getLhsType().accept(new distributeVariance(),
eq1.removeIf(x -> !(x.getRhsType() instanceof PlaceholderType && ((PlaceholderType)x.getRhsType()).equals(a))); * a.getVariance());}); phSetVariance = new ArrayList<>(phSet);
eq1.stream().forEach(x -> { x.getLhsType().accept(new distributeVariance(), a.getVariance());}); * phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x))); }
phSetVariance = new ArrayList<>(phSet); * }
phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x)));
}
}
*/ */
public UnifyResultModel typeInferenceAsync(UnifyResultListener resultListener, Writer logFile) throws ClassNotFoundException { public UnifyResultModel typeInferenceAsync(UnifyResultListener resultListener, Writer logFile)
throws ClassNotFoundException {
List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses(); List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
// Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC // Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
for (SourceFile sf : this.sourceFiles.values()) { for (SourceFile sf : this.sourceFiles.values()) {
@@ -291,21 +288,20 @@ public class JavaTXCompiler {
UnifyResultModel urm = null; UnifyResultModel urm = null;
// urm.addUnifyResultListener(resultListener); // urm.addUnifyResultListener(resultListener);
try { try {
logFile = logFile == null ? new FileWriter(new File("log_"+sourceFiles.keySet().iterator().next().getName())) : logFile; logFile = logFile == null
? new FileWriter(new File("log_" + sourceFiles.keySet().iterator().next().getName()))
: logFile;
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile); IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile);
System.out.println(finiteClosure); System.out.println(finiteClosure);
urm = new UnifyResultModel(cons, finiteClosure); urm = new UnifyResultModel(cons, finiteClosure);
urm.addUnifyResultListener(resultListener); urm.addUnifyResultListener(resultListener);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons); ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
Function<UnifyPair, UnifyPair> distributeInnerVars = Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
x -> {
UnifyType lhs, rhs; UnifyType lhs, rhs;
if (((lhs = x.getLhsType()) instanceof PlaceholderType) if (((lhs = x.getLhsType()) instanceof PlaceholderType)
&& ((rhs = x.getRhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType)
&& (((PlaceholderType)lhs).isInnerType() && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
|| ((PlaceholderType)rhs).isInnerType()))
{
((PlaceholderType) lhs).setInnerType(true); ((PlaceholderType) lhs).setInnerType(true);
((PlaceholderType) rhs).setInnerType(true); ((PlaceholderType) rhs).setInnerType(true);
} }
@@ -323,27 +319,58 @@ public class JavaTXCompiler {
} }
logFile.flush(); logFile.flush();
Set<String> methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist() Set<String> methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream()
.stream().filter(z -> z.getType() instanceof TypePlaceholder) .map(y -> y.getParameterList().getFormalparalist().stream()
.map(z -> ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))) .filter(z -> z.getType() instanceof TypePlaceholder)
.reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return a;}, (a,b) -> { a.addAll(b); return a;} ) ) .map(z -> ((TypePlaceholder) z.getType()).getName())
.reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return a;} ); .collect(Collectors.toCollection(HashSet::new)))
.reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
}, (a, b) -> {
a.addAll(b);
return a;
})).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
});
Set<String> constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().stream().map(y -> y.getParameterList().getFormalparalist() Set<String> constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().stream()
.stream().filter(z -> z.getType() instanceof TypePlaceholder) .map(y -> y.getParameterList().getFormalparalist().stream()
.map(z -> ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))) .filter(z -> z.getType() instanceof TypePlaceholder)
.reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return a;}, (a,b) -> { a.addAll(b); return a;} ) ) .map(z -> ((TypePlaceholder) z.getType()).getName())
.reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return a;} ); .collect(Collectors.toCollection(HashSet::new)))
.reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
}, (a, b) -> {
a.addAll(b);
return a;
})).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
});
Set<String> paraTypeVarNames = methodParaTypeVarNames; Set<String> paraTypeVarNames = methodParaTypeVarNames;
paraTypeVarNames.addAll(constructorParaTypeVarNames); paraTypeVarNames.addAll(constructorParaTypeVarNames);
Set<String> returnTypeVarNames = allClasses.stream()
.map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder)
.map(z -> ((TypePlaceholder) z.getReturnType()).getName())
.collect(Collectors.toCollection(HashSet::new)))
.reduce((a, b) -> {
a.addAll(b);
return a;
}).get();
Set<String> returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder) Set<String> fieldTypeVarNames = allClasses.stream()
.map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get(); .map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder)
.map(z -> ((TypePlaceholder) z.getReturnType()).getName())
Set<String> fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder) .collect(Collectors.toCollection(HashSet::new)))
.map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get(); .reduce((a, b) -> {
a.addAll(b);
return a;
}).get();
returnTypeVarNames.addAll(fieldTypeVarNames); returnTypeVarNames.addAll(fieldTypeVarNames);
@@ -374,31 +401,32 @@ public class JavaTXCompiler {
((PlaceholderType) x.getRhsType()).disableWildcardtable(); ((PlaceholderType) x.getRhsType()).disableWildcardtable();
} }
} }
return x;//HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE JEWEILS ANDERE SEITE return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE
// JEWEILS ANDERE SEITE
}); });
Set<PlaceholderType> varianceTPHold; Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>(); Set<PlaceholderType> varianceTPH = new HashSet<>();
varianceTPH = varianceInheritanceConstraintSet(unifyCons); varianceTPH = varianceInheritanceConstraintSet(unifyCons);
/* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt /*
do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen * PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL
//anderen Seite übertragen * 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen
varianceTPHold = new HashSet<>(varianceTPH); * //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH);
varianceTPH = varianceInheritanceConstraintSet(unifyCons); * varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y
unifyCons.map( y -> { * -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType()
if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { * instanceof PlaceholderType)) { if
if (((PlaceholderType)y.getLhsType()).getVariance() != 0 && ((PlaceholderType)y.getRhsType()).getVariance() == 0) { * (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType()).getVariance()); * ((PlaceholderType)y.getRhsType()).getVariance() == 0) {
} * ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType(
if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { * )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0
((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType()).getVariance()); * && ((PlaceholderType)y.getRhsType()).getVariance() != 0) {
} * ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType(
} * )).getVariance()); } } return y; } ); } while
return y; } ); } * (!varianceTPHold.equals(varianceTPH));
while (!varianceTPHold.equals(varianceTPH));
*/ */
//Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure, logFile, log); // Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
// logFile, log);
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure); // Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
List<Set<Set<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints().stream().map(x -> { List<Set<Set<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints().stream().map(x -> {
Set<Set<UnifyPair>> ret = new HashSet<>(); Set<Set<UnifyPair>> ret = new HashSet<>();
@@ -407,15 +435,14 @@ public class JavaTXCompiler {
} }
return ret; return ret;
}).collect(Collectors.toCollection(ArrayList::new)); }).collect(Collectors.toCollection(ArrayList::new));
unify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm); unify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm,
} usedTasks);
catch (IOException e) { } catch (IOException e) {
System.err.println("kein LogFile"); System.err.println("kein LogFile");
} }
return urm; return urm;
} }
public List<ResultSet> typeInference() throws ClassNotFoundException { public List<ResultSet> typeInference() throws ClassNotFoundException {
List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses(); List<ClassOrInterface> allClasses = new ArrayList<>();// environment.getAllAvailableClasses();
// Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC // Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
@@ -428,28 +455,28 @@ public class JavaTXCompiler {
Set<Set<UnifyPair>> results = new HashSet<>(); Set<Set<UnifyPair>> results = new HashSet<>();
try { try {
Writer logFile = // new OutputStreamWriter(new NullOutputStream()); Writer logFile = // new OutputStreamWriter(new NullOutputStream());
new FileWriter(new File(System.getProperty("user.dir")+"/src/test/java/logFiles/"+"log_"+sourceFiles.keySet().iterator().next().getName())); // new FileWriter(new
// File(System.getProperty("user.dir")+"/src/test/resources/logFiles/"+"log_"+sourceFiles.keySet().iterator().next().getName()));
new FileWriter(new File(System.getProperty("user.dir") + "/logFiles/" + "log_"
+ sourceFiles.keySet().iterator().next().getName()));
IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile); IFiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses, logFile);
System.out.println(finiteClosure); System.out.println(finiteClosure);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons); ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
Function<UnifyPair, UnifyPair> distributeInnerVars = Function<UnifyPair, UnifyPair> distributeInnerVars = x -> {
x -> {
UnifyType lhs, rhs; UnifyType lhs, rhs;
if (((lhs = x.getLhsType()) instanceof PlaceholderType) if (((lhs = x.getLhsType()) instanceof PlaceholderType)
&& ((rhs = x.getRhsType()) instanceof PlaceholderType) && ((rhs = x.getRhsType()) instanceof PlaceholderType)
&& (((PlaceholderType)lhs).isInnerType() && (((PlaceholderType) lhs).isInnerType() || ((PlaceholderType) rhs).isInnerType())) {
|| ((PlaceholderType)rhs).isInnerType()))
{
((PlaceholderType) lhs).setInnerType(true); ((PlaceholderType) lhs).setInnerType(true);
((PlaceholderType) rhs).setInnerType(true); ((PlaceholderType) rhs).setInnerType(true);
} }
return x; return x;
}; };
logFile.write(unifyCons.toString()); logFile.write("Unify:" + unifyCons.toString());
unifyCons = unifyCons.map(distributeInnerVars); unifyCons = unifyCons.map(distributeInnerVars);
logFile.write(unifyCons.toString()); logFile.write("\nUnify_distributeInnerVars: " + unifyCons.toString());
TypeUnify unify = new TypeUnify(); TypeUnify unify = new TypeUnify();
// Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen // Set<Set<UnifyPair>> results = new HashSet<>(); Nach vorne gezogen
logFile.write("FC:\\" + finiteClosure.toString() + "\n"); logFile.write("FC:\\" + finiteClosure.toString() + "\n");
@@ -458,27 +485,58 @@ public class JavaTXCompiler {
} }
logFile.flush(); logFile.flush();
Set<String> methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist() Set<String> methodParaTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream()
.stream().filter(z -> z.getType() instanceof TypePlaceholder) .map(y -> y.getParameterList().getFormalparalist().stream()
.map(z -> ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))) .filter(z -> z.getType() instanceof TypePlaceholder)
.reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return a;}, (a,b) -> { a.addAll(b); return a;} ) ) .map(z -> ((TypePlaceholder) z.getType()).getName())
.reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return a;} ); .collect(Collectors.toCollection(HashSet::new)))
.reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
}, (a, b) -> {
a.addAll(b);
return a;
})).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
});
Set<String> constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().stream().map(y -> y.getParameterList().getFormalparalist() Set<String> constructorParaTypeVarNames = allClasses.stream().map(x -> x.getConstructors().stream()
.stream().filter(z -> z.getType() instanceof TypePlaceholder) .map(y -> y.getParameterList().getFormalparalist().stream()
.map(z -> ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(HashSet::new))) .filter(z -> z.getType() instanceof TypePlaceholder)
.reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return a;}, (a,b) -> { a.addAll(b); return a;} ) ) .map(z -> ((TypePlaceholder) z.getType()).getName())
.reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return a;} ); .collect(Collectors.toCollection(HashSet::new)))
.reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
}, (a, b) -> {
a.addAll(b);
return a;
})).reduce(new HashSet<String>(), (a, b) -> {
a.addAll(b);
return a;
});
Set<String> paraTypeVarNames = methodParaTypeVarNames; Set<String> paraTypeVarNames = methodParaTypeVarNames;
paraTypeVarNames.addAll(constructorParaTypeVarNames); paraTypeVarNames.addAll(constructorParaTypeVarNames);
Set<String> returnTypeVarNames = allClasses.stream()
.map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder)
.map(z -> ((TypePlaceholder) z.getReturnType()).getName())
.collect(Collectors.toCollection(HashSet::new)))
.reduce((a, b) -> {
a.addAll(b);
return a;
}).get();
Set<String> returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder) Set<String> fieldTypeVarNames = allClasses.stream()
.map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get(); .map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder)
.map(z -> ((TypePlaceholder) z.getReturnType()).getName())
Set<String> fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder) .collect(Collectors.toCollection(HashSet::new)))
.map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get(); .reduce((a, b) -> {
a.addAll(b);
return a;
}).get();
returnTypeVarNames.addAll(fieldTypeVarNames); returnTypeVarNames.addAll(fieldTypeVarNames);
@@ -509,31 +567,32 @@ public class JavaTXCompiler {
((PlaceholderType) x.getRhsType()).disableWildcardtable(); ((PlaceholderType) x.getRhsType()).disableWildcardtable();
} }
} }
return x;//HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE JEWEILS ANDERE SEITE return x;// HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE
// JEWEILS ANDERE SEITE
}); });
Set<PlaceholderType> varianceTPHold; Set<PlaceholderType> varianceTPHold;
Set<PlaceholderType> varianceTPH = new HashSet<>(); Set<PlaceholderType> varianceTPH = new HashSet<>();
varianceTPH = varianceInheritanceConstraintSet(unifyCons); varianceTPH = varianceInheritanceConstraintSet(unifyCons);
/* PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt /*
do { //PL 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen * PL 2018-11-07 wird in varianceInheritanceConstraintSet erledigt do { //PL
//anderen Seite übertragen * 2018-11-05 Huellenbildung Variance auf alle TPHs der Terme auf der jeweiligen
varianceTPHold = new HashSet<>(varianceTPH); * //anderen Seite übertragen varianceTPHold = new HashSet<>(varianceTPH);
varianceTPH = varianceInheritanceConstraintSet(unifyCons); * varianceTPH = varianceInheritanceConstraintSet(unifyCons); unifyCons.map( y
unifyCons.map( y -> { * -> { if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType()
if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) { * instanceof PlaceholderType)) { if
if (((PlaceholderType)y.getLhsType()).getVariance() != 0 && ((PlaceholderType)y.getRhsType()).getVariance() == 0) { * (((PlaceholderType)y.getLhsType()).getVariance() != 0 &&
((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType()).getVariance()); * ((PlaceholderType)y.getRhsType()).getVariance() == 0) {
} * ((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType(
if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) { * )).getVariance()); } if (((PlaceholderType)y.getLhsType()).getVariance() == 0
((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType()).getVariance()); * && ((PlaceholderType)y.getRhsType()).getVariance() != 0) {
} * ((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType(
} * )).getVariance()); } } return y; } ); } while
return y; } ); } * (!varianceTPHold.equals(varianceTPH));
while (!varianceTPHold.equals(varianceTPH));
*/ */
//Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure, logFile, log); // Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure,
// logFile, log);
// Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure); // Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
List<Set<Set<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints().stream().map(x -> { List<Set<Set<UnifyPair>>> oderConstraints = unifyCons.getOderConstraints().stream().map(x -> {
Set<Set<UnifyPair>> ret = new HashSet<>(); Set<Set<UnifyPair>> ret = new HashSet<>();
@@ -547,7 +606,8 @@ public class JavaTXCompiler {
UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure); UnifyResultModel urm = new UnifyResultModel(cons, finiteClosure);
UnifyResultListenerImpl li = new UnifyResultListenerImpl(); UnifyResultListenerImpl li = new UnifyResultListenerImpl();
urm.addUnifyResultListener(li); urm.addUnifyResultListener(li);
unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm); unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm,
usedTasks);
System.out.println("RESULT Final: " + li.getResults()); System.out.println("RESULT Final: " + li.getResults());
logFile.write("RES_FINAL: " + li.getResults().toString() + "\n"); logFile.write("RES_FINAL: " + li.getResults().toString() + "\n");
logFile.flush(); logFile.flush();
@@ -555,53 +615,64 @@ public class JavaTXCompiler {
} }
/* UnifyResultModel End */ /* UnifyResultModel End */
else { else {
Set<Set<UnifyPair>> result = unify.unify(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure)); // Set<Set<UnifyPair>> result = unify.unify(unifyCons.getUndConstraints(),
//Set<Set<UnifyPair>> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure)); // oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons,
// finiteClosure));
Set<Set<UnifyPair>> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints,
finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure), usedTasks);
System.out.println("RESULT: " + result); System.out.println("RESULT: " + result);
logFile.write("RES: " + result.toString() + "\n"); logFile.write("RES: " + result.toString() + "\n");
logFile.flush(); logFile.flush();
results.addAll(result); results.addAll(result);
results = results.stream().map(x -> { results = results.stream().map(x -> {
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> { Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
if (y.getPairOp() == PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT); if (y.getPairOp() == PairOperator.SMALLERDOTWC)
y.setPairOp(PairOperator.EQUALSDOT);
return y; // alle Paare a <.? b erden durch a =. b ersetzt return y; // alle Paare a <.? b erden durch a =. b ersetzt
}).collect(Collectors.toCollection(HashSet::new))); }).collect(Collectors.toCollection(HashSet::new)));
if (res.isPresent()) {// wenn subst ein Erg liefert wurde was veraendert if (res.isPresent()) {// wenn subst ein Erg liefert wurde was veraendert
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure); return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure);
} } else
else return x; //wenn nichts veraendert wurde wird x zurueckgegeben return x; // wenn nichts veraendert wurde wird x zurueckgegeben
}).collect(Collectors.toCollection(HashSet::new)); }).collect(Collectors.toCollection(HashSet::new));
System.out.println("RESULT Final: " + results); System.out.println("RESULT Final: " + results);
logFile.write("RES_FINAL: " + results.toString() + "\n"); logFile.write("RES_FINAL: " + results.toString() + "\n");
logFile.flush(); logFile.flush();
logFile.write("PLACEHOLDERS: " + PlaceholderType.EXISTING_PLACEHOLDERS); logFile.write("PLACEHOLDERS: " + PlaceholderType.EXISTING_PLACEHOLDERS);
logFile.flush(); logFile.flush();
}} }
catch (IOException e) { } catch (IOException e) {
System.err.println("kein LogFile"); System.err.println("kein LogFile");
} }
return results.stream().map((unifyPairs -> return results.stream()
new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons))))).collect(Collectors.toList()); .map((unifyPairs -> new ResultSet(UnifyTypeFactory.convert(unifyPairs, Pair.generateTPHMap(cons)))))
.collect(Collectors.toList());
} }
/** /**
* Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) * Vererbt alle Variancen bei Paaren (a <. theta) oder (Theta <. a) wenn a eine
* wenn a eine Variance !=0 hat auf alle Typvariablen in Theta. * Variance !=0 hat auf alle Typvariablen in Theta.
* @param eq The set of constraints *
*
*/ */
private Set<PlaceholderType> varianceInheritanceConstraintSet(ConstraintSet<UnifyPair> cons) { private Set<PlaceholderType> varianceInheritanceConstraintSet(ConstraintSet<UnifyPair> cons) {
Set<UnifyPair> eq = cons.getAll(); Set<UnifyPair> eq = cons.getAll();
Set<PlaceholderType> usedTPH = new HashSet<>(); Set<PlaceholderType> usedTPH = new HashSet<>();
Set<PlaceholderType> phSet = eq.stream().map(x -> { Set<PlaceholderType> phSet = eq.stream().map(x -> {
Set<PlaceholderType> pair = new HashSet<>(); Set<PlaceholderType> pair = new HashSet<>();
if (x.getLhsType() instanceof PlaceholderType) pair.add((PlaceholderType)x.getLhsType()); if (x.getLhsType() instanceof PlaceholderType)
if (x.getRhsType() instanceof PlaceholderType) pair.add((PlaceholderType)x.getRhsType()); pair.add((PlaceholderType) x.getLhsType());
if (x.getRhsType() instanceof PlaceholderType)
pair.add((PlaceholderType) x.getRhsType());
return pair; return pair;
}).reduce(new HashSet<>(), (a,b) -> { a.addAll(b); return a;} , (c,d) -> { c.addAll(d); return c;}); }).reduce(new HashSet<>(), (a, b) -> {
a.addAll(b);
return a;
}, (c, d) -> {
c.addAll(d);
return c;
});
ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet); ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet);
phSetVariance.removeIf(x -> (x.getVariance() == 0)); phSetVariance.removeIf(x -> (x.getVariance() == 0));
@@ -611,7 +682,8 @@ public class JavaTXCompiler {
// HashMap<PlaceholderType,Integer> ht = new HashMap<>(); // HashMap<PlaceholderType,Integer> ht = new HashMap<>();
// ht.put(a, a.getVariance()); // ht.put(a, a.getVariance());
// ConstraintSet<UnifyPair> eq1 = cons; // ConstraintSet<UnifyPair> eq1 = cons;
//eq1.removeIf(x -> !(x.getLhsType() instanceof PlaceholderType && ((PlaceholderType)x.getLhsType()).equals(a))); // eq1.removeIf(x -> !(x.getLhsType() instanceof PlaceholderType &&
// ((PlaceholderType)x.getLhsType()).equals(a)));
// durch if-Abfrage im foreach geloest // durch if-Abfrage im foreach geloest
cons.forEach(x -> { cons.forEach(x -> {
if (x.getLhsType() instanceof PlaceholderType && ((PlaceholderType) x.getLhsType()).equals(a)) { if (x.getLhsType() instanceof PlaceholderType && ((PlaceholderType) x.getLhsType()).equals(a)) {
@@ -619,38 +691,91 @@ public class JavaTXCompiler {
} }
}); });
// ` eq1 = new HashSet<>(eq); // ` eq1 = new HashSet<>(eq);
//eq1.removeIf(x -> !(x.getRhsType() instanceof PlaceholderType && ((PlaceholderType)x.getRhsType()).equals(a))); // eq1.removeIf(x -> !(x.getRhsType() instanceof PlaceholderType &&
// ((PlaceholderType)x.getRhsType()).equals(a)));
// durch if-Abfrage im foreach geloest // durch if-Abfrage im foreach geloest
cons.forEach(x -> { cons.forEach(x -> {
if (x.getRhsType() instanceof PlaceholderType && ((PlaceholderType) x.getRhsType()).equals(a)) { if (x.getRhsType() instanceof PlaceholderType && ((PlaceholderType) x.getRhsType()).equals(a)) {
x.getLhsType().accept(new distributeVariance(), a.getVariance()); x.getLhsType().accept(new distributeVariance(), a.getVariance());
} }
}); });
phSetVariance = new ArrayList<>(phSet); //macht vermutlich keinen Sinn PL 2018-10-18, doch, es koennen neue TPHs mit Variancen dazugekommen sein PL 2018-11-07 phSetVariance = new ArrayList<>(phSet); // macht vermutlich keinen Sinn PL 2018-10-18, doch, es koennen neue
// TPHs mit Variancen dazugekommen sein PL 2018-11-07
phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x))); phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x)));
} }
return usedTPH; return usedTPH;
} }
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException { private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
CompilationUnitContext tree = JavaTXParser.parse(sourceFile); CompilationUnitContext tree = JavaTXParser.parse(sourceFile);
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile), new GenericsRegistry(null)); SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile),
new GenericsRegistry(null));
SourceFile ret = generator.convert(tree, environment.packageCrawler); SourceFile ret = generator.convert(tree, environment.packageCrawler);
return ret; return ret;
} }
public void generateBytecodForFile(String path, HashMap<String, byte[]> classFiles, SourceFile sf,
List<ResultSet> typeinferenceResult) throws IOException {
try {
List<GenericGenratorResultForSourceFile> genericResults = getGeneratedGenericResultsForAllSourceFiles(typeinferenceResult);
BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult, genericResults, sf,path);
bytecodeGen.visit(sf);
this.writeClassFile(bytecodeGen.getClassFiles(), path);
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public List<GenericGenratorResultForSourceFile> getGeneratedGenericResultsForAllSourceFiles()
throws ClassNotFoundException {
List<GenericGenratorResultForSourceFile> result = new ArrayList<>();
for (File f : sourceFiles.keySet()) {
SourceFile sf = sourceFiles.get(f);
List<ResultSet> typeinferenceResult = this.typeInference();
GeneratedGenericsFinder sResFinder = new GeneratedGenericsFinder(sf, typeinferenceResult);
GenericGenratorResultForSourceFile simplifyResOfSF = sResFinder.findGeneratedGenerics();
result.add(simplifyResOfSF);
}
return result;
}
public List<GenericGenratorResultForSourceFile> getGeneratedGenericResultsForAllSourceFiles(
List<ResultSet> typeinferenceResult) throws ClassNotFoundException {
List<GenericGenratorResultForSourceFile> result = new ArrayList<>();
for (File f : sourceFiles.keySet()) {
SourceFile sf = sourceFiles.get(f);
GeneratedGenericsFinder sResFinder = new GeneratedGenericsFinder(sf, typeinferenceResult);
GenericGenratorResultForSourceFile simplifyResOfSF = sResFinder.findGeneratedGenerics();
result.add(simplifyResOfSF);
}
return result;
}
// um pfad erweitern // um pfad erweitern
public void generateBytecode(String path) throws ClassNotFoundException, IOException { public void generateBytecode(String path) throws ClassNotFoundException, IOException, BytecodeGeneratorError {
List<ResultSet> typeinferenceResult = this.typeInference();
List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles = getGeneratedGenericResultsForAllSourceFiles(
typeinferenceResult);
generateBytecode(path, typeinferenceResult, simplifyResultsForAllSourceFiles);
}
/**
* @param path
* @param typeinferenceResult
* @param simplifyResultsForAllSourceFiles
* @throws IOException
*/
public void generateBytecode(String path, List<ResultSet> typeinferenceResult,
List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles) throws IOException {
for (File f : sourceFiles.keySet()) { for (File f : sourceFiles.keySet()) {
HashMap<String, byte[]> classFiles = new HashMap<>(); HashMap<String, byte[]> classFiles = new HashMap<>();
SourceFile sf = sourceFiles.get(f); SourceFile sf = sourceFiles.get(f);
List<ResultSet> typeinferenceResult = this.typeInference(); BytecodeGen bytecodeGen = new BytecodeGen(classFiles, typeinferenceResult, simplifyResultsForAllSourceFiles,
BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult,sf,path); sf, path);
// BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult.get(0));
bytecodeGen.visit(sf); bytecodeGen.visit(sf);
this.writeClassFile(bytecodeGen.getClassFiles(), path); writeClassFile(bytecodeGen.getClassFiles(), path);
} }
} }
@@ -659,11 +784,13 @@ public class JavaTXCompiler {
for (String name : classFiles.keySet()) { for (String name : classFiles.keySet()) {
byte[] bytecode = classFiles.get(name); byte[] bytecode = classFiles.get(name);
System.out.println("generating " + name + ".class file ..."); System.out.println("generating " + name + ".class file ...");
//output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class")); // output = new FileOutputStream(new File(System.getProperty("user.dir") +
// "/testBytecode/generatedBC/" +name+".class"));
output = new FileOutputStream(new File(path + name + ".class")); output = new FileOutputStream(new File(path + name + ".class"));
output.write(bytecode); output.write(bytecode);
output.close(); output.close();
System.out.println(name + ".class file generated"); System.out.println(name + ".class file generated");
} }
} }
} }

View File

@@ -35,7 +35,7 @@ public class SyntaxTreeGenerator{
Set<JavaClassName> imports = new HashSet(); Set<JavaClassName> imports = new HashSet();
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields = new HashMap<>(); //PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH bekommen private Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields = new HashMap<>(); //PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH bekommen
List<Statement> fieldInitializations = new ArrayList<>(); List<Statement> fieldInitializations = new ArrayList<>(); //PL 2019-10-23: Muss für jede Klasse neu initilisiert werden
public SyntaxTreeGenerator(JavaClassRegistry reg, GenericsRegistry globalGenerics){ public SyntaxTreeGenerator(JavaClassRegistry reg, GenericsRegistry globalGenerics){
//Die Generics müssen während des Bauens des AST erstellt werden, //Die Generics müssen während des Bauens des AST erstellt werden,
@@ -159,6 +159,7 @@ public class SyntaxTreeGenerator{
private ClassOrInterface convertClass(Java8Parser.ClassDeclarationContext ctx) { private ClassOrInterface convertClass(Java8Parser.ClassDeclarationContext ctx) {
ClassOrInterface newClass; ClassOrInterface newClass;
fieldInitializations = new ArrayList<>(); //PL 2019-10-22: muss für jede Klasse neu initilisiert werden
if(ctx.normalClassDeclaration() != null){ if(ctx.normalClassDeclaration() != null){
newClass = convertNormal(ctx.normalClassDeclaration()); newClass = convertNormal(ctx.normalClassDeclaration());
} }

View File

@@ -2,6 +2,10 @@ package de.dhbwstuttgart.syntaxtree;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import com.google.common.collect.Lists;
import de.dhbwstuttgart.parser.NullToken;
import java.util.*; import java.util.*;
@@ -16,10 +20,20 @@ public class GenericDeclarationList extends SyntaxTreeNode implements Iterable<G
private Token offsetOfLastElement; private Token offsetOfLastElement;
private List<GenericTypeVar> gtvs = new ArrayList<>(); private List<GenericTypeVar> gtvs = new ArrayList<>();
public GenericDeclarationList(List<GenericTypeVar> values, Token endOffset) { @SuppressWarnings("unchecked")
public GenericDeclarationList(Iterable<? extends GenericTypeVar> values, Token endOffset) {
super(endOffset);
gtvs = isListOfGenericTypeVar(values) ? (List<GenericTypeVar>)values : Lists.newArrayList(values);
this.offsetOfLastElement = endOffset;
}
public GenericDeclarationList(ArrayList<GenericTypeVar> values, Token endOffset) {
super(endOffset); super(endOffset);
gtvs = values; gtvs = values;
this.offsetOfLastElement = endOffset; this.offsetOfLastElement = endOffset; }
private boolean isListOfGenericTypeVar(Iterable<? extends GenericTypeVar> values) {
return values instanceof List && ((List<?>)values).size() > 0 && ((List<?>)values).get(0) instanceof GenericTypeVar;
} }
@Override @Override

View File

@@ -100,7 +100,7 @@ public class UnifyTypeFactory {
} }
ret = new ReferenceType(t.getName().toString(),new TypeParams(params)); ret = new ReferenceType(t.getName().toString(),new TypeParams(params));
}else{ }else{
ret = new ReferenceType(t.getName().toString()); ret = new ReferenceType(t.getName().toString(), false);
} }
return ret; return ret;
} }
@@ -136,7 +136,7 @@ public class UnifyTypeFactory {
} }
public static UnifyType convert(GenericRefType t, Boolean innerType){ public static UnifyType convert(GenericRefType t, Boolean innerType){
return new ReferenceType(t.getParsedName()); return new ReferenceType(t.getParsedName(), true);
} }
public static UnifyType convert(WildcardType t, Boolean innerType){ public static UnifyType convert(WildcardType t, Boolean innerType){
@@ -222,12 +222,15 @@ public class UnifyTypeFactory {
return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, (RefType) tr); return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, (RefType) tr);
}else if(tr instanceof WildcardType){ }else if(tr instanceof WildcardType){
return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, (WildcardType) tr); return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, (WildcardType) tr);
}else if(tr instanceof GenericRefType){
return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, (GenericRefType) tr);
}else throw new NotImplementedException(); }else throw new NotImplementedException();
}else throw new NotImplementedException(); }else throw new NotImplementedException();
} }
public static RefTypeOrTPHOrWildcardOrGeneric convert(ReferenceType t, Map<String,TypePlaceholder> tphs) { public static RefTypeOrTPHOrWildcardOrGeneric convert(ReferenceType t, Map<String,TypePlaceholder> tphs) {
if(JavaClassName.Void.equals(t.getName()))return new Void(new NullToken()); if(JavaClassName.Void.equals(t.getName()))return new Void(new NullToken());
if (t.isGenTypeVar()) return new GenericRefType(t.getName(),new NullToken());
RefType ret = new RefType(new JavaClassName(t.getName()),convert(t.getTypeParams(), tphs),new NullToken()); RefType ret = new RefType(new JavaClassName(t.getName()),convert(t.getTypeParams(), tphs),new NullToken());
return ret; return ret;
} }

View File

@@ -19,4 +19,8 @@ public class This extends Expression
public void accept(StatementVisitor visitor) { public void accept(StatementVisitor visitor) {
visitor.visit(this); visitor.visit(this);
} }
public String toString() {
return "this: "+ this.getType();
}
} }

View File

@@ -1,22 +1,23 @@
package de.dhbwstuttgart.typedeployment; package de.dhbwstuttgart.typedeployment;
import org.antlr.v4.runtime.Token;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.typeinference.result.ResultPair;
public class TypeInsert { public class TypeInsert {
/** /**
* point wird hauptsächlich zur Anzeige einer Annotation im Eclipse-plugin benutzt. * point wird hauptsächlich zur Anzeige einer Annotation im Eclipse-plugin benutzt.
*/ */
public final TypeInsertPoint point; public final TypeInsertPoint point;
Set<TypeInsertPoint> inserts; Set<TypeInsertPoint> inserts;
ResultPair<?, ?> resultPair;
public TypeInsert(TypeInsertPoint point, Set<TypeInsertPoint> additionalPoints){ public TypeInsert(TypeInsertPoint point, Set<TypeInsertPoint> additionalPoints, ResultPair<?, ?> resultPair){
this.point = point; this.point = point;
inserts = additionalPoints; inserts = additionalPoints;
this.resultPair = resultPair;
} }
public String insert(String intoSource){ public String insert(String intoSource){
@@ -34,6 +35,10 @@ public class TypeInsert {
return point.getInsertString(); return point.getInsertString();
} }
public ResultPair<?, ?> getResultPair() {
return this.resultPair;
}
/* PL 2018-06-18 /* PL 2018-06-18
* Zwei TypeInsert's sind gleich, wenn ihre point's und ihre inserts' gleich sind * Zwei TypeInsert's sind gleich, wenn ihre point's und ihre inserts' gleich sind
* eingefuegt damit man TypeReplaceMarker vergleichen kann * eingefuegt damit man TypeReplaceMarker vergleichen kann

View File

@@ -1,9 +1,18 @@
package de.dhbwstuttgart.typedeployment; package de.dhbwstuttgart.typedeployment;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGenratorResultForSourceFile;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResult;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericsGeneratorResultForClass;
import de.dhbwstuttgart.bytecode.utilities.MethodUtility;
import de.dhbwstuttgart.bytecode.utilities.Resolver;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.typeinference.result.*; import de.dhbwstuttgart.typeinference.result.*;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import org.objectweb.asm.Type;
import java.util.*; import java.util.*;
@@ -29,61 +38,89 @@ public class TypeInsertFactory {
public static TypeInsert createInsertPoints(RefTypeOrTPHOrWildcardOrGeneric type, Token offset, ClassOrInterface cl, Method m, public static TypeInsert createInsertPoints(RefTypeOrTPHOrWildcardOrGeneric type, Token offset, ClassOrInterface cl, Method m,
ResultSet resultSet) { ResultSet resultSet) {
try {
ResolvedType resolvedType = resultSet.resolveType(type); ResolvedType resolvedType = resultSet.resolveType(type);
TypeInsertPoint insertPoint = new TypeInsertPoint(offset, TypeInsertPoint insertPoint = new TypeInsertPoint(offset,
new TypeToInsertString(resolvedType.resolvedType).insert); new TypeToInsertString(resolvedType.resolvedType).insert);
return new TypeInsert(insertPoint, new HashSet<>(Arrays.asList(createGenericInsert(resolvedType.additionalGenerics, cl, m)))); List<GenericGenratorResultForSourceFile> simplifyResults = JavaTXCompiler.INSTANCE.getGeneratedGenericResultsForAllSourceFiles();
for (GenericGenratorResultForSourceFile simplifyResultsEntries : simplifyResults) {
GenericsGeneratorResultForClass genericResultsForClass = simplifyResultsEntries.getSimplifyResultsByName("", cl.getClassName().toString());
return new TypeInsert(insertPoint, createGenericInsert(genericResultsForClass, cl, m, resultSet), resolvedType.getResultPair());
} }
private static TypeInsertPoint createGenericInsert(Set<GenericInsertPair> toInsert, ClassOrInterface cl, Method m){ return new TypeInsert(insertPoint, new HashSet<>(), resolvedType.getResultPair());
//Momentan wird Methode ignoriert. Parameter werden immer als Klassenparameter angefügt: } catch (ClassNotFoundException e) {
//Offset zum Einstzen bestimmen: e.printStackTrace();
Token offset; return null;
String insert = ""; }
String end; }
if(cl.getGenerics().iterator().hasNext()){
//offset = cl.getGenerics().iterator().next().getOffset(); private static synchronized Set<TypeInsertPoint> createGenericInsert(GenericsGeneratorResultForClass genericResult, ClassOrInterface cl, Method m, ResultSet resultSet){
offset = cl.getGenerics().getOffset(); Set<TypeInsertPoint> result = createGenericClassInserts(genericResult, cl);
end=",";
for (Method method : cl.getMethods()) {
Resolver resolver = new Resolver(resultSet);
List<GenericsGeneratorResult> methodConstraints = genericResult.getMethodConstraintsByID(MethodUtility.createID(resolver, method));
createMethodConstraints(method, methodConstraints);
}
return result;
}
private static Set<TypeInsertPoint> createMethodConstraints(Method method, List<GenericsGeneratorResult> constraints) {
Set<TypeInsertPoint> result = new HashSet<>();
Token offset = new GenericDeclarationList(method.getGenerics(), new NullToken()).getOffset();
if (constraints.size() == 0) {
result.add(new TypeInsertPoint(offset, ""));
return result;
}
String insert = " <";
for (GenericsGeneratorResult genericInsertConstraint : constraints) {
if (genericInsertConstraint.getConstraint().getRight().equals(Type.getInternalName(Object.class))) {
insert += genericInsertConstraint.getConstraint().getLeft();
} else { } else {
offset = cl.getGenerics().getOffset(); insert += genericInsertConstraint.getConstraint().getLeft() + " extends " + genericInsertConstraint.getConstraint().getRight() + ", ";
insert += "<";
end = ">";
}
//Alle einzusetzenden Generics und deren Bounds bestimmen:
HashMap<TypePlaceholder, HashSet<TypePlaceholder>> genericsAndBounds = new HashMap<>();
for(GenericInsertPair p : toInsert){
if(!genericsAndBounds.containsKey(p.TA1)){
genericsAndBounds.put((TypePlaceholder) p.TA1, new HashSet<>());
}
if(p.TA2 != null){
genericsAndBounds.get(p.TA1).add((TypePlaceholder) p.TA2);
if(!genericsAndBounds.containsKey(p.TA2)){
genericsAndBounds.put((TypePlaceholder) p.TA2, new HashSet<>());
}
} }
} }
//String zum Einsetzen (Generics mit bounds) generieren: insert = insert.substring(0, insert.length() -2);
Iterator<TypePlaceholder> it = genericsAndBounds.keySet().iterator(); insert += ">";
if(! it.hasNext())return new TypeInsertPoint(offset, "");
while(it.hasNext()){ result.add(new TypeInsertPoint(offset, insert));
TypePlaceholder tph = it.next(); return result;
insert += tph.getName(); }
Set<TypePlaceholder> bounds = genericsAndBounds.get(tph);
if(bounds.size() > 0){ private static Set<TypeInsertPoint> createGenericClassInserts(GenericsGeneratorResultForClass genericResult, ClassOrInterface cl) {
insert += " extends "; Set<TypeInsertPoint> result = new HashSet<>();
Iterator<TypePlaceholder> boundIt = bounds.iterator(); Token offset = cl.getGenerics().getOffset();
while(boundIt.hasNext()){
TypePlaceholder bound = boundIt.next(); List<GenericsGeneratorResult> classConstraints = genericResult.getClassConstraints();
insert += bound.getName();
if(boundIt.hasNext())insert += " & "; if (classConstraints.size() == 0) {
result.add(new TypeInsertPoint(offset, ""));
return result;
}
String insert = " <";
for (GenericsGeneratorResult genericInsertConstraint : classConstraints) {
if (genericInsertConstraint.getConstraint().getRight().equals(Type.getInternalName(Object.class))) {
insert += genericInsertConstraint.getConstraint().getLeft();
} else {
insert += genericInsertConstraint.getConstraint().getLeft() + " extends " + genericInsertConstraint.getConstraint().getRight() + ", ";
} }
} }
if(it.hasNext())insert+=",";
} insert = insert.substring(0, insert.length() -2);
return new TypeInsertPoint(offset, insert + end); insert += ">";
result.add(new TypeInsertPoint(offset, insert));
return result;
} }
} }

View File

@@ -4,12 +4,14 @@ import org.antlr.v4.runtime.Token;
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType; import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
import java.time.OffsetDateTime;
import java.util.List; import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class TypeInsertPoint { public class TypeInsertPoint {
public final Token point; public Token point;
private String insertString; private String insertString;
private int extraOffset = 0;
public TypeInsertPoint(Token point, String toInsert){ public TypeInsertPoint(Token point, String toInsert){
this.point = point; this.point = point;
@@ -21,13 +23,21 @@ public class TypeInsertPoint {
//token.point.getLine() != point.getLine() && token.point.getCharPositionInLine() <= point.getCharPositionInLine())) //token.point.getLine() != point.getLine() && token.point.getCharPositionInLine() <= point.getCharPositionInLine()))
token.point.getStartIndex() <= point.getStartIndex())) token.point.getStartIndex() <= point.getStartIndex()))
.mapToInt((typeInsertPoint -> typeInsertPoint.insertString.length())).sum(); .mapToInt((typeInsertPoint -> typeInsertPoint.insertString.length())).sum();
return new StringBuilder(intoSource).insert(point.getStartIndex()+offset, insertString).toString(); return new StringBuilder(intoSource).insert(point.getStartIndex()+offset+extraOffset, insertString).toString();
} }
public String getInsertString() { public String getInsertString() {
return insertString; return insertString;
} }
public void addExtraOffset(int toAdd) {
this.extraOffset += toAdd;
}
public int getPositionInCode() {
return point.getStartIndex() + extraOffset;
}
/* PL 2018-06-19 /* PL 2018-06-19
* Zwei TypeInsertPoint's sind gleich, wenn ihre point's gleich sind * Zwei TypeInsertPoint's sind gleich, wenn ihre point's gleich sind
* eingefuegt damit man TypeReplaceMarker vergleichen kann * eingefuegt damit man TypeReplaceMarker vergleichen kann

View File

@@ -23,4 +23,9 @@ public class GenericInsertPair {
if(TA2.equals(additionalTPH))return true; if(TA2.equals(additionalTPH))return true;
return false; return false;
} }
@Override
public String toString() {
return "GenIns(" + TA1.toString() + " < " + TA2.toString() + ")";
}
} }

View File

@@ -21,4 +21,9 @@ public class PairTPHequalRefTypeOrWildcardType extends ResultPair{
public void accept(ResultPairVisitor visitor) { public void accept(ResultPairVisitor visitor) {
visitor.visit(this); visitor.visit(this);
} }
@Override
public String toString() {
return "(" + left.toString() + " = " + right.toString() + ")";
}
} }

View File

@@ -20,4 +20,9 @@ public class PairTPHsmallerTPH extends ResultPair{
public void accept(ResultPairVisitor visitor) { public void accept(ResultPairVisitor visitor) {
visitor.visit(this); visitor.visit(this);
} }
@Override
public String toString() {
return "(" + left.toString() + " < " + right.toString() + ")";
}
} }

View File

@@ -7,11 +7,21 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import java.util.Set; import java.util.Set;
public class ResolvedType{ public class ResolvedType{
private ResultPair<?, ?> resultPair;
public final RefTypeOrTPHOrWildcardOrGeneric resolvedType; public final RefTypeOrTPHOrWildcardOrGeneric resolvedType;
public final Set<GenericInsertPair> additionalGenerics; //public final Set<GenericInsertPair> additionalGenerics;
public ResolvedType(RefTypeOrTPHOrWildcardOrGeneric resolvedType, Set<GenericInsertPair> additionalGenerics){ public ResolvedType(RefTypeOrTPHOrWildcardOrGeneric resolvedType, Set<GenericInsertPair> additionalGenerics){
this.resolvedType = resolvedType; this.resolvedType = resolvedType;
this.additionalGenerics = additionalGenerics; //this.additionalGenerics = additionalGenerics;
}
public void setResultPair(ResultPair<?, ?> resultPair) {
this.resultPair = resultPair;
}
public ResultPair<?, ?> getResultPair() {
return resultPair;
} }
} }

View File

@@ -27,4 +27,36 @@ public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B ext
public String toString() { public String toString() {
return "(" + left.toString() + ", " + right.toString() + ")"; return "(" + left.toString() + ", " + right.toString() + ")";
} }
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((left == null) ? 0 : left.getOffset().hashCode());
result = prime * result + ((right == null) ? 0 : right.getOffset().hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ResultPair<?,?> other = (ResultPair<?,?>) obj;
if (left == null) {
if (other.left != null)
return false;
} else if (!left.getOffset().equals(other.left.getOffset()))
return false;
if (right == null) {
if (other.right != null)
return false;
} else if (!right.getOffset().equals(other.right.getOffset()))
return false;
return true;
}
} }

View File

@@ -1,16 +1,34 @@
package de.dhbwstuttgart.typeinference.result; package de.dhbwstuttgart.typeinference.result;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.*;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
@SuppressWarnings("rawtypes")
public class ResultSet { public class ResultSet {
public final Set<ResultPair> results; public final Set<ResultPair> results;
public ResultSet(Set<ResultPair> results){ public Set<ResultPair<TypePlaceholder, TypePlaceholder>> genIns;
this.results = results;
public ResultSet(Set<ResultPair> set){
this.results = set;
this.genIns = new HashSet<>();
results.forEach(x -> { if (x instanceof PairTPHsmallerTPH) { this.genIns.add(x);}} );
}
public boolean contains(ResultPair toCheck) {
return this.results.contains(toCheck);
}
public void remove(ResultPair toCheck) {
results.remove(toCheck);
} }
public ResolvedType resolveType(RefTypeOrTPHOrWildcardOrGeneric type) { public ResolvedType resolveType(RefTypeOrTPHOrWildcardOrGeneric type) {
@@ -27,12 +45,24 @@ public class ResultSet {
} }
} }
//TODO Beim Einsetzen eines Generics, müssen die new und Methodenaufrufe verändert werden
public String toString() { public String toString() {
return results.toString(); return results.toString();
} }
@Override
public boolean equals(Object o) {
if (o instanceof ResultSet) {
ResultSet other = (ResultSet)o;
return this.results.equals(other.results);
} else {
return false;
}
}
@Override
public int hashCode() {
return results.hashCode();
}
} }
class Resolver implements ResultSetVisitor { class Resolver implements ResultSetVisitor {
@@ -40,6 +70,7 @@ class Resolver implements ResultSetVisitor {
private TypePlaceholder toResolve; private TypePlaceholder toResolve;
private RefTypeOrTPHOrWildcardOrGeneric resolved; private RefTypeOrTPHOrWildcardOrGeneric resolved;
private final Set<GenericInsertPair> additionalTPHs = new HashSet<>(); private final Set<GenericInsertPair> additionalTPHs = new HashSet<>();
private ResultPair<?,?> currentPair;
public Resolver(ResultSet resultPairs){ public Resolver(ResultSet resultPairs){
this.result = resultPairs; this.result = resultPairs;
@@ -49,23 +80,28 @@ class Resolver implements ResultSetVisitor {
toResolve = tph; toResolve = tph;
resolved = null; resolved = null;
System.out.println(tph.toString()); System.out.println(tph.toString());
for(ResultPair resultPair : result.results){ for(ResultPair<?,?> resultPair : result.results) {
if(resultPair instanceof PairTPHEqualTPH && ((PairTPHEqualTPH) resultPair).getLeft().equals(toResolve)){ if(resultPair instanceof PairTPHEqualTPH && ((PairTPHEqualTPH) resultPair).getLeft().equals(toResolve)){
currentPair = resultPair;
return resolve(((PairTPHEqualTPH) resultPair).getRight()); return resolve(((PairTPHEqualTPH) resultPair).getRight());
} }
} }
for(ResultPair resultPair : result.results){ for(ResultPair<?,?> resultPair : result.results){
currentPair = resultPair;
resultPair.accept(this); resultPair.accept(this);
} }
if(resolved==null){//TPH kommt nicht im Result vor: if(resolved==null){//TPH kommt nicht im Result vor:
resolved = tph; resolved = tph;
} }
return new ResolvedType(resolved, additionalTPHs);//resolved; ResolvedType result = new ResolvedType(resolved, additionalTPHs);//resolved;
result.setResultPair(currentPair);
return result;
} }
@Override @Override
public void visit(PairTPHsmallerTPH p) { public void visit(PairTPHsmallerTPH p) {
currentPair = p;
if(p.left.equals(toResolve)){ if(p.left.equals(toResolve)){
additionalTPHs.add(new GenericInsertPair(p.left, p.right)); additionalTPHs.add(new GenericInsertPair(p.left, p.right));
additionalTPHs.addAll(new RelatedTypeWalker(p.right, result).relatedTPHs); additionalTPHs.addAll(new RelatedTypeWalker(p.right, result).relatedTPHs);
@@ -76,6 +112,7 @@ class Resolver implements ResultSetVisitor {
@Override @Override
public void visit(PairTPHequalRefTypeOrWildcardType p) { public void visit(PairTPHequalRefTypeOrWildcardType p) {
currentPair = p;
if(p.left.equals(toResolve)){ if(p.left.equals(toResolve)){
resolved = p.right; resolved = p.right;
RelatedTypeWalker related = new RelatedTypeWalker(null, result); RelatedTypeWalker related = new RelatedTypeWalker(null, result);
@@ -121,6 +158,7 @@ class Resolver implements ResultSetVisitor {
/** /**
* Sucht aus dem Result Set den Sub/supertyp für einen TPH * Sucht aus dem Result Set den Sub/supertyp für einen TPH
*/ */
@SuppressWarnings("rawtypes")
class TPHResolver implements ResultSetVisitor { class TPHResolver implements ResultSetVisitor {
private final TypePlaceholder tph; private final TypePlaceholder tph;
@@ -189,6 +227,7 @@ class TPHResolver implements ResultSetVisitor {
} }
} }
@SuppressWarnings("rawtypes")
class RelatedTypeWalker implements ResultSetVisitor { class RelatedTypeWalker implements ResultSetVisitor {
final Set<GenericInsertPair> relatedTPHs = new HashSet<>(); final Set<GenericInsertPair> relatedTPHs = new HashSet<>();

View File

@@ -312,6 +312,9 @@ public class TYPEStmt implements StatementVisitor{
numericAdditionOrStringConcatenation.add(stringConcat); numericAdditionOrStringConcatenation.add(stringConcat);
} }
} }
if(numericAdditionOrStringConcatenation.size()<1){
throw new TypeinferenceException("Kein Typ für " + binary.operation.toString() + " vorhanden", binary.getOffset());
}
constraintsSet.addOderConstraint(numericAdditionOrStringConcatenation); constraintsSet.addOderConstraint(numericAdditionOrStringConcatenation);
}else if(binary.operation.equals(BinaryExpr.Operator.LESSEQUAL) || }else if(binary.operation.equals(BinaryExpr.Operator.LESSEQUAL) ||
binary.operation.equals(BinaryExpr.Operator.BIGGEREQUAL) || binary.operation.equals(BinaryExpr.Operator.BIGGEREQUAL) ||
@@ -355,6 +358,7 @@ public class TYPEStmt implements StatementVisitor{
//***ACHTUNG: Moeglicherweise oder und und-Contraint falsch //***ACHTUNG: Moeglicherweise oder und und-Contraint falsch
*/ */
//Testeise eingefuegt PL 2018-05-24 //Testeise eingefuegt PL 2018-05-24
//Hier sollte evtl. noch importe angefragt werden PL 2019-05-07
constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERNEQDOT)); constraintsSet.addUndConstraint(new Pair(binary.lexpr.getType(), number, PairOperator.SMALLERNEQDOT));
constraintsSet.addUndConstraint(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERNEQDOT)); constraintsSet.addUndConstraint(new Pair(binary.rexpr.getType(), number, PairOperator.SMALLERNEQDOT));
//Rückgabetyp ist Boolean //Rückgabetyp ist Boolean

View File

@@ -3,10 +3,12 @@ package de.dhbwstuttgart.typeinference.unify;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.ForkJoinPool; import java.util.concurrent.ForkJoinPool;
import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.constraints.Pair; import de.dhbwstuttgart.typeinference.constraints.Pair;
@@ -26,8 +28,8 @@ public class TypeUnify {
* @param cons * @param cons
* @return * @return
*/ */
public Set<Set<UnifyPair>> unify(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret) { public Set<Set<UnifyPair>> unify(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret, UnifyTaskModel usedTasks) {
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret); TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, usedTasks);
ForkJoinPool pool = new ForkJoinPool(); ForkJoinPool pool = new ForkJoinPool();
pool.invoke(unifyTask); pool.invoke(unifyTask);
Set<Set<UnifyPair>> res = unifyTask.join(); Set<Set<UnifyPair>> res = unifyTask.join();
@@ -52,8 +54,8 @@ public class TypeUnify {
* @param ret * @param ret
* @return * @return
*/ */
public UnifyResultModel unifyAsync(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret) { public UnifyResultModel unifyAsync(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret, UnifyTaskModel usedTasks) {
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret); TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, usedTasks);
ForkJoinPool pool = new ForkJoinPool(); ForkJoinPool pool = new ForkJoinPool();
pool.invoke(unifyTask); pool.invoke(unifyTask);
return ret; return ret;
@@ -70,8 +72,8 @@ public class TypeUnify {
* @param ret * @param ret
* @return * @return
*/ */
public UnifyResultModel unifyParallel(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret) { public UnifyResultModel unifyParallel(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret, UnifyTaskModel usedTasks) {
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret); TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, usedTasks);
ForkJoinPool pool = new ForkJoinPool(); ForkJoinPool pool = new ForkJoinPool();
pool.invoke(unifyTask); pool.invoke(unifyTask);
Set<Set<UnifyPair>> res = unifyTask.join(); Set<Set<UnifyPair>> res = unifyTask.join();
@@ -103,8 +105,8 @@ public class TypeUnify {
* @param cons * @param cons
* @return * @return
*/ */
public Set<Set<UnifyPair>> unifyOderConstraints(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret) { public Set<Set<UnifyPair>> unifyOderConstraints(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret, UnifyTaskModel usedTasks) {
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, false, logFile, log, 0, ret); TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, false, logFile, log, 0, ret, usedTasks);
Set<Set<UnifyPair>> res = unifyTask.compute(); Set<Set<UnifyPair>> res = unifyTask.compute();
try { try {
logFile.write("\nnoShortendElements: " + unifyTask.noShortendElements +"\n"); logFile.write("\nnoShortendElements: " + unifyTask.noShortendElements +"\n");

View File

@@ -3,6 +3,7 @@ package de.dhbwstuttgart.typeinference.unify;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.util.ArrayList;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@@ -17,8 +18,8 @@ public class TypeUnify2Task extends TypeUnifyTask {
Set<Set<UnifyPair>> setToFlatten; Set<Set<UnifyPair>> setToFlatten;
public TypeUnify2Task(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, List<Set<Set<UnifyPair>>> oderConstraints, Set<UnifyPair> nextSetElement, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm) { public TypeUnify2Task(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, List<Set<Set<UnifyPair>>> oderConstraints, Set<UnifyPair> nextSetElement, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm, UnifyTaskModel usedTasks) {
super(eq, oderConstraints, fc, parallel, logFile, log, rekTiefe, urm); super(eq, oderConstraints, fc, parallel, logFile, log, rekTiefe, urm, usedTasks);
this.setToFlatten = setToFlatten; this.setToFlatten = setToFlatten;
this.nextSetElement = nextSetElement; this.nextSetElement = nextSetElement;
} }
@@ -38,9 +39,17 @@ public class TypeUnify2Task extends TypeUnifyTask {
return new HashSet<>(); } return new HashSet<>(); }
else else
*/ */
noOfThread--; //writeLog("xxx");
//noOfThread--;
synchronized (usedTasks) {
if (this.myIsCancelled()) {
return new HashSet<>();
}
else {
return res; return res;
} }
}
}
public void closeLogFile() { public void closeLogFile() {

View File

@@ -19,6 +19,10 @@ import java.util.function.BinaryOperator;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import org.apache.commons.io.output.NullOutputStream;
import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory; import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.typeinference.constraints.Constraint; import de.dhbwstuttgart.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
@@ -44,6 +48,7 @@ import de.dhbwstuttgart.typeinference.unify.model.Pair;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer; import java.io.Writer;
import com.google.common.collect.Ordering; import com.google.common.collect.Ordering;
@@ -117,6 +122,10 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
static Integer noShortendElements = 0; static Integer noShortendElements = 0;
Boolean myIsCanceled = false;
volatile UnifyTaskModel usedTasks;
public TypeUnifyTask() { public TypeUnifyTask() {
rules = new RuleSet(); rules = new RuleSet();
} }
@@ -136,7 +145,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
*/ */
public TypeUnifyTask(Set<UnifyPair> eq, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm) { public TypeUnifyTask(Set<UnifyPair> eq, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm, UnifyTaskModel usedTasks) {
synchronized (this) { synchronized (this) {
this.eq = eq; this.eq = eq;
//this.oderConstraints = oderConstraints.stream().map(x -> x.stream().map(y -> new HashSet<>(y)).collect(Collectors.toSet(HashSet::new))).collect(Collectors.toList(ArrayList::new)); //this.oderConstraints = oderConstraints.stream().map(x -> x.stream().map(y -> new HashSet<>(y)).collect(Collectors.toSet(HashSet::new))).collect(Collectors.toList(ArrayList::new));
@@ -163,14 +172,27 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
thNo = totalnoOfThread; thNo = totalnoOfThread;
writeLog("thNo2 " + thNo); writeLog("thNo2 " + thNo);
try { try {
this.logFile = new FileWriter(new File(System.getProperty("user.dir")+"/src/test/java/logFiles/"+"Thread_"+thNo)); this.logFile = //new OutputStreamWriter(new NullOutputStream());
//new FileWriter(new File(System.getProperty("user.dir")+"/src/test/resources/logFiles/"+"Thread_"+thNo));
new FileWriter(new File(System.getProperty("user.dir")+"/logFiles/"+"Thread_"+thNo));
logFile.write("");
} }
catch (IOException e) { catch (IOException e) {
System.err.println("log-File nicht vorhanden"); System.err.println("log-File nicht vorhanden");
} }
/*Abbruchtest
if (thNo > 10) {
System.out.println("cancel");
usedTasks.cancel();
writeLog(nOfUnify.toString() + "cancel");
System.out.println("cancel");
}
*/
rules = new RuleSet(logFile); rules = new RuleSet(logFile);
this.rekTiefeField = rekTiefe; this.rekTiefeField = rekTiefe;
this.urm = urm; this.urm = urm;
this.usedTasks = usedTasks;
this.usedTasks.add(this);
} }
} }
@@ -206,6 +228,13 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
} }
} }
*/ */
void myCancel(Boolean b) {
myIsCanceled = true;
}
public boolean myIsCancelled() {
return myIsCanceled;
}
protected Set<Set<UnifyPair>> compute() { protected Set<Set<UnifyPair>> compute() {
if (one) { if (one) {
@@ -228,8 +257,19 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
catch (IOException ioE) { catch (IOException ioE) {
System.err.println("no log-File"); System.err.println("no log-File");
} }
if (isUndefinedPairSetSet(res)) { return new HashSet<>(); } if (isUndefinedPairSetSet(res)) {
else return res; throw new TypeinferenceException("Unresolved constraints: " + res.toString(), new NullToken()); //return new HashSet<>();
}
else {
synchronized (usedTasks) {
if (this.myIsCancelled()) {
return new HashSet<>();
}
else {
return res;
}
}
}
} }
/* /*
@Override @Override
@@ -263,6 +303,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
/* /*
* Step 1: Repeated application of reduce, adapt, erase, swap * Step 1: Repeated application of reduce, adapt, erase, swap
*/ */
rekTiefe++; rekTiefe++;
nOfUnify++; nOfUnify++;
writeLog(nOfUnify.toString() + " Unifikation: " + eq.toString()); writeLog(nOfUnify.toString() + " Unifikation: " + eq.toString());
@@ -422,6 +463,8 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
// .collect(Collectors.toCollection(HashSet::new)); // .collect(Collectors.toCollection(HashSet::new));
//Muss auskommentiert werden, wenn computeCartesianRecursive ENDE //Muss auskommentiert werden, wenn computeCartesianRecursive ENDE
Set<Set<UnifyPair>> eqPrimePrimeSet = new HashSet<>(); Set<Set<UnifyPair>> eqPrimePrimeSet = new HashSet<>();
Set<TypeUnifyTask> forks = new HashSet<>(); Set<TypeUnifyTask> forks = new HashSet<>();
@@ -478,15 +521,16 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//PL 2018-05-18 beide Bedingungen muessen gelten, da eqPrime Veränderungen in allem ausser subst //PL 2018-05-18 beide Bedingungen muessen gelten, da eqPrime Veränderungen in allem ausser subst
//eqPrimePrime Veraenderungen in subst repraesentieren. //eqPrimePrime Veraenderungen in subst repraesentieren.
//try { //try {
if (isSolvedForm(eqPrime)) { //if (isSolvedForm(eqPrime)) {
writeLog("eqPrime:" + eqPrime.toString()+"\n"); // writeLog("eqPrime:" + eqPrime.toString()+"\n");
} //}
//} //}
//catch (IOException e) { //catch (IOException e) {
// System.err.println("log-File nicht vorhanden"); // System.err.println("log-File nicht vorhanden");
//} //}
eqPrimePrimeSet.add(eqPrime); eqPrimePrimeSet.add(eqPrime);
if (finalresult) { if (finalresult && isSolvedForm(eqPrime)) {
writeLog("eqPrime:" + eqPrime.toString()+"\n");
urm.notify(eqPrimePrimeSet); urm.notify(eqPrimePrimeSet);
} }
} }
@@ -530,6 +574,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
Set<Set<UnifyPair>> computeCartesianRecursive(Set<Set<UnifyPair>> fstElems, ArrayList<Set<Set<UnifyPair>>> topLevelSets, Set<UnifyPair> eq, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, int rekTiefe, Boolean finalresult) { Set<Set<UnifyPair>> computeCartesianRecursive(Set<Set<UnifyPair>> fstElems, ArrayList<Set<Set<UnifyPair>>> topLevelSets, Set<UnifyPair> eq, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, int rekTiefe, Boolean finalresult) {
//ArrayList<Set<Set<UnifyPair>>> remainingSets = new ArrayList<>(topLevelSets); //ArrayList<Set<Set<UnifyPair>>> remainingSets = new ArrayList<>(topLevelSets);
fstElems.addAll(topLevelSets.stream() fstElems.addAll(topLevelSets.stream()
.filter(x -> x.size()==1) .filter(x -> x.size()==1)
.map(y -> y.stream().findFirst().get()) .map(y -> y.stream().findFirst().get())
@@ -794,9 +839,14 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
newElemsOrig.add(a); newElemsOrig.add(a);
/* FORK ANFANG */ /* FORK ANFANG */
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, rekTiefe, urm); TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, rekTiefe, urm, usedTasks);
//forks.add(forkOrig); //forks.add(forkOrig);
synchronized(usedTasks) {
if (this.myIsCancelled()) {
return new HashSet<>();
}
forkOrig.fork(); forkOrig.fork();
}
/* FORK ENDE */ /* FORK ENDE */
synchronized (this) { synchronized (this) {
@@ -841,17 +891,23 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
Set<Set<UnifyPair>> newElems = new HashSet<>(elems); Set<Set<UnifyPair>> newElems = new HashSet<>(elems);
List<Set<Set<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints); List<Set<Set<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints);
newElems.add(nSaL); newElems.add(nSaL);
TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, rekTiefe, urm); TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, rekTiefe, urm, usedTasks);
forks.add(fork); forks.add(fork);
synchronized(usedTasks) {
if (this.myIsCancelled()) {
return new HashSet<>();
}
fork.fork(); fork.fork();
} }
}
//res = unify2(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, rekTiefe); //res = unify2(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, rekTiefe);
/* FORK ANFANG */ /* FORK ANFANG */
synchronized (this) { synchronized (this) {
noOfThread--;
writeLog("wait "+ forkOrig.thNo); writeLog("wait "+ forkOrig.thNo);
noOfThread--;
res = forkOrig.join(); res = forkOrig.join();
//noOfThread++;
forkOrig.writeLog("final Orig 1"); forkOrig.writeLog("final Orig 1");
forkOrig.closeLogFile(); forkOrig.closeLogFile();
//Set<Set<UnifyPair>> fork_res = forkOrig.join(); //Set<Set<UnifyPair>> fork_res = forkOrig.join();
@@ -864,7 +920,9 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
forks.forEach(x -> writeLog("wait: " + x.thNo)); forks.forEach(x -> writeLog("wait: " + x.thNo));
for(TypeUnify2Task fork : forks) { for(TypeUnify2Task fork : forks) {
synchronized (this) { synchronized (this) {
noOfThread--;
Set<Set<UnifyPair>> fork_res = fork.join(); Set<Set<UnifyPair>> fork_res = fork.join();
//noOfThread++;
writeLog("Join " + new Integer(fork.thNo).toString()); writeLog("Join " + new Integer(fork.thNo).toString());
//noOfThread--; an das Ende von compute verschoben //noOfThread--; an das Ende von compute verschoben
writeLog("fork_res: " + fork_res.toString()); writeLog("fork_res: " + fork_res.toString());
@@ -877,7 +935,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
fork.closeLogFile(); fork.closeLogFile();
}; };
} }
noOfThread++; //noOfThread++;
} else { } else {
if(parallel && (variance == -1) && noOfThread <= MaxNoOfThreads) { if(parallel && (variance == -1) && noOfThread <= MaxNoOfThreads) {
Set<TypeUnify2Task> forks = new HashSet<>(); Set<TypeUnify2Task> forks = new HashSet<>();
@@ -887,9 +945,14 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
newElemsOrig.add(a); newElemsOrig.add(a);
/* FORK ANFANG */ /* FORK ANFANG */
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, rekTiefe, urm); TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, rekTiefe, urm, usedTasks);
//forks.add(forkOrig); //forks.add(forkOrig);
synchronized(usedTasks) {
if (this.myIsCancelled()) {
return new HashSet<>();
}
forkOrig.fork(); forkOrig.fork();
}
/* FORK ENDE */ /* FORK ENDE */
synchronized (this) { synchronized (this) {
@@ -934,17 +997,23 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
Set<Set<UnifyPair>> newElems = new HashSet<>(elems); Set<Set<UnifyPair>> newElems = new HashSet<>(elems);
List<Set<Set<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints); List<Set<Set<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints);
newElems.add(nSaL); newElems.add(nSaL);
TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, rekTiefe, urm); TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, rekTiefe, urm, usedTasks);
forks.add(fork); forks.add(fork);
synchronized(usedTasks) {
if (this.myIsCancelled()) {
return new HashSet<>();
}
fork.fork(); fork.fork();
} }
}
//res = unify2(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, rekTiefe); //res = unify2(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, rekTiefe);
/* FORK ANFANG */ /* FORK ANFANG */
synchronized (this) { synchronized (this) {
noOfThread--;
writeLog("wait "+ forkOrig.thNo); writeLog("wait "+ forkOrig.thNo);
noOfThread--;
res = forkOrig.join(); res = forkOrig.join();
//noOfThread++;
forkOrig.writeLog("final Orig -1"); forkOrig.writeLog("final Orig -1");
forkOrig.closeLogFile(); forkOrig.closeLogFile();
//Set<Set<UnifyPair>> fork_res = forkOrig.join(); //Set<Set<UnifyPair>> fork_res = forkOrig.join();
@@ -957,7 +1026,9 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
forks.forEach(x -> writeLog("wait: " + x.thNo)); forks.forEach(x -> writeLog("wait: " + x.thNo));
for(TypeUnify2Task fork : forks) { for(TypeUnify2Task fork : forks) {
synchronized (this) { synchronized (this) {
noOfThread--;
Set<Set<UnifyPair>> fork_res = fork.join(); Set<Set<UnifyPair>> fork_res = fork.join();
//noOfThread++;
writeLog("Join " + new Integer(fork.thNo).toString()); writeLog("Join " + new Integer(fork.thNo).toString());
//noOfThread--; an das Ende von compute verschoben //noOfThread--; an das Ende von compute verschoben
writeLog("fork_res: " + fork_res.toString()); writeLog("fork_res: " + fork_res.toString());
@@ -970,7 +1041,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
fork.closeLogFile(); fork.closeLogFile();
}; };
} }
noOfThread++; //noOfThread++;
} else { } else {
if(parallel && (variance == 2) && noOfThread <= MaxNoOfThreads) { if(parallel && (variance == 2) && noOfThread <= MaxNoOfThreads) {
writeLog("var2einstieg"); writeLog("var2einstieg");
@@ -981,9 +1052,14 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
newElemsOrig.add(a); newElemsOrig.add(a);
/* FORK ANFANG */ /* FORK ANFANG */
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, rekTiefe, urm); TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, rekTiefe, urm, usedTasks);
//forks.add(forkOrig); //forks.add(forkOrig);
synchronized(usedTasks) {
if (this.myIsCancelled()) {
return new HashSet<>();
}
forkOrig.fork(); forkOrig.fork();
}
/* FORK ENDE */ /* FORK ENDE */
synchronized (this) { synchronized (this) {
@@ -997,17 +1073,23 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
Set<Set<UnifyPair>> newElems = new HashSet<>(elems); Set<Set<UnifyPair>> newElems = new HashSet<>(elems);
List<Set<Set<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints); List<Set<Set<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints);
newElems.add(nSaL); newElems.add(nSaL);
TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, rekTiefe, urm); TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, rekTiefe, urm, usedTasks);
forks.add(fork); forks.add(fork);
synchronized(usedTasks) {
if (this.myIsCancelled()) {
return new HashSet<>();
}
fork.fork(); fork.fork();
} }
}
//res = unify2(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, rekTiefe); //res = unify2(newElemsOrig, newEqOrig, newOderConstraintsOrig, fc, parallel, rekTiefe);
/* FORK ANFANG */ /* FORK ANFANG */
synchronized (this) { synchronized (this) {
noOfThread--;
writeLog("wait "+ forkOrig.thNo); writeLog("wait "+ forkOrig.thNo);
noOfThread--;
res = forkOrig.join(); res = forkOrig.join();
//noOfThread++;
forkOrig.writeLog("final Orig 2"); forkOrig.writeLog("final Orig 2");
forkOrig.closeLogFile(); forkOrig.closeLogFile();
//Set<Set<UnifyPair>> fork_res = forkOrig.join(); //Set<Set<UnifyPair>> fork_res = forkOrig.join();
@@ -1019,7 +1101,9 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
forks.forEach(x -> writeLog("wait: " + x.thNo)); forks.forEach(x -> writeLog("wait: " + x.thNo));
for(TypeUnify2Task fork : forks) { for(TypeUnify2Task fork : forks) {
synchronized (this) { synchronized (this) {
noOfThread--;
Set<Set<UnifyPair>> fork_res = fork.join(); Set<Set<UnifyPair>> fork_res = fork.join();
//noOfThread++;
writeLog("Join " + new Integer(fork.thNo).toString()); writeLog("Join " + new Integer(fork.thNo).toString());
//noOfThread--; an das Ende von compute verschoben //noOfThread--; an das Ende von compute verschoben
add_res.add(fork_res); add_res.add(fork_res);
@@ -1027,7 +1111,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
fork.closeLogFile(); fork.closeLogFile();
}; };
} }
noOfThread++; //noOfThread++;
} else { } else {
//parallel = false; //Wenn MaxNoOfThreads erreicht ist, sequentiell weiterarbeiten //parallel = false; //Wenn MaxNoOfThreads erreicht ist, sequentiell weiterarbeiten
elems.add(a); //PL 2019-01-16 muss das wirklich hin steht schon in Zeile 859 ja braucht man siehe Zeile 859 elems.add(a); //PL 2019-01-16 muss das wirklich hin steht schon in Zeile 859 ja braucht man siehe Zeile 859
@@ -1036,9 +1120,6 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
if (!isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result)) { if (!isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result)) {
//wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen //wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen
result = res; result = res;
if (res.iterator().next() instanceof WildcardType) {
System.out.println("");
}
} }
else { else {
if ((isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result)) if ((isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result))
@@ -1066,8 +1147,9 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//Alle Variablen bestimmen die nicht hinzugefügt wurden in a_last //Alle Variablen bestimmen die nicht hinzugefügt wurden in a_last
//System.out.println(a_last); //System.out.println(a_last);
a_last.forEach(x -> {writeLog("a_last_elem:" + x + " basepair: " + x.getBasePair());});
try {//PL eingefuegt 2019-03-06 da bei map mmer wieder Nullpointer kamen try {//PL eingefuegt 2019-03-06 da bei map mmer wieder Nullpointer kamen
a_last.forEach(x -> {writeLog("a_last_elem:" + x + " basepair: " + x.getBasePair());});//PL 2019-05-13 ins try hinzugefuegt Nullpointer-Exception ist in der Zeile aufgetaucht.
List<PlaceholderType> varsLast_a = List<PlaceholderType> varsLast_a =
a_last.stream().filter(x -> ((x.getLhsType().getName().equals(x.getBasePair().getLhsType().getName()) a_last.stream().filter(x -> ((x.getLhsType().getName().equals(x.getBasePair().getLhsType().getName())
&& (x.getLhsType() instanceof PlaceholderType) && (x.getBasePair().getLhsType() instanceof PlaceholderType)) && (x.getLhsType() instanceof PlaceholderType) && (x.getBasePair().getLhsType() instanceof PlaceholderType))

View File

@@ -0,0 +1,18 @@
package de.dhbwstuttgart.typeinference.unify;
import java.util.ArrayList;
public class UnifyTaskModel {
ArrayList<TypeUnifyTask> usedTasks = new ArrayList<>();
public synchronized void add(TypeUnifyTask t) {
usedTasks.add(t);
}
public synchronized void cancel() {
for(TypeUnifyTask t : usedTasks) {
t.myCancel(true);
}
}
}

View File

@@ -11,26 +11,43 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
* @author Florian Steurer * @author Florian Steurer
* *
*/ */
public final class ReferenceType extends UnifyType { public class ReferenceType extends UnifyType {
/** /**
* The buffered hashCode * The buffered hashCode
*/ */
private final int hashCode; private final int hashCode;
/**
* gibt an, ob der ReferenceType eine generische Typvariable ist
*/
private final boolean genericTypeVar;
public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) { public <T> UnifyType accept(UnifyTypeVisitor<T> visitor, T ht) {
return visitor.visit(this, ht); return visitor.visit(this, ht);
} }
public ReferenceType(String name, Boolean genericTypeVar) {
super(name, new TypeParams());
hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();
this.genericTypeVar = genericTypeVar;
}
public ReferenceType(String name, UnifyType... params) { public ReferenceType(String name, UnifyType... params) {
super(name, new TypeParams(params)); super(name, new TypeParams(params));
hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode(); hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();
genericTypeVar = false;
} }
public ReferenceType(String name, TypeParams params) { public ReferenceType(String name, TypeParams params) {
super(name, params); super(name, params);
hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode(); hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();
genericTypeVar = false;
}
public boolean isGenTypeVar () {
return genericTypeVar;
} }
@Override @Override

View File

@@ -137,7 +137,7 @@ public class UnifyPair {
undefinedPair = true; undefinedPair = true;
} }
public Set<UnifyPair> getSubstitution() { public Set<UnifyPair> getSubstitution() {
return substitution; return new HashSet<>(substitution);
} }
public UnifyPair getBasePair() { public UnifyPair getBasePair() {
@@ -149,9 +149,9 @@ public class UnifyPair {
public Set<UnifyPair> getAllSubstitutions () { public Set<UnifyPair> getAllSubstitutions () {
Set<UnifyPair> ret = new HashSet<>(); Set<UnifyPair> ret = new HashSet<>();
ret.addAll(getSubstitution()); ret.addAll(new ArrayList<>(getSubstitution()));
if (basePair != null) { if (basePair != null) {
ret.addAll(basePair.getAllSubstitutions()); ret.addAll(new ArrayList<>(basePair.getAllSubstitutions()));
} }
return ret; return ret;
} }

View File

@@ -37,14 +37,14 @@ public class BinaryTest {
public void test() throws Exception { public void test() throws Exception {
Method m2 = classToTest.getDeclaredMethod("m2", Integer.class,Integer.class); Method m2 = classToTest.getDeclaredMethod("m2", Integer.class,Integer.class);
Integer res = (Integer) m2.invoke(instanceOfClass, 2,3); Integer res = (Integer) m2.invoke(instanceOfClass, 2,3);
assertEquals(6, res); assertEquals(new Integer(6), res);
} }
@Test @Test
public void testM3() throws Exception { public void testM3() throws Exception {
Method m3 = classToTest.getDeclaredMethod("m3", Integer.class); Method m3 = classToTest.getDeclaredMethod("m3", Integer.class);
Integer res = (Integer) m3.invoke(instanceOfClass, 2); Integer res = (Integer) m3.invoke(instanceOfClass, 2);
assertEquals(4, res); assertEquals(new Integer(4), res);
} }
} }

View File

@@ -0,0 +1,37 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class ClassGenLamTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
private static ClassLoader loader;
private static Class<?> classToTest;
private static String pathToClassFile;
private static Object instanceOfClass;
@Test
public void generateBC() throws Exception {
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/ClassGenLam.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/";
compiler.generateBytecode(pathToClassFile);
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("ClassGenLam");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
}

View File

@@ -38,7 +38,7 @@ public class FacTest {
public void testInteger() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void testInteger() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method getFac = classToTest.getDeclaredMethod("getFac", Integer.class); Method getFac = classToTest.getDeclaredMethod("getFac", Integer.class);
Integer result = (Integer) getFac.invoke(instanceOfClass,3); Integer result = (Integer) getFac.invoke(instanceOfClass,3);
assertEquals(result, 6); assertEquals(result, new Integer(6));
} }
} }

View File

@@ -51,7 +51,7 @@ public class FacultyTest {
// Integer result = (Integer) apply.invoke(lambda,i); // Integer result = (Integer) apply.invoke(lambda,i);
Integer result = (Integer) getFact.invoke(instanceOfClass,i); Integer result = (Integer) getFact.invoke(instanceOfClass,i);
assertEquals(6, result); assertEquals(new Integer(6), result);
} }

View File

@@ -40,7 +40,7 @@ public class FieldTphConsMethTest {
Field a = classToTest.getDeclaredField("a"); Field a = classToTest.getDeclaredField("a");
a.setAccessible(true); a.setAccessible(true);
Method m = classToTest.getDeclaredMethod("m", Object.class); Method m = classToTest.getDeclaredMethod("id", Object.class);
Object result = m.invoke(instanceOfClass, 42); Object result = m.invoke(instanceOfClass, 42);
assertEquals(42,result); assertEquals(42,result);

View File

@@ -8,9 +8,10 @@ import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.core.JavaTXCompiler;
import org.junit.Test;
public class IdTest { public class IdTest {

View File

@@ -43,7 +43,7 @@ public class LambdaTest {
System.out.println(m.invoke(instanceOfClass).toString()); System.out.println(m.invoke(instanceOfClass).toString());
Integer result = (Integer) apply.invoke(m.invoke(instanceOfClass), i); Integer result = (Integer) apply.invoke(m.invoke(instanceOfClass), i);
assertEquals(77, result); assertEquals(i, result);
} }

View File

@@ -68,7 +68,6 @@ public class MatrixOpTest {
instanceOfClass_m2 = classToTest.getDeclaredConstructor(Vector.class).newInstance(vv1);//Matrix m2 = new Matrix(vv1); instanceOfClass_m2 = classToTest.getDeclaredConstructor(Vector.class).newInstance(vv1);//Matrix m2 = new Matrix(vv1);
//Matrix m3 = m1.mul(vv1); //Matrix m3 = m1.mul(vv1);
// Method mul = classToTest.getDeclaredMethod("mul", Vector.class); // Method mul = classToTest.getDeclaredMethod("mul", Vector.class);
// Object result = mul.invoke(instanceOfClass_m1, instanceOfClass_m2); // Object result = mul.invoke(instanceOfClass_m1, instanceOfClass_m2);

View File

@@ -85,7 +85,6 @@ public class MatrixTest {
res.addElement(v6); res.addElement(v6);
instanceOfClass_m3 = classToTest.getDeclaredConstructor(Vector.class).newInstance(res); instanceOfClass_m3 = classToTest.getDeclaredConstructor(Vector.class).newInstance(res);
assertEquals(result, instanceOfClass_m3); assertEquals(result, instanceOfClass_m3);
} }
} }

View File

@@ -12,7 +12,7 @@ import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.core.JavaTXCompiler;
public class FunOLTest { public class OLFunTest {
private static String path; private static String path;
private static File fileToTest; private static File fileToTest;
private static JavaTXCompiler compiler; private static JavaTXCompiler compiler;
@@ -23,13 +23,13 @@ public class FunOLTest {
@Test @Test
public void generateBC() throws Exception { public void generateBC() throws Exception {
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/FunOL.jav"; path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/OLFun.jav";
fileToTest = new File(path); fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest); compiler = new JavaTXCompiler(fileToTest);
compiler.generateBytecode(System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/"); compiler.generateBytecode(System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/");
pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/"; pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/";
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("FunOL"); classToTest = loader.loadClass("OLFun");
/* /*
instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); instanceOfClass = classToTest.getDeclaredConstructor().newInstance();

View File

@@ -7,11 +7,14 @@ import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader; import java.net.URLClassLoader;
import java.util.List;
import org.junit.BeforeClass; import org.junit.BeforeClass;
import org.junit.Test; import org.junit.Test;
import de.dhbwstuttgart.bytecode.genericsGeneratorTypes.GenericGenratorResultForSourceFile;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.core.JavaTXCompiler;
import de.dhbwstuttgart.typeinference.result.ResultSet;
public class OLTest { public class OLTest {
private static String path; private static String path;
@@ -30,7 +33,9 @@ public class OLTest {
fileToTest = new File(path); fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest); compiler = new JavaTXCompiler(fileToTest);
pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/"; pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/";
compiler.generateBytecode(pathToClassFile); List<ResultSet> typeinferenceResult = compiler.typeInference();
List<GenericGenratorResultForSourceFile> simplifyResultsForAllSourceFiles = compiler.getGeneratedGenericResultsForAllSourceFiles(typeinferenceResult);
compiler.generateBytecode(pathToClassFile,typeinferenceResult,simplifyResultsForAllSourceFiles);
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("OL"); classToTest = loader.loadClass("OL");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
@@ -47,14 +52,14 @@ public class OLTest {
public void testmInt() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void testmInt() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method m = classToTest.getDeclaredMethod("m", Integer.class); Method m = classToTest.getDeclaredMethod("m", Integer.class);
Integer result = (Integer) m.invoke(instanceOfClass, 5); Integer result = (Integer) m.invoke(instanceOfClass, 5);
assertEquals(10, result); assertEquals(new Integer(10), result);
} }
@Test @Test
public void testmDouble() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void testmDouble() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method m = classToTest.getDeclaredMethod("m", Double.class); Method m = classToTest.getDeclaredMethod("m", Double.class);
Double result = (Double) m.invoke(instanceOfClass, 5.0); Double result = (Double) m.invoke(instanceOfClass, 5.0);
assertEquals(10.0, result); assertEquals(new Double(10.0), result);
} }
@Test @Test
@@ -73,14 +78,14 @@ public class OLTest {
public void testmainInt() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void testmainInt() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method main = classToTest1.getDeclaredMethod("main", Integer.class); Method main = classToTest1.getDeclaredMethod("main", Integer.class);
Integer result = (Integer) main.invoke(instanceOfClass1, 5); Integer result = (Integer) main.invoke(instanceOfClass1, 5);
assertEquals(10, result); assertEquals(new Integer(10), result);
} }
@Test @Test
public void testmainDouble() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void testmainDouble() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method main = classToTest1.getDeclaredMethod("main", Double.class); Method main = classToTest1.getDeclaredMethod("main", Double.class);
Double result = (Double) main.invoke(instanceOfClass1, 5.0); Double result = (Double) main.invoke(instanceOfClass1, 5.0);
assertEquals(10.0, result); assertEquals(new Double(10.0), result);
} }
@Test @Test

View File

@@ -54,7 +54,7 @@ public class OpTest {
Integer result = (Integer) m.invoke(instanceOfClass, 7,3); Integer result = (Integer) m.invoke(instanceOfClass, 7,3);
assertEquals(10, result); assertEquals(new Integer(10), result);
} }

View File

@@ -38,28 +38,28 @@ public class PostIncTest {
public void testM1() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void testM1() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method m = classToTest.getDeclaredMethod("m"); Method m = classToTest.getDeclaredMethod("m");
Integer res = (Integer) m.invoke(instanceOfClass); Integer res = (Integer) m.invoke(instanceOfClass);
assertEquals(1, res); assertEquals(new Integer(1), res);
} }
@Test @Test
public void testM2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void testM2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method m = classToTest.getDeclaredMethod("m2"); Method m = classToTest.getDeclaredMethod("m2");
Integer res = (Integer) m.invoke(instanceOfClass); Integer res = (Integer) m.invoke(instanceOfClass);
assertEquals(0, res); assertEquals(new Integer(0), res);
} }
@Test @Test
public void testD1() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void testD1() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method m = classToTest.getDeclaredMethod("d"); Method m = classToTest.getDeclaredMethod("d");
Integer res = (Integer) m.invoke(instanceOfClass); Integer res = (Integer) m.invoke(instanceOfClass);
assertEquals(-1, res); assertEquals(new Integer(-1), res);
} }
@Test @Test
public void testD2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void testD2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method m = classToTest.getDeclaredMethod("d2"); Method m = classToTest.getDeclaredMethod("d2");
Integer res = (Integer) m.invoke(instanceOfClass); Integer res = (Integer) m.invoke(instanceOfClass);
assertEquals(0, res); assertEquals(new Integer(0), res);
} }
} }

View File

@@ -38,28 +38,28 @@ public class PreIncTest {
public void testM() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void testM() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method m = classToTest.getDeclaredMethod("m"); Method m = classToTest.getDeclaredMethod("m");
Integer res = (Integer) m.invoke(instanceOfClass); Integer res = (Integer) m.invoke(instanceOfClass);
assertEquals(1, res); assertEquals(new Integer(1), res);
} }
@Test @Test
public void testM2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void testM2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method m = classToTest.getDeclaredMethod("m2"); Method m = classToTest.getDeclaredMethod("m2");
Integer res = (Integer) m.invoke(instanceOfClass); Integer res = (Integer) m.invoke(instanceOfClass);
assertEquals(1, res); assertEquals(new Integer(1), res);
} }
@Test @Test
public void testD() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void testD() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method m = classToTest.getDeclaredMethod("d"); Method m = classToTest.getDeclaredMethod("d");
Integer res = (Integer) m.invoke(instanceOfClass); Integer res = (Integer) m.invoke(instanceOfClass);
assertEquals(-1, res); assertEquals(new Integer(-1), res);
} }
@Test @Test
public void testD2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void testD2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method m = classToTest.getDeclaredMethod("d2"); Method m = classToTest.getDeclaredMethod("d2");
Integer res = (Integer) m.invoke(instanceOfClass); Integer res = (Integer) m.invoke(instanceOfClass);
assertEquals(-1, res); assertEquals(new Integer(-1), res);
} }
} }

View File

@@ -0,0 +1,38 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class SimpleCycleTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
private static ClassLoader loader;
private static Class<?> classToTest;
private static String pathToClassFile;
private static Object instanceOfClass;
@Test
public void generateGen() throws Exception {
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/SimpleCycle.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/";
compiler.generateBytecode(pathToClassFile);
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("SimpleCycle");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
}

View File

@@ -39,7 +39,7 @@ public class TphTest {
Method m = classToTest.getDeclaredMethod("m", Object.class, Object.class); Method m = classToTest.getDeclaredMethod("m", Object.class, Object.class);
Object result = m.invoke(instanceOfClass, 1,2); Object result = m.invoke(instanceOfClass, 1,2);
assertEquals(2,result); assertEquals(1,result);
} }
@Test @Test
@@ -47,7 +47,7 @@ public class TphTest {
Method m = classToTest.getDeclaredMethod("m", Object.class, Object.class); Method m = classToTest.getDeclaredMethod("m", Object.class, Object.class);
Object result = m.invoke(instanceOfClass, 1, "sss"); Object result = m.invoke(instanceOfClass, 1, "sss");
assertEquals("sss",result); assertEquals(1,result);
} }
@Test @Test

View File

@@ -0,0 +1,38 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class TypedIDTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
private static ClassLoader loader;
private static Class<?> classToTest;
private static String pathToClassFile;
private static Object instanceOfClass;
@Test
public void test() throws Exception {
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/TypedID.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
compiler.generateBytecode(System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/");
pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/";
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("TypedID");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
}

View File

@@ -0,0 +1,38 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Vector;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class VectorAddTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
private static ClassLoader loader;
private static Class<?> classToTest;
private static String pathToClassFile;
private static Object instanceOfClass;
@Test
public void test() throws Exception {
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/VectorAdd.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/";
compiler.generateBytecode(pathToClassFile);
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("VectorAdd");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
}

View File

@@ -38,21 +38,21 @@ public class WhileTest {
public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method m = classToTest.getDeclaredMethod("m", Integer.class); Method m = classToTest.getDeclaredMethod("m", Integer.class);
Integer result = (Integer) m.invoke(instanceOfClass, 0); Integer result = (Integer) m.invoke(instanceOfClass, 0);
assertEquals(2, result); assertEquals(new Integer(2), result);
} }
@Test @Test
public void testDouble() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void testDouble() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method m = classToTest.getDeclaredMethod("m", Double.class); Method m = classToTest.getDeclaredMethod("m", Double.class);
Double result = (Double) m.invoke(instanceOfClass, 0.0); Double result = (Double) m.invoke(instanceOfClass, 0.0);
assertEquals(2.0, result); assertEquals(new Double(2.0), result);
} }
@Test @Test
public void testLong() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { public void testLong() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
Method m = classToTest.getDeclaredMethod("m", Long.class); Method m = classToTest.getDeclaredMethod("m", Long.class);
Long result = (Long) m.invoke(instanceOfClass, 0l); Long result = (Long) m.invoke(instanceOfClass, 0l);
assertEquals(2l, result); assertEquals(new Long(2l), result);
} }
} }

View File

@@ -25,11 +25,11 @@ public class YTest {
public void generateBC() throws Exception { public void generateBC() throws Exception {
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/Y.jav"; path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/Y.jav";
fileToTest = new File(path); fileToTest = new File(path);
// compiler = new JavaTXCompiler(fileToTest); compiler = new JavaTXCompiler(fileToTest);
// compiler.generateBytecode(System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/"); compiler.generateBytecode(System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/");
// pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/"; pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/";
// loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
// classToTest = loader.loadClass("Y"); classToTest = loader.loadClass("Y");
/* /*
instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); instanceOfClass = classToTest.getDeclaredConstructor().newInstance();

View File

@@ -1,3 +1,4 @@
package bytecode; package bytecode;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;

View File

@@ -0,0 +1,38 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class mathStrucIntegerTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
private static ClassLoader loader;
private static Class<?> classToTest;
private static String pathToClassFile;
private static Object instanceOfClass;
@Test
public void test() throws Exception {
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/mathStrucInteger.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
compiler.generateBytecode(System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/");
pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/";
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("mathStrucInteger");
//instanceOfClass = classToTest.getDeclaredConstructor(Integer.class).newInstance("A");
}
}

View File

@@ -0,0 +1,38 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.Field;
import java.net.URL;
import java.net.URLClassLoader;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class mathStrucTest {
private static String path;
private static File fileToTest;
private static JavaTXCompiler compiler;
private static ClassLoader loader;
private static Class<?> classToTest;
private static String pathToClassFile;
private static Object instanceOfClass;
@Test
public void test() throws Exception {
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/mathStruc.jav";
fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest);
compiler.generateBytecode(System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/");
pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/";
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("mathStruc");
instanceOfClass = classToTest.getDeclaredConstructor(Object.class).newInstance("A");
}
}

View File

@@ -1,77 +0,0 @@
/**
*
*/
package bytecode.simplifyalgo;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import org.junit.BeforeClass;
import org.junit.Test;
import org.objectweb.asm.Type;
import de.dhbwstuttgart.bytecode.TPHExtractor;
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
import de.dhbwstuttgart.bytecode.utilities.Simplify;
/**
* @author Fayez Abu Alia
*
*/
public class CycleTest {
private static TPHExtractor tphExtractor;
private static String methName;
/**
* @throws java.lang.Exception
*/
@BeforeClass
public static void setUpBeforeClass() throws Exception {
tphExtractor = new TPHExtractor();
// A < B
TPHConstraint c1 = new ExtendsConstraint("A", "B", Relation.EXTENDS);
// B < C
TPHConstraint c2 = new ExtendsConstraint("B", "C", Relation.EXTENDS);
// C < D
TPHConstraint c3 = new ExtendsConstraint("C", "D", Relation.EXTENDS);
// D < A
TPHConstraint c4 = new ExtendsConstraint("D", "A", Relation.EXTENDS);
// name
methName = "m";
MethodAndTPH mtph = new MethodAndTPH("m");
mtph.getTphs().add("A");
mtph.getTphs().add("B");
mtph.getTphs().add("C");
mtph.getTphs().add("D");
tphExtractor.ListOfMethodsAndTph.add(mtph);
tphExtractor.allCons.add(c1);
tphExtractor.allCons.add(c2);
tphExtractor.allCons.add(c3);
tphExtractor.allCons.add(c4);
}
@Test
public void test() {
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
HashSet<String> equals = new HashSet<>();
equals.add("A");
equals.add("B");
equals.add("C");
equals.add("D");
TPHConstraint k = new ExtendsConstraint("A", Type.getInternalName(Object.class), Relation.EXTENDS);
result.put(k, equals);
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor,new ArrayList<>());
boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
assertTrue(areEquals);
}
}

View File

@@ -1,64 +0,0 @@
package bytecode.simplifyalgo;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import org.junit.BeforeClass;
import org.junit.Test;
import org.objectweb.asm.Type;
import de.dhbwstuttgart.bytecode.TPHExtractor;
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.utilities.ConstraintsFinder;
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
import de.dhbwstuttgart.bytecode.utilities.Simplify;
import de.dhbwstuttgart.typedeployment.TypeInsertPlacer;
/**
*
* @author Fayez Abu Alia
*
*/
public class FinderTest {
@Test
public void testM1() {
List<TPHConstraint> allCons = new ArrayList<>();
// L < M
TPHConstraint c1 = new ExtendsConstraint("L", "M", Relation.EXTENDS);
// L < N
TPHConstraint c2 = new ExtendsConstraint("L", "N", Relation.EXTENDS);
// M < O
TPHConstraint c3 = new ExtendsConstraint("M", "O", Relation.EXTENDS);
// M < P
TPHConstraint c4 = new ExtendsConstraint("M", "P", Relation.EXTENDS);
allCons.add(c1);
allCons.add(c2);
allCons.add(c3);
allCons.add(c4);
List<List<TPHConstraint>> res = new ArrayList<>();
List<TPHConstraint> l1 = new ArrayList<>();
List<TPHConstraint> l2 = new ArrayList<>();
l1.add(c1);
l1.add(c2);
l2.add(c3);
l2.add(c4);
res.add(l1);
res.add(l2);
ConstraintsFinder finder = new ConstraintsFinder(allCons);
assertEquals(finder.findConstraints(), res);
}
}

View File

@@ -1,102 +0,0 @@
package bytecode.simplifyalgo;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import org.junit.BeforeClass;
import org.junit.Test;
import org.objectweb.asm.Type;
import de.dhbwstuttgart.bytecode.TPHExtractor;
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
import de.dhbwstuttgart.bytecode.utilities.Simplify;
import de.dhbwstuttgart.typedeployment.TypeInsertPlacer;
/**
*
* @author Fayez Abu Alia
*
*/
public class SameLeftSide {
// Typeplaceholders können nicht definiert werden, da die Konstruktor
// private ist => Test geht nicht
private static TPHExtractor tphExtractor;
private static String methName;
private static String methName2;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
tphExtractor = new TPHExtractor();
// A < B
TPHConstraint c1 = new ExtendsConstraint("A", "B", Relation.EXTENDS);
// A < C
TPHConstraint c2 = new ExtendsConstraint("A", "C", Relation.EXTENDS);
// B < D
TPHConstraint c3 = new ExtendsConstraint("B", "D", Relation.EXTENDS);
// C < E
TPHConstraint c4 = new ExtendsConstraint("C", "E", Relation.EXTENDS);
// name
methName = "m1";
MethodAndTPH m1 = new MethodAndTPH("m1");
methName2 = "m2";
MethodAndTPH m2 = new MethodAndTPH("m2");
m1.getTphs().add("A");
m1.getTphs().add("B");
m1.getTphs().add("D");
m2.getTphs().add("C");
m2.getTphs().add("E");
tphExtractor.ListOfMethodsAndTph.add(m1);
tphExtractor.ListOfMethodsAndTph.add(m2);
tphExtractor.allCons.add(c1);
tphExtractor.allCons.add(c2);
tphExtractor.allCons.add(c3);
tphExtractor.allCons.add(c4);
}
@Test
public void testM1() {
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
TPHConstraint d = new ExtendsConstraint("D", Type.getInternalName(Object.class), Relation.EXTENDS);
TPHConstraint a = new ExtendsConstraint("A", "D", Relation.EXTENDS);
TPHConstraint b = new ExtendsConstraint("B", "D", Relation.EXTENDS);
result.put(d, new HashSet<>());
result.put(a, new HashSet<>());
HashSet<String> hs = new HashSet<>();
result.put(b, hs);
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor,new ArrayList<>());
boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
assertTrue(areEquals);
}
@Test
public void testM2() {
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
TPHConstraint e = new ExtendsConstraint("E", Type.getInternalName(Object.class), Relation.EXTENDS);
TPHConstraint c = new ExtendsConstraint("C", "E", Relation.EXTENDS);
result.put(e, new HashSet<>());
HashSet<String> hs = new HashSet<>();
hs.add("B");
result.put(c, hs);
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName2, tphExtractor,new ArrayList<>());
boolean areEquals = SimpleCycle.areMapsEqual(result, sim);
assertTrue(areEquals);
}
}

View File

@@ -1,80 +0,0 @@
package bytecode.simplifyalgo;
import static org.junit.Assert.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import org.junit.BeforeClass;
import org.junit.Test;
import org.objectweb.asm.Type;
import de.dhbwstuttgart.bytecode.TPHExtractor;
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.utilities.Simplify;
/**
*
* @author Fayez Abu Alia
*
*/
public class SimpleCycle {
private static TPHExtractor tphExtractor;
private static String methName;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
tphExtractor = new TPHExtractor();
// A < B
TPHConstraint c1 = new ExtendsConstraint("A", "B", Relation.EXTENDS);
// B < A
TPHConstraint c2 = new ExtendsConstraint("B", "A", Relation.EXTENDS);
// name
methName = "m";
tphExtractor.allCons.add(c1);
tphExtractor.allCons.add(c2);
}
@Test
public void test() {
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
HashSet<String> equals = new HashSet<>();
equals.add("A");
equals.add("B");
TPHConstraint k = new ExtendsConstraint("B", Type.getInternalName(Object.class), Relation.EXTENDS);
result.put(k, equals);
HashMap<TPHConstraint, HashSet<String>> sim = Simplify.simplifyConstraints(methName, tphExtractor,new ArrayList<>());
boolean areEquals = areMapsEqual(result, sim);
assertTrue(areEquals);
}
public static boolean areMapsEqual(HashMap<TPHConstraint, HashSet<String>> m1, HashMap<TPHConstraint, HashSet<String>> m2) {
for(TPHConstraint c : m1.keySet()) {
for(TPHConstraint c2 : m2.keySet()) {
if(c.getLeft().equals(c2.getLeft()) && c.getRight().equals(c2.getRight()) && c.getRel()==c2.getRel()) {
HashSet<String> eq1 = m1.get(c);
HashSet<String> eq2 = m2.get(c2);
if((eq1 == null && eq2 != null) || (eq1 != null && eq2 == null))
return false;
if(eq1 != null) {
if(eq1.size() != eq2.size())
return false;
for(String tph:eq1) {
if(!eq2.contains(tph))
return false;
}
}
}
}
}
return true;
}
}

View File

@@ -0,0 +1,8 @@
import java.lang.Integer;
public class ClassGenLam {
lam = x-> x;
// public ClassGenLam() {
// lam = x->x;
// }
}

View File

@@ -1,4 +1,6 @@
import java.lang.Integer; import java.lang.Integer;
//import java.lang.Long;
//import java.lang.Short;
public class Faculty { public class Faculty {
public fact; public fact;
@@ -14,9 +16,11 @@ public class Faculty {
} }
public getFact(x) { public getFact(x) {
return fact.apply(x); return fact.apply(x);
} }
}
// m (x) { // m (x) {
// //
//// var fact = (x) -> { //// var fact = (x) -> {
@@ -45,4 +49,4 @@ public class Faculty {
// return x * m(x-1); // return x * m(x-1);
// } // }
// } // }
} //}

View File

@@ -2,10 +2,25 @@ public class FieldTphConsMeth {
a; a;
public FieldTphConsMeth(c) { public FieldTphConsMeth(c) {
a = m(c); a = id(c);
} }
m(b) { id(b) {
return b; return b;
} }
/*setA(x) {
a = x;
return a;
}*/
m(x,y) {
x = id(y);
}
/*m2(x,y) {
x = setA(y);
return x;
}*/
} }

View File

@@ -1,6 +1,20 @@
public class Id<FTU extends FTT,FTT> { public class Id {
// a;
// id(b){
// return b;
// }
id2 = x -> x;
// id2 = () -> {
// var x = m(a);
// var y = x;
// var z = y;
// };
//
// m(a){
// return a;
// }
id3 (x) {
return id2.apply(x);
}
}
id(FTU b){
return b;
}
}

View File

@@ -8,3 +8,4 @@ public class Lambda {
}; };
return lam1; return lam1;
} }
}

View File

@@ -19,7 +19,7 @@ public class Matrix extends Vector<Vector<Integer>> {
} }
} }
mul(java.util.Vector<? extends Vector<? extends java.lang.Integer>> m) { mul(m) {
var ret = new Matrix(); var ret = new Matrix();
var i = 0; var i = 0;
while(i < size()) { while(i < size()) {

View File

@@ -1,6 +1,6 @@
import java.util.Vector; import java.util.Vector;
import java.lang.Integer; import java.lang.Integer;
import java.lang.Byte; //import java.lang.Byte;
import java.lang.Boolean; import java.lang.Boolean;
public class MatrixOP extends Vector<Vector<Integer>> { public class MatrixOP extends Vector<Vector<Integer>> {
@@ -18,7 +18,7 @@ public class MatrixOP extends Vector<Vector<Integer>> {
} }
} }
Fun2$$<java.util.Vector<? extends java.util.Vector<? extends java.lang.Byte>>, java.util.Vector<? extends java.util.Vector<? extends java.lang.Byte>>, MatrixOP> mul = (m1, m2) -> { public mul = (m1, m2) -> {
var ret = new MatrixOP(); var ret = new MatrixOP();
var i = 0; var i = 0;
while(i < m1.size()) { while(i < m1.size()) {

View File

@@ -1,17 +1,26 @@
import java.lang.String; import java.lang.String;
import java.lang.Integer; import java.lang.Integer;
import java.lang.Double; import java.lang.Double;
import java.lang.Boolean;
//import java.util.Vector;
public class OL { public class OL {
m(x) { return x + x; } m(x) { return x + x; }
m(Boolean x) { return x; }
// if the class contains just this method, then correct BC will be generated.
// But if another methods are contained then the generated BC is not correct
// m(x) {
// //x.add(1);
// x.addAll(x);
// return x;
// }
} }
public class OLMain { public class OLMain {
main(x) { main(x) {

View File

@@ -0,0 +1,17 @@
import java.lang.String;
import java.lang.Integer;
import java.lang.Double;
import java.util.Vector;
import java.lang.Boolean;
public class OLFun {
//f = x -> {return x + x;};
m(f, x) {
x = f.apply(x+x);
}
}

View File

@@ -0,0 +1,25 @@
public class SimpleCycle {
m(a,b,d){
/* var g;
var h;
g = h;
h = g;
var y;
var z;
y=z;
z=y;
var j = z;
var x;
b = a;
var c = b;
var f = d;
b = x;
var l = c;
a = l; */
}
}

View File

@@ -7,17 +7,17 @@ public class Sorting{
a.addAll(b); a.addAll(b);
return a; return a;
} }
/*
sort(in){ sort(in){
var firstHalf = in; var firstHalf = in;
var secondHalf = in; var secondHalf = in;
return merge(sort(firstHalf), sort(secondHalf)); return merge(sort(firstHalf), sort(secondHalf));
} }
*/
/*
void sort(a){ void sort(a){
a = merge(a,a); a = merge(a,a);
} }
*/
} }

Some files were not shown because too many files have changed in this diff Show More