1
0

Compare commits

...

85 Commits

Author SHA1 Message Date
Martin Plümicke
84c7d728c5 modified: ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
modified:   ../../resources/bytecode/javFiles/Faculty.jav
	modified:   ../../resources/bytecode/javFiles/MatrixOP.jav
2019-04-26 12:03:57 +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
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
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
Martin Plümicke
0f1526daa2 modified: ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
deleted:    .gitignore
2019-03-28 15:44:03 +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
Martin Plümicke
4ba4292db4 Merge branch 'unify-test' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bigRefactoring 2019-03-20 16:30:21 +01:00
Martin Plümicke
57b5a51895 modified: ../../../main/java/de/dhbwstuttgart/core/JavaTXCompiler.java 2019-03-20 16:24:55 +01:00
Martin Plümicke
986ce8e6e0 modified: ../../../main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java
	modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java
	modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
2019-03-20 14:35:50 +01:00
Martin Plümicke
8a6646bd7c modified: ../../../main/java/de/dhbwstuttgart/core/JavaTXCompiler.java 2019-03-20 13:00:08 +01:00
Martin Plümicke
01a548215a Merge branch 'bytecode2' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bigRefactoring 2019-03-20 12:53:35 +01:00
Martin Plümicke
66cd1e7012 modified: ../../bytecode/javFiles/MatrixOP.jav 2019-03-20 12:45:17 +01:00
Martin Plümicke
850fe39426 modified: ../../../main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java
Typen mit Argumenten korrgiert
2019-03-19 16:31:04 +01:00
Martin Plümicke
212aeaa3a0 modified: ../../../main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
2019-03-18 16:14:13 +01:00
Michael Uhl
7cb2eed36e Logger comes from plugin now. 2019-03-18 09:33:22 +01:00
Martin Plümicke
82f330eab5 modified: ../../../main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
	modified:   ../../resources/bytecode/javFiles/Matrix.jav
2019-03-17 17:44:09 +01:00
Michael Uhl
f25ba4d13e Merge remote-tracking branch 'origin/bytecode2' into bytecode2 2019-03-15 10:53:10 +01:00
Michael Uhl
4d4be5420b Anpassung asynchroner Aufruf des Plugins
========================================

UnifyResultListener muss übergeben werden, da sonst Ergebnisse gemeldet werden (notify), ohne dass das Plugin als UnifyResultListener registriert wurde.
2019-03-15 10:52:31 +01:00
Martin Plümicke
a01779d6df modified: ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
auskommentierter Code der nach checkA verschoben wurde geloescht
2019-03-14 00:27:21 +01:00
Martin Plümicke
44ed1d8e8d modified: ../../../main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java
	modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
Die Ueberpruefung von a bzw. nSaL in Methode checkA ausgelagert und für die Faelle a <. th und ty <. a implementiert.
2019-03-14 00:20:19 +01:00
Martin Plümicke
75adbaf579 Merge branch 'bigRefactoring' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into unify-test 2019-03-07 13:45:03 +01:00
Martin Plümicke
411629279d modified: ../../../main/java/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java
Kommentar eingefuegt
2019-03-07 13:44:29 +01:00
Martin Plümicke
47783083b0 Merge branch 'bigRefactoring' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into unify-test
Conflicts:
	src/main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java

 It looks like you may be committing a merge.
 If this is not correct, please remove the file
	.git/MERGE_HEAD
 and try again.
2019-03-07 13:42:26 +01:00
Martin Plümicke
94c32609c6 modified: ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
disableCondWildcards wird aufgerufen

	modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java
/**
	 * wenn in einem  Paar bestehend aus 2 Typvariablen eine nicht wildcardtable ist,
	 * so beide auf nicht wildcardtable setzen
	 */
	public void disableCondWildcards()
eingefuegt
2019-03-07 13:37:08 +01:00
Martin Plümicke
6175fb3ee3 modified: ../../../../main/java/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java 2019-03-07 09:17:05 +01:00
Martin Plümicke
2bd6147517 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/model/OrderingUnifyPair.java
	modified:   ../../../../main/java/de/dhbwstuttgart/typeinference/unify/model/UnifyPair.java
Noch einige Fehler
2019-03-07 09:14:41 +01:00
Martin Plümicke
728b729f08 modified: ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
in calculatePairSets werden andere Constraints fuer die gleiche Variable betrachtet
Sollte aber nach computeCartesianRecursive verschoben werden.
2019-03-05 00:24:11 +01:00
Martin Plümicke
27c6351aed modified: ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
Anfang Paare zusammenfassen
2019-03-01 16:52:59 +01:00
Martin Plümicke
fc14cf9893 modified: ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
subst-Anwendung gleich am Anfang von unify eingefuehrt
2019-02-28 18:29:08 +01:00
Martin Plümicke
b46e0b855c modified: ../../resources/bytecode/javFiles/MatrixOP.jav 2019-02-28 15:38:30 +01:00
Martin Plümicke
88ec8823fd modified: ../../../main/java/de/dhbwstuttgart/parser/SyntaxTreeGenerator/TypeGenerator.java
modified:   ../../../main/java/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java
	deleted:    ../../../main/java/de/dhbwstuttgart/syntaxtree/type/FunN.java
	modified:   ../../../main/java/de/dhbwstuttgart/typeinference/assumptions/FunNClass.java
	modified:   ../../../main/java/de/dhbwstuttgart/typeinference/assumptions/MethodAssumption.java
	modified:   ../../../main/java/de/dhbwstuttgart/typeinference/typeAlgo/TYPEStmt.java
	modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/model/FunNType.java
Es wird jetzt FunN-Type FunN$$ geparst
Der Typ FunN wurde entfernt
Der Name des Typs FunNType wurde um $$ am Ende ergänzt
2019-02-27 16:04:55 +01:00
Fayez Abu Alia
c77a2b3354 Merge branch 'bytecode2' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bytecode2 2019-02-25 19:20:43 +01:00
Fayez Abu Alia
8a5dbb28ac Bug gefixt: genericList als Paramater uebergeben 2019-02-25 19:20:11 +01:00
Michael Uhl
86768153c0 Merge remote-tracking branch 'origin/bytecode2' into bytecode2 2019-02-24 15:06:49 +01:00
Michael Uhl
5722f0285b Skip tests in maven build. 2019-02-24 15:06:34 +01:00
Fayez Abu Alia
6c19a9f78c Merge branch 'bytecode2' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bytecode2 2019-02-21 13:35:07 +01:00
Fayez Abu Alia
3e186334a2 Simpify Algo korrigiert so dass die lokalen Variablen der Methode beruecksichtigt werden 2019-02-21 13:34:36 +01:00
Martin Plümicke
fcad60996c modified: de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java 2019-02-20 17:53:45 +01:00
Martin Plümicke
9c648546e4 modified: de/dhbwstuttgart/core/JavaTXCompiler.java
modified:   de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java
	modified:   de/dhbwstuttgart/typeinference/unify/RuleSet.java
	modified:   de/dhbwstuttgart/typeinference/unify/TypeUnify.java
	modified:   de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java
	modified:   de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
FileWriter durch Writer ersetzt
2019-02-20 17:36:07 +01:00
Martin Plümicke
8e4b39b05e modified: ../../test/resources/bytecode/javFiles/Inf.jav 2019-02-20 16:03:56 +01:00
Martin Plümicke
926d911d21 modified: ../bytecode/MatrixTest.java 2019-02-20 15:08:06 +01:00
Fayez Abu Alia
d010c843df Bug in MatrixTest gefixt. Die richtige Descriptor von MethodCalls wird erzeugt 2019-02-20 12:15:55 +01:00
Martin Plümicke
72705ac868 modified: ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify2Task.java
modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
close log-Files
TypeUnifyTask in TypeUnify2Task bei Abarbeitung oderconstraints umgetauscht
2019-02-20 09:40:06 +01:00
Martin Plümicke
362e797b10 modified: ../../../main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
2019-02-19 17:51:11 +01:00
Martin Plümicke
1f12aaec82 modified: ../../../main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java
	modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
	modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/model/FiniteClosure.java
	modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/model/OrderingUnifyPair.java
Einen Fall ? extends/super a <.? a ergaenzt bei dem compare falsches Ergbnis geliefret hat
2019-02-18 22:36:06 +01:00
Martin Plümicke
08d69ce6e3 modified: ../../../main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnify.java
	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/UnifyResultModel.java

zurueckumwandlung von den Unifytypen in UnifyResultModel verlegt.
2019-02-17 08:51:23 +01:00
Martin Plümicke
396efb52de modified: ../../../main/java/de/dhbwstuttgart/typeinference/unify/RuleSet.java
modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/TypeUnifyTask.java
	modified:   ../../../main/java/de/dhbwstuttgart/typeinference/unify/interfaces/IRuleSet.java
subst-Anwendung auf oderconstraints eingebaut
2019-02-15 00:00:41 +01:00
Fayez Abu Alia
67469bbb84 Merge branch 'bytecode2' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bytecode2 2019-02-14 11:44:37 +01:00
Fayez Abu Alia
d2581b02ab modified: src/main/java/de/dhbwstuttgart/bytecode/BytecodeGenMethod.java
Bug in generate BC fuer if(Boolean) gefixt

	modified:   src/main/java/de/dhbwstuttgart/bytecode/signature/Signature.java

	new file:   src/main/java/de/dhbwstuttgart/bytecode/utilities/ConstraintsFinder.java
	Fasst alle Constraints mit der gleichen Linke-Seite in einer Liste zusammen

	new file:   src/main/java/de/dhbwstuttgart/bytecode/utilities/NameReplacer.java
	Ersetzt die gleiche Type Variables durch einen neuen eindeutigen Namen

	modified:   src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java
	Algorithmus angepasst

	modified:   src/test/java/bytecode/FieldTphMMethTest.java
	Test funktioniert
	new file:   src/test/java/bytecode/InfTest.java
	Infimum Test funktioniert

	new file:   src/test/java/bytecode/simplifyalgo/FinderTest.java
	Tests fuer die HilfsMethoden
2019-02-14 11:37:15 +01:00
Michael Uhl
28c6f78715 Merge branch 'unify-test' into bytecode2 2019-02-02 15:50:34 +01:00
Michael Uhl
2eaebbf0f8 FileWriter -> Writer. 2019-02-01 22:56:30 +01:00
Michael Uhl
1e5e9f8cd4 Merge remote-tracking branch 'origin/bytecode2' into bytecode2 2019-02-01 22:15:28 +01:00
Michael Uhl
9805f956c0 Merge remote-tracking branch 'origin/bytecode2' into bytecode2
# Conflicts:
#	pom.xml
2019-01-23 22:05:59 +01:00
Michael Uhl
0a4a625198 Removed "tycho-p2-repository-plugin". 2019-01-23 22:04:25 +01:00
Fayez Abu Alia
fd72ed340d Test Erzeugung Type-Variablen fuer Klassen 2019-01-17 11:26:09 +01:00
Fayez Abu Alia
d6961b0d0b Merge branch 'unify-test' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into bytecode2 2019-01-16 14:42:07 +01:00
Fayez Abu Alia
d4d668b662 Simplify fuer Klassen Type Variablen 2019-01-16 14:41:33 +01:00
67 changed files with 3019 additions and 1179 deletions

18
pom.xml

@@ -7,7 +7,7 @@ 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>
@@ -55,6 +55,14 @@ http://maven.apache.org/maven-v4_0_0.xsd">
<finalName>${project.artifactId}-${project.version}</finalName> <finalName>${project.artifactId}-${project.version}</finalName>
<testOutputDirectory>target/test-classes</testOutputDirectory> <testOutputDirectory>target/test-classes</testOutputDirectory>
<plugins> <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M3</version>
<configuration>
<skipTests>true</skipTests>
</configuration>
</plugin>
<plugin> <plugin>
<groupId>org.antlr</groupId> <groupId>org.antlr</groupId>
<artifactId>antlr4-maven-plugin</artifactId> <artifactId>antlr4-maven-plugin</artifactId>
@@ -119,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>
@@ -138,10 +146,6 @@ http://maven.apache.org/maven-v4_0_0.xsd">
</execution> </execution>
</executions> </executions>
</plugin> </plugin>
<!-- plugin> <groupId>org.eclipse.tycho</groupId> <artifactId>tycho-p2-repository-plugin</artifactId>
<version>${tycho.version}</version> <executions> <execution> <phase>package</phase>
<goals> <goal>archive-repository</goal> </goals> </execution> </executions>
</plugin -->
</plugins> </plugins>
</build> </build>
<pluginRepositories> <pluginRepositories>
@@ -169,5 +173,3 @@ http://maven.apache.org/maven-v4_0_0.xsd">
</repository> </repository>
</distributionManagement> </distributionManagement>
</project> </project>

@@ -17,6 +17,7 @@ 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.Exception.BytecodeGeneratorError;
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;
@@ -29,6 +30,7 @@ import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
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.Simplify;
import de.dhbwstuttgart.bytecode.utilities.SimplifyResult;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.Literal; import de.dhbwstuttgart.syntaxtree.statement.Literal;
@@ -44,11 +46,11 @@ 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 {
ClassWriter cw =new ClassWriter(ClassWriter.COMPUTE_FRAMES|ClassWriter.COMPUTE_MAXS); ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
String type; String type;
public static RefTypeOrTPHOrWildcardOrGeneric THISTYPE = null; public static RefTypeOrTPHOrWildcardOrGeneric THISTYPE = null;
String className; String className;
private boolean isInterface; private boolean isInterface;
@@ -56,185 +58,222 @@ public class BytecodeGen implements ASTVisitor {
private ResultSet resultSet; private ResultSet resultSet;
private SourceFile sf; private SourceFile sf;
private String path; private String path;
private Optional<Constructor> fieldInitializations; private Optional<Constructor> fieldInitializations;
private int indexOfFirstParam = 0; private int indexOfFirstParam = 0;
private String superClass; private String superClass;
private ArrayList<TypePlaceholder> tphsClass; private ArrayList<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 TPHExtractor tphExtractor = new TPHExtractor();
private final ArrayList<GenericInsertPair> commonPairs = new ArrayList<>(); 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 HashMap<String, SimplifyResult> simplifyResults = new HashMap<>();
private List<HashMap<String, SimplifyResult>> simplifyResultsList = new ArrayList<>();
private final ArrayList<String> fieldNameSignature = new ArrayList<>();
public List<HashMap<String, SimplifyResult>> getSimplifyResultsList() {
return simplifyResultsList;
}
public void setSimplifyResultsList(List<HashMap<String, SimplifyResult>> simplifyResultsList) {
this.simplifyResultsList = simplifyResultsList;
}
public BytecodeGen(HashMap<String, byte[]> classFiles, List<ResultSet> listOfResultSets, SourceFile sf,
String path) {
this.classFiles = classFiles; this.classFiles = classFiles;
this.listOfResultSets = listOfResultSets; this.listOfResultSets = listOfResultSets;
this.sf = sf; this.sf = sf;
this.path = path; this.path = path;
} }
@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, sf, path);
cl.accept(classGen); cl.accept(classGen);
simplifyResultsList.add(classGen.getSimplifyResults());
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 the bytecode is to be associated
*/ */
private void writeClass(String name) { private void writeClass(String name) {
bytecode = cw.toByteArray(); bytecode = cw.toByteArray();
classFiles.put(name, bytecode); classFiles.put(name, bytecode);
} }
public HashMap<String,byte[]> getClassFiles() { public HashMap<String, byte[]> getClassFiles() {
return classFiles; return classFiles;
} }
@Override @Override
public void visit(ClassOrInterface classOrInterface) { public void visit(ClassOrInterface classOrInterface) {
className = classOrInterface.getClassName().toString();
cw.visitSource(className +".jav", null);
isInterface = (classOrInterface.getModifiers()&512)==512;
int acc = isInterface?classOrInterface.getModifiers()+Opcodes.ACC_ABSTRACT:classOrInterface.getModifiers()+Opcodes.ACC_SUPER; className = classOrInterface.getClassName().toString();
cw.visitSource(className + ".jav", null);
isInterface = (classOrInterface.getModifiers() & 512) == 512;
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 isConsWithNoParamsVisited = false;
boolean isVisited = false; boolean isVisited = false;
for(ResultSet rs : listOfResultSets) { for (ResultSet rs : listOfResultSets) {
superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()); superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor());
resultSet = rs; resultSet = rs;
tphExtractor.setResultSet(resultSet); tphExtractor.setResultSet(resultSet);
// Nur einmal ausführen!! // Nur einmal ausführen!!
if(!isVisited) { if (!isVisited) {
classOrInterface.accept(tphExtractor); classOrInterface.accept(tphExtractor);
getCommonTPHS(tphExtractor); getCommonTPHS(tphExtractor);
tphsClass = new ArrayList<>(); tphsClass = new ArrayList<>();
for(TypePlaceholder t : tphExtractor.allTPHS.keySet()) { for (String t : tphExtractor.allTPHS.keySet()) {
if(!tphExtractor.allTPHS.get(t)) if (!tphExtractor.allTPHS.get(t))
tphsClass.add(t); tphsClass.add(t);
} }
ArrayList<TPHConstraint> consClass = new ArrayList<>();
for(TPHConstraint cons : tphExtractor.allCons) {
TypePlaceholder right = null;
for(TypePlaceholder tph : tphsClass) {
if(cons.getLeft().equals(tph.getName())) {
consClass.add(cons);
right = getTPH(cons.getRight());
}
}
if(right != null) {
tphsClass.add(right);
removeFromMethod(right.getName());
right = null;
}
}
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() || !commonPairs.isEmpty()
classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<") || classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<")
|| !tphsClass.isEmpty()) { || !tphsClass.isEmpty()) {
Signature signature = new Signature(classOrInterface, genericsAndBounds,commonPairs,tphsClass, consClass); HashMap<TPHConstraint, HashSet<String>> constraints = Simplify
.simplifyConstraintsClass(tphExtractor, tphsClass);
ArrayList<TPHConstraint> consClass = new ArrayList<>();
for (TPHConstraint cons : constraints.keySet()) {
String right = null;
boolean isToAdd = false;
for (String tph : tphsClass) {
if (cons.getLeft().equals(tph)) {
consClass.add(cons);
try {
right = getTPH(cons.getRight());
isToAdd = true;
} catch (NoSuchElementException e) {
continue;
}
}
}
if (isToAdd) {
tphsClass.add(right);
removeFromMethod(right);
right = null;
isToAdd = false;
}
// if(right != null) {
// tphsClass.add(right);
// removeFromMethod(right);
// right = null;
// }
}
SimplifyResult sRes = new SimplifyResult(consClass, tphsClass, new HashMap<>());
simplifyResults.put(className, sRes);
Signature signature = new Signature(classOrInterface, genericsAndBounds, commonPairs, tphsClass,
consClass);
sig = signature.toString(); 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;
} }
for(Field f : classOrInterface.getFieldDecl()) { for (Field f : classOrInterface.getFieldDecl()) {
f.accept(this); f.accept(this);
} }
for(Constructor c : classOrInterface.getConstructors()) { for (Constructor c : classOrInterface.getConstructors()) {
// if(!isConsWithNoParamsVisited) { // if(!isConsWithNoParamsVisited) {
c.accept(this); c.accept(this);
// } // }
// if(!c.getParameterList().iterator().hasNext()) // if(!c.getParameterList().iterator().hasNext())
// isConsWithNoParamsVisited = true; // isConsWithNoParamsVisited = true;
} }
for(Method m : classOrInterface.getMethods()) { for (Method m : classOrInterface.getMethods()) {
m.accept(this); m.accept(this);
} }
} }
} }
private void removeFromMethod(String name) { private void removeFromMethod(String name) {
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) { for (MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
ArrayList<String> toRemove = new ArrayList<>(); ArrayList<String> toRemove = new ArrayList<>();
for(String tph : m.getTphs()) { for (String tph : m.getTphs()) {
if(tph.equals(name)) { if (tph.equals(name)) {
toRemove.add(tph); toRemove.add(tph);
} }
} }
if(!toRemove.isEmpty()) { if (!toRemove.isEmpty()) {
m.getTphs().removeAll(toRemove); m.getTphs().removeAll(toRemove);
return; return;
} }
} }
} }
private TypePlaceholder getTPH(String name) { private String getTPH(String name) {
for(TypePlaceholder tph: tphExtractor.allTPHS.keySet()) { for (String tph : tphExtractor.allTPHS.keySet()) {
if(tph.getName().equals(name)) if (tph.equals(name))
return tph; return tph;
} }
throw new NoSuchElementException("TPH "+name +" does not exist"); throw new NoSuchElementException("TPH " + name + " does not exist");
} }
private void getCommonTPHS(TPHExtractor tphExtractor) { private void getCommonTPHS(TPHExtractor tphExtractor) {
// Gemeinsame TPHs // Gemeinsame TPHs
ArrayList<TypePlaceholder> cTPHs = new ArrayList<>(); ArrayList<String> cTPHs = new ArrayList<>();
// Alle TPHs der Felder speichern // Alle TPHs der Felder speichern
for(TypePlaceholder tph : tphExtractor.allTPHS.keySet()) { for (String tph : tphExtractor.allTPHS.keySet()) {
if(!tphExtractor.allTPHS.get(tph)) if (!tphExtractor.allTPHS.get(tph))
cTPHs.add(tph); cTPHs.add(tph);
} }
} }
@@ -242,156 +281,179 @@ public class BytecodeGen implements ASTVisitor {
@Override @Override
public void visit(Constructor field) { public void visit(Constructor field) {
System.out.println("ResultSet: "); System.out.println("ResultSet: ");
resultSet.results.forEach(a->{ resultSet.results.forEach(a -> {
System.out.println(a.getLeft().toString() + " = " + a.getRight().toString()); System.out.println(a.getLeft().toString() + " = " + a.getRight().toString());
}); });
System.out.println("---------------"); 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 methParamTypes = field.name + "%%";
Iterator<FormalParameter> itr = field.getParameterList().iterator(); Iterator<FormalParameter> itr = field.getParameterList().iterator();
while(itr.hasNext()) { while (itr.hasNext()) {
FormalParameter fp = itr.next(); FormalParameter fp = itr.next();
methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";"; methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()) + ";";
// methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";"; // methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";";
} }
if(methodNameAndParamsT.contains(methParamTypes)) { if (methodNameAndParamsT.contains(methParamTypes)) {
System.out.println("ignore - Method: "+field.name +" , paramsType: "+methParamTypes); System.out.println("ignore - Method: " + field.name + " , paramsType: " + methParamTypes);
return; return;
} }
methodNameAndParamsT.add(methParamTypes); methodNameAndParamsT.add(methParamTypes);
System.out.println("Method: "+field.name +" , paramsType: "+methParamTypes); System.out.println("Method: " + field.name + " , paramsType: " + methParamTypes);
String desc = null; String desc = null;
boolean hasGen = false; boolean hasGen = false;
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); HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(field.name, tphExtractor,
Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,constraints); tphsClass);
Signature signature = new Signature(field, genericsAndBounds, methodParamsAndTypes, resultSet, constraints);
sig = signature.toString(); sig = signature.toString();
} }
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()));
NormalConstructor constructor = new NormalConstructor(field,genericsAndBounds,hasGen); NormalConstructor constructor = new NormalConstructor(field, genericsAndBounds, hasGen);
desc = constructor.accept(new DescriptorToString(resultSet)); desc = constructor.accept(new DescriptorToString(resultSet));
System.out.println("Constructor: " + field.getName() + " Sig: "+ sig + " Desc: " + desc); System.out.println("Constructor: " + field.getName() + " Sig: " + sig + " Desc: " + desc);
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", desc, sig, null); MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, "<init>", desc, sig, null);
mv.visitCode(); mv.visitCode();
Block block = fieldInitializations.get().block; Block block = fieldInitializations.get().block;
constructorPos += 1; constructorPos += 1;
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);
mv.visitEnd(); mv.visitEnd();
} }
@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 retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
String methParamTypes = retType+method.name+"%%"; String methParamTypes = retType + method.name + "%%";
method.getParameterList().accept(this); method.getParameterList().accept(this);
Iterator<FormalParameter> itr = method.getParameterList().iterator(); Iterator<FormalParameter> itr = method.getParameterList().iterator();
while(itr.hasNext()) { while (itr.hasNext()) {
FormalParameter fp = itr.next(); FormalParameter fp = itr.next();
methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";"; methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor()) + ";";
// methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";"; // methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";";
} }
if(methodNameAndParamsT.contains(methParamTypes)) { if (methodNameAndParamsT.contains(methParamTypes)) {
return; return;
} }
methodNameAndParamsT.add(methParamTypes); methodNameAndParamsT.add(methParamTypes);
System.out.println("Method: "+method.name +" , paramsType: "+methParamTypes); System.out.println("Method: " + method.name + " , paramsType: " + methParamTypes);
// 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<>();
String methDesc = null; String methDesc = null;
// Method getModifiers() ? // Method getModifiers() ?
int acc = isInterface?Opcodes.ACC_ABSTRACT:method.modifier; int acc = isInterface ? Opcodes.ACC_ABSTRACT : method.modifier;
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*/ /*
if(!hasGenInParameterList) { * Wenn die Rückgabe-Type eine Typ-variable ist, erzeuge direkt die Signature,
for(String paramName : methodParamsAndTypes.keySet()) { * 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 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
//then create the descriptor with the new syntax. // type. (VP)
// 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())
.equals("TPH")) {
System.out.println("ALL CONST: " + tphExtractor.allCons.size()); System.out.println("ALL CONST: " + tphExtractor.allCons.size());
tphExtractor.allCons.forEach(c->System.out.println(c.toString())); tphExtractor.allCons.forEach(c -> System.out.println(c.toString()));
System.out.println("----------------"); System.out.println("----------------");
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(method.name, tphExtractor, tphsClass); HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(method.name,
tphExtractor, tphsClass);
// ArrayList<GenericInsertPair> pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons); // ArrayList<GenericInsertPair> pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons);
Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet,constraints); Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,
methodParamsAndTypes, resultSet, constraints);
sig = signature.toString(); sig = signature.toString();
} if (simplifyResults.containsKey(className)) {
System.out.println(method.getName()+" ==> "+sig); simplifyResults.get(className).getMethodsConstraints().put(methParamTypes, constraints);
NormalMethod meth = new NormalMethod(method,genericsAndBounds,genericsAndBoundsMethod,hasGen); } else {
methDesc = meth.accept(new DescriptorToString(resultSet)); SimplifyResult sRes = new SimplifyResult(new ArrayList<>(), new ArrayList<>(), new HashMap<>());
sRes.getMethodsConstraints().put(methParamTypes, constraints);
// System.out.println(methDesc); simplifyResults.put(className, sRes);
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC+acc, method.getName(), methDesc, sig, null); }
}
System.out.println(method.getName() + " ==> " + sig);
NormalMethod meth = new NormalMethod(method, genericsAndBounds, genericsAndBoundsMethod, hasGen);
methDesc = meth.accept(new DescriptorToString(resultSet));
// System.out.println(methDesc);
MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC + acc, method.getName(), methDesc, sig, null);
mv.visitCode();
BytecodeGenMethod gen = new BytecodeGenMethod(className, superClass, resultSet, method, mv, paramsAndLocals, cw,
genericsAndBoundsMethod, genericsAndBounds, isInterface, classFiles, sf, path);
mv.visitCode();
BytecodeGenMethod gen = new BytecodeGenMethod(className,superClass,resultSet,method, mv,paramsAndLocals,cw,
genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles, sf,path);
mv.visitMaxs(0, 0); mv.visitMaxs(0, 0);
mv.visitEnd(); mv.visitEnd();
} }
public HashMap<String, SimplifyResult> getSimplifyResults() {
return simplifyResults;
}
@Override @Override
public void visit(ParameterList formalParameters) { public void visit(ParameterList formalParameters) {
paramsAndLocals = new HashMap<>(); paramsAndLocals = new HashMap<>();
methodParamsAndTypes = new HashMap<>(); methodParamsAndTypes = new HashMap<>();
Iterator<FormalParameter> itr = formalParameters.iterator(); Iterator<FormalParameter> itr = formalParameters.iterator();
int i = 1; int i = 1;
while(itr.hasNext()) { while (itr.hasNext()) {
FormalParameter fp = itr.next(); FormalParameter fp = itr.next();
paramsAndLocals.put(fp.getName(), i); paramsAndLocals.put(fp.getName(), i);
methodParamsAndTypes.put(fp.getName(), resultSet.resolveType(fp.getType()).resolvedType); methodParamsAndTypes.put(fp.getName(), resultSet.resolveType(fp.getType()).resolvedType);
@@ -399,39 +461,39 @@ public class BytecodeGen implements ASTVisitor {
i++; i++;
} }
} }
@Override @Override
public void visit(FormalParameter formalParameter) { public void visit(FormalParameter formalParameter) {
formalParameter.getType().accept(this); formalParameter.getType().accept(this);
} }
@Override @Override
public void visit(RefType refType) { public void visit(RefType refType) {
type = "L"+refType.toString()+";"; type = "L" + refType.toString() + ";";
} }
@Override @Override
public void visit(SuperWildcardType superWildcardType) { public void visit(SuperWildcardType superWildcardType) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(TypePlaceholder typePlaceholder) { public void visit(TypePlaceholder typePlaceholder) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(ExtendsWildcardType extendsWildcardType) { public void visit(ExtendsWildcardType extendsWildcardType) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(GenericRefType genericRefType) { public void visit(GenericRefType genericRefType) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
// ?? // ??
@@ -439,41 +501,51 @@ 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();
} }
@Override @Override
public void visit(Field field) { public void visit(Field field) {
System.out.println("In Field ---"); System.out.println("In Field ---");
String des = "L"; String des = "L";
if(resultSet.resolveType(field.getType()).resolvedType instanceof TypePlaceholder) { if (resultSet.resolveType(field.getType()).resolvedType instanceof TypePlaceholder) {
des += Type.getInternalName(Object.class); des += Type.getInternalName(Object.class);
} else { } else {
des += resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToDescriptor()); des += resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToDescriptor());
} }
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());
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
public void visit(LambdaExpression lambdaExpression) { public void visit(LambdaExpression lambdaExpression) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(Assign assign) { public void visit(Assign assign) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
@@ -484,151 +556,151 @@ public class BytecodeGen implements ASTVisitor {
@Override @Override
public void visit(Block block) { public void visit(Block block) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(CastExpr castExpr) { public void visit(CastExpr castExpr) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(EmptyStmt emptyStmt) { public void visit(EmptyStmt emptyStmt) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(ForStmt forStmt) { public void visit(ForStmt forStmt) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(IfStmt ifStmt) { public void visit(IfStmt ifStmt) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(InstanceOf instanceOf) { public void visit(InstanceOf instanceOf) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(LocalVar localVar) { public void visit(LocalVar localVar) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(LocalVarDecl localVarDecl) { public void visit(LocalVarDecl localVarDecl) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(MethodCall methodCall) { public void visit(MethodCall methodCall) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(NewClass methodCall) { public void visit(NewClass methodCall) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(NewArray newArray) { public void visit(NewArray newArray) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(Return aReturn) { public void visit(Return aReturn) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(ReturnVoid aReturn) { public void visit(ReturnVoid aReturn) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(StaticClassName staticClassName) { public void visit(StaticClassName staticClassName) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(Super aSuper) { public void visit(Super aSuper) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(This aThis) { public void visit(This aThis) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(WhileStmt whileStmt) { public void visit(WhileStmt whileStmt) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(DoStmt whileStmt) { public void visit(DoStmt whileStmt) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
// ??? // ???
@Override @Override
public void visit(Literal literal) { public void visit(Literal literal) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(ArgumentList argumentList) { public void visit(ArgumentList argumentList) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(GenericTypeVar genericTypeVar) { public void visit(GenericTypeVar genericTypeVar) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(GenericDeclarationList genericTypeVars) { public void visit(GenericDeclarationList genericTypeVars) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(AssignToField assignLeftSide) { public void visit(AssignToField assignLeftSide) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(AssignToLocal assignLeftSide) { public void visit(AssignToLocal assignLeftSide) {
// TODO Auto-generated method stub // TODO Auto-generated method stub
} }
@Override @Override
public void visit(SuperCall superCall) { public void visit(SuperCall superCall) {
} }
@Override @Override
@@ -641,6 +713,5 @@ public class BytecodeGen implements ASTVisitor {
public void visit(UnaryExpr unaryExpr) { public void visit(UnaryExpr unaryExpr) {
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }

@@ -33,12 +33,14 @@ 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.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.Signature;
import de.dhbwstuttgart.bytecode.signature.TypeToSignature; import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
import de.dhbwstuttgart.bytecode.utilities.KindOfLambda; import de.dhbwstuttgart.bytecode.utilities.KindOfLambda;
import de.dhbwstuttgart.bytecode.utilities.Lambda; import de.dhbwstuttgart.bytecode.utilities.Lambda;
import de.dhbwstuttgart.bytecode.utilities.MethodCallHelper;
import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall; import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
import de.dhbwstuttgart.bytecode.utilities.SamMethod; import de.dhbwstuttgart.bytecode.utilities.SamMethod;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
@@ -52,6 +54,7 @@ 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 {
@@ -140,7 +143,8 @@ public class BytecodeGenMethod implements StatementVisitor {
} }
public BytecodeGenMethod(LambdaExpression lambdaExpression, ArrayList<String> usedVars, ResultSet resultSet, MethodVisitor mv, public BytecodeGenMethod(LambdaExpression lambdaExpression, ArrayList<String> usedVars, ResultSet resultSet, MethodVisitor mv,
int indexOfFirstParamLam, boolean isInterface, HashMap<String, byte[]> classFiles, String path, int lamCounter, SourceFile sf) { int indexOfFirstParamLam, boolean isInterface, HashMap<String, byte[]> classFiles, String path, int lamCounter, SourceFile sf,HashMap<String, String> genericsAndBoundsMethod,
HashMap<String, String> genericsAndBounds) {
this.resultSet = resultSet; this.resultSet = resultSet;
this.mv = mv; this.mv = mv;
@@ -149,6 +153,9 @@ public class BytecodeGenMethod implements StatementVisitor {
this.path = path; this.path = path;
this.lamCounter = lamCounter; this.lamCounter = lamCounter;
this.sf = sf; this.sf = sf;
this.genericsAndBoundsMethod = genericsAndBoundsMethod;
this.genericsAndBounds = genericsAndBounds;
Iterator<FormalParameter> itr = lambdaExpression.params.iterator(); Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
int i = indexOfFirstParamLam; int i = indexOfFirstParamLam;
@@ -644,7 +651,8 @@ public class BytecodeGenMethod implements StatementVisitor {
ArrayList<String> usedVars = kindOfLambda.getUsedVars(); ArrayList<String> usedVars = kindOfLambda.getUsedVars();
new BytecodeGenMethod(lambdaExpression, usedVars,this.resultSet, mvLambdaBody, indexOfFirstParamLam, isInterface, new BytecodeGenMethod(lambdaExpression, usedVars,this.resultSet, mvLambdaBody, indexOfFirstParamLam, isInterface,
classFiles,this.path, lamCounter, sf); classFiles,this.path, lamCounter, sf, genericsAndBoundsMethod,
genericsAndBounds);
mvLambdaBody.visitMaxs(0, 0); mvLambdaBody.visitMaxs(0, 0);
mvLambdaBody.visitEnd(); mvLambdaBody.visitEnd();
@@ -670,7 +678,7 @@ public class BytecodeGenMethod implements StatementVisitor {
} }
methSig.visitReturnType().visitTypeVariable("R"); methSig.visitReturnType().visitTypeVariable("R");
// ")"+lam.getReturn.getBounds // ")"+lam.getReturn.getBounds
Signature sig = new Signature(lambdaExpression, numberOfParams); Signature sig = new Signature(numberOfParams);
String name = "Fun" + numberOfParams + "$$"; String name = "Fun" + numberOfParams + "$$";
classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(), classWriter.visit(Opcodes.V1_8, Opcodes.ACC_PUBLIC+Opcodes.ACC_INTERFACE + Opcodes.ACC_ABSTRACT, name, sig.toString(),
Type.getInternalName(Object.class), null); Type.getInternalName(Object.class), null);
@@ -744,6 +752,13 @@ public class BytecodeGenMethod implements StatementVisitor {
statement = new IfStatement(ifStmt.expr, ifStmt.then_block, ifStmt.else_block); statement = new IfStatement(ifStmt.expr, ifStmt.then_block, ifStmt.else_block);
isBinaryExp = statement.isExprBinary(); isBinaryExp = statement.isExprBinary();
ifStmt.expr.accept(this); ifStmt.expr.accept(this);
if(!(ifStmt.expr instanceof BinaryExpr)) {
doUnboxing(getResolvedType(ifStmt.expr.getType()));
Label branchLabel = new Label();
Label endLabel = new Label();
mv.visitJumpInsn(Opcodes.IFEQ, branchLabel);
statement.genBCForRelOp(mv, branchLabel, endLabel, this);
}
statement = null; statement = null;
} }
@@ -751,105 +766,112 @@ public class BytecodeGenMethod implements StatementVisitor {
public void visit(InstanceOf instanceOf) { public void visit(InstanceOf instanceOf) {
} }
@Override @Override
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 = getResolvedType(methodCall.receiver.getType());
System.out.println("Methods of " + receiverName + " "); System.out.println("Methods of " + receiverName + " ");
java.lang.reflect.Method methodRefl = null;
String clazz = receiverName.replace("/", ".");
String mDesc = "";
MethodCallHelper helper = new MethodCallHelper(methodCall, sf, resultSet, path);
boolean toCreate = false;
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;
java.lang.reflect.Method methodRefl = null;
String clazz = receiverName.replace("/", ".");
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("<")) { if (receiverName.contains("<")) {
clazz = clazz.substring(0, receiverName.indexOf("<")); 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 { String superClass = "";
// cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)}); while(true) {
// java.lang.reflect.Method[] methods = cLoader2.loadClass(clazz).getMethods(); try {
// System.out.println("Methods of " + receiverName + " "); superClass = helper.getSuperClass(receiverName);
// for(int i = 0; i<methods.length; i++) {
// System.out.println(methods[i]); try {
// } String superClazz = superClass.replace("/", ".");
// methodRefl = getMethod(methodCall.name,methodCall.arglist.getArguments().size(),methCallType, typesOfParams,methods); if(superClass.contains("<")) {
// }catch (Exception e2) { superClazz = superClazz.substring(0, superClass.indexOf("<"));
String superClass = ""; }
// TODO: Test SubMatrix.jav java.lang.reflect.Method[] methods = cLoader.loadClass(superClazz).getMethods();
while(true) { System.out.println("Methods of " + superClass + " ");
for(ClassOrInterface cl : sf.getClasses()) {
if(receiverName.equals(cl.getClassName().toString())) { for(java.lang.reflect.Method m : methods) {
superClass = cl.getSuperClass().getName().toString(); if(methodCall.name.equals(m.getName())) {
methodRefl = m;
break;
}
}
break;
} catch (Exception e3) {
receiverName = superClass;
continue;
}
} catch (NotInCurrentPackageException e2) {
break; break;
} }
}
System.out.println(superClass);
if(superClass.equals(""))
break;
try {
String superClazz = superClass.replace("/", ".");
if(superClass.contains("<")) {
superClazz = superClazz.substring(0, superClass.indexOf("<"));
}
java.lang.reflect.Method[] methods = cLoader.loadClass(superClazz).getMethods();
System.out.println("Methods of " + superClass + " ");
for(java.lang.reflect.Method m : methods) {
if(methodCall.name.equals(m.getName())) {
methodRefl = m;
break;
}
}
break;
} catch (Exception e3) {
receiverName = superClass;
continue;
} }
}
// } }
} if(methodRefl == null) {
toCreate = !receiverName.equals(className) && helper.isInCurrPkg(clazz);
if(methodRefl == null) { if(toCreate) {
try { try {
cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)}); mDesc = helper.getDesc(clazz);
java.lang.reflect.Method[] methods = cLoader2.loadClass(clazz).getMethods(); } catch (NotInCurrentPackageException | NotFoundException e) {
System.out.println("Methods of " + receiverName + " "); e.printStackTrace();
for(int i = 0; i<methods.length; i++) { }
System.out.println(methods[i]); } else if(!helper.isInCurrPkg(clazz)){
if(clazz.contains("$$")) {
mDesc = helper.generateBCForFunN();
}else {
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) {
e2.printStackTrace();
}
}
} }
methodRefl = getMethod(methodCall.name,methodCall.arglist.getArguments().size(),methCallType, typesOfParams,methods);
} }
catch (Exception e2) {
System.out.println("");
//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");
receiverRefl = methodRefl.getAnnotatedReceiverType().getType().toString(); receiverRefl = methodRefl.getAnnotatedReceiverType().getType().toString();
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());
@@ -863,9 +885,11 @@ public class BytecodeGenMethod implements StatementVisitor {
al.accept(argV); al.accept(argV);
statement = null; statement = null;
} }
} else {
methodCall.arglist.accept(this);
} }
System.out.println("Methodcall Desc : " + mDesc); System.out.println("Methodcall ("+ methodCall.name +") Desc : " + mDesc);
// methodCall.arglist.accept(this); // methodCall.arglist.accept(this);
@@ -900,6 +924,19 @@ public class BytecodeGenMethod implements StatementVisitor {
} }
private String getDescForMethInCurrPkg(String name) {
// TODO Auto-generated method stub
return null;
}
private boolean isInCurrPkg(String superClass) {
for(ClassOrInterface cl : sf.KlassenVektor) {
if(superClass.equals(cl.getClassName().toString()))
return true;
}
return false;
}
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) {
@@ -1197,6 +1234,7 @@ public class BytecodeGenMethod implements StatementVisitor {
break; break;
case "java/lang/Boolean": case "java/lang/Boolean":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
break; break;
case "java/lang/Byte": case "java/lang/Byte":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false); mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false);
@@ -1234,10 +1272,16 @@ public class BytecodeGenMethod implements StatementVisitor {
visitBooleanLiteral((Boolean) value); visitBooleanLiteral((Boolean) value);
break; break;
case "java/lang/Byte": case "java/lang/Byte":
visitByteLiteral(((Double) value).byteValue(), false); if(value instanceof Double)
visitByteLiteral(((Double) value).byteValue(), false);
if(value instanceof Integer)
visitByteLiteral(((Integer) value).byteValue(), false);
break; break;
case "java/lang/Short": case "java/lang/Short":
visitShortLiteral(((Double) value).shortValue(), false); if(value instanceof Double)
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
@@ -1248,10 +1292,16 @@ public class BytecodeGenMethod implements StatementVisitor {
visitIntegerLiteral(((Integer) value).intValue(), false); visitIntegerLiteral(((Integer) value).intValue(), false);
break; break;
case "java/lang/Long": case "java/lang/Long":
visitLongLiteral(((Integer) value).longValue(), true); if(value instanceof Double)
visitLongLiteral(((Double) value).longValue(), true);
if(value instanceof Integer)
visitLongLiteral(((Integer) value).longValue(), true);
break; break;
case "java/lang/Float": case "java/lang/Float":
visitFloatLiteral(((Double) value).floatValue()); if(value instanceof Double)
visitFloatLiteral(((Double) value).floatValue());
if(value instanceof Integer)
visitFloatLiteral(((Integer) value).floatValue());
break; break;
case "java/lang/Double": case "java/lang/Double":
if(value instanceof Double) if(value instanceof Double)

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

@@ -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);
}
}

@@ -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);
}
}

@@ -5,67 +5,151 @@ 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.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.syntaxtree.AbstractASTWalker; import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
import de.dhbwstuttgart.syntaxtree.Constructor;
import de.dhbwstuttgart.syntaxtree.Field;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.Method; import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.statement.LocalVar;
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;
/** /**
* @author Fayez Abu Alia * @author Fayez Abu Alia
* *
*/ */
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<>(); final HashMap<String, Boolean> allTPHS = new HashMap<>();
MethodAndTPH methodAndTph; MethodAndTPH methodAndTph;
Boolean inMethod = false; Boolean inMethod = false;
boolean inLocalOrParam = 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;
public TPHExtractor() { public TPHExtractor() {
} }
public void setResultSet(ResultSet resultSet) { public void setResultSet(ResultSet resultSet) {
this.resultSet = resultSet; this.resultSet = resultSet;
} }
@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)
allTPHS.put(resolvedTPH,inMethod); methodAndTph.getLocalTphs().add(resolvedTPH.getName());
resultSet.resolveType(tph).additionalGenerics.forEach(ag ->{ }
if(ag.contains(resolvedTPH)&&ag.TA1.equals(resolvedTPH)&&!contains(allPairs,ag)) {
if(inMethod) allTPHS.put(resolvedTPH.getName(), inMethod);
// final List<TPHConstraint> cons = new ArrayList<>();
// 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)
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(), Relation.EXTENDS);
allCons.add(con); if(!containsConstraint(allCons,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(c.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.getLocalTphs().add(name);
if (inLocalOrParam)
methodAndTph.getLocalTphs().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);
if(p.TA1.equals(genPair.TA1) && p.TA2.equals(genPair.TA2)) if (p.TA1.equals(genPair.TA1) && p.TA2.equals(genPair.TA2))
return true; return true;
} }
return false; return false;
} }
@Override @Override
public void visit(Method method) { public void visit(Method method) {
inMethod = true; inMethod = true;
@@ -74,5 +158,33 @@ public class TPHExtractor extends AbstractASTWalker{
inMethod = false; inMethod = false;
ListOfMethodsAndTph.add(methodAndTph); ListOfMethodsAndTph.add(methodAndTph);
} }
@Override
public void visit(Constructor cons) {
inMethod = false;
super.visit(cons);
inMethod = true;
}
@Override
public void visit(LocalVarDecl localVarDecl) {
inLocalOrParam = true;
super.visit(localVarDecl);
inLocalOrParam = false;
}
@Override
public void visit(LocalVar localVar) {
inLocalOrParam = true;
super.visit(localVar);
inLocalOrParam = false;
}
@Override
public void visit(ParameterList formalParameters) {
inLocalOrParam = true;
super.visit(formalParameters);
inLocalOrParam = false;
}
} }

@@ -1,5 +1,6 @@
package de.dhbwstuttgart.bytecode.descriptor; package de.dhbwstuttgart.bytecode.descriptor;
import java.util.HashMap;
import java.util.Iterator; import java.util.Iterator;
import org.objectweb.asm.Type; import org.objectweb.asm.Type;
@@ -44,17 +45,28 @@ 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("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 { } 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+ ";";
}
} }
} }
} }
@@ -78,11 +90,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("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 +115,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 = "(";
@@ -131,7 +162,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("TPH ") ||d.contains("<")) {
desc += "L"+Type.getInternalName(Object.class)+ ";"; desc += "L"+Type.getInternalName(Object.class)+ ";";
}else { }else {
desc = desc + "L"+ d + ";"; desc = desc + "L"+ d + ";";
@@ -140,7 +171,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("TPH ")|| retType.contains("<")){
desc += ")L"+Type.getInternalName(Object.class)+ ";"; desc += ")L"+Type.getInternalName(Object.class)+ ";";
}else { }else {
desc = desc + ")"+"L"+retType+";"; desc = desc + ")"+"L"+retType+";";
@@ -156,7 +187,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("TPH ") ||d.contains("<")) {
desc += "L"+Type.getInternalName(Object.class)+ ";"; desc += "L"+Type.getInternalName(Object.class)+ ";";
}else { }else {
desc += "L"+ d + ";"; desc += "L"+ d + ";";
@@ -165,7 +196,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("TPH ")|| retType.contains("<")){
desc += ")L"+Type.getInternalName(Object.class)+ ";"; desc += ")L"+Type.getInternalName(Object.class)+ ";";
}else { }else {
desc = desc + ")"+"L"+retType+";"; desc = desc + ")"+"L"+retType+";";
@@ -179,7 +210,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("TPH ") ||d.contains("<") || 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)) {
@@ -196,7 +227,7 @@ public class DescriptorToString implements DescriptorVisitor{
System.out.println("DescriptorToString retType = " + retType); System.out.println("DescriptorToString retType = " + retType);
if(retType.equals("void")) { if(retType.equals("void")) {
desc += ")V"; desc += ")V";
}else if(retType.substring(0, 4).equals("TPH ")|| retType.contains("<") || methodFromMethodCall.getReceiverName().contains("$$")){ }else if(retType.contains("TPH ")|| retType.contains("<") || 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)) {

@@ -41,11 +41,11 @@ public class Signature {
private ResultSet resultSet; private ResultSet resultSet;
private ArrayList<GenericInsertPair> commonPairs; private ArrayList<GenericInsertPair> commonPairs;
private HashMap<TPHConstraint,HashSet<String>> methodConstraints; private HashMap<TPHConstraint,HashSet<String>> methodConstraints;
private ArrayList<TypePlaceholder> tphsClass; private ArrayList<String> tphsClass;
private ArrayList<TPHConstraint> consClass; 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) { ArrayList<GenericInsertPair> commonPairs, ArrayList<String> tphsClass, ArrayList<TPHConstraint> consClass) {
this.classOrInterface = classOrInterface; this.classOrInterface = classOrInterface;
this.genericsAndBounds = genericsAndBounds; this.genericsAndBounds = genericsAndBounds;
this.commonPairs = commonPairs; this.commonPairs = commonPairs;
@@ -80,12 +80,12 @@ public class Signature {
createSignatureForConsOrMethod(this.method,false); createSignatureForConsOrMethod(this.method,false);
} }
public Signature(LambdaExpression lambdaExpression,int numberOfParams) { public Signature(int numberOfParams) {
sw = new SignatureWriter(); sw = new SignatureWriter();
createSignatureForFunN(lambdaExpression, numberOfParams); createSignatureForFunN(numberOfParams);
} }
private void createSignatureForFunN(LambdaExpression lambdaExpression, int numberOfParams) { private void createSignatureForFunN(int numberOfParams) {
// sw.visitClassBound().visitEnd(); // sw.visitClassBound().visitEnd();
for(int i = 0;i<numberOfParams;i++) { for(int i = 0;i<numberOfParams;i++) {
@@ -235,8 +235,9 @@ public class Signature {
RefTypeOrTPHOrWildcardOrGeneric resolved = resType.resolvedType; RefTypeOrTPHOrWildcardOrGeneric resolved = resType.resolvedType;
if(resolved instanceof TypePlaceholder) { if(resolved instanceof TypePlaceholder) {
resType.additionalGenerics.forEach(ag ->{ //resType.getAdditionalGenerics().forEach(ag ->{
TPHConstraint constr = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS); resultSet.genIns.forEach(ag ->{
TPHConstraint constr = new ExtendsConstraint(ag.getLeft().getName(), ag.getRight().getName(), Relation.EXTENDS);
if(!contains(res,constr)) { if(!contains(res,constr)) {
res.add(constr); res.add(constr);
} }
@@ -246,8 +247,9 @@ public class Signature {
WildcardType resWC = (WildcardType) resolved; WildcardType resWC = (WildcardType) resolved;
ResolvedType resType2 = resultSet.resolveType(resWC.getInnerType()); ResolvedType resType2 = resultSet.resolveType(resWC.getInnerType());
if(resType2.resolvedType instanceof TypePlaceholder) { if(resType2.resolvedType instanceof TypePlaceholder) {
resType2.additionalGenerics.forEach(ag ->{ //resType2.getAdditionalGenerics().forEach(ag ->{
TPHConstraint constr = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS); resultSet.genIns.forEach(ag ->{
TPHConstraint constr = new ExtendsConstraint(ag.getLeft().getName(), ag.getRight().getName(), Relation.EXTENDS);
if(!contains(res,constr)) { if(!contains(res,constr)) {
res.add(constr); res.add(constr);
} }
@@ -290,7 +292,8 @@ public class Signature {
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()).substring(1));
sv.visitTypeVariable(g.acceptTV(new TypeToSignature()));
break; break;
case "TPH": case "TPH":
RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType; RefTypeOrTPHOrWildcardOrGeneric r = resultSet.resolveType(t).resolvedType;
@@ -301,16 +304,27 @@ public class Signature {
// 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());
String eqTPH = getEqualTPH(methodConstraints, sig2.substring(1, sig2.length()-1))+"$"; if(r instanceof GenericRefType) {
if(!(r instanceof TypePlaceholder)) { sv.visitTypeVariable(sig2);
}else if(!(r instanceof TypePlaceholder)) {
if(sig2.contains("$$")) { if(sig2.contains("$$")) {
System.out.println(" Signature FUN$$: "+r); System.out.println(" Signature FUN$$: "+r);
sv.visitInterface().visitClassType(sig2.substring(1, sig2.length())); sv.visitInterface().visitClassType(sig2.substring(1, sig2.length()));
} 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 {
String eqTPH = getEqualTPH(methodConstraints, sig2.substring(1, sig2.length()-1))+"$";
System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature())); System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature()));
sv.visitTypeVariable(eqTPH); sv.visitTypeVariable(eqTPH);
} }
@@ -391,7 +405,7 @@ public class Signature {
} }
for(TPHConstraint cons : consClass) { for(TPHConstraint cons : consClass) {
if(!types.contains(cons.getRight())) { if(!types.contains(cons.getRight()) && !genericsAndBounds.keySet().contains(cons.getRight()+"$")) {
String t = cons.getRight()+"$"; String t = cons.getRight()+"$";
String bound = Type.getInternalName(Object.class); String bound = Type.getInternalName(Object.class);
sw.visitFormalTypeParameter(t); sw.visitFormalTypeParameter(t);
@@ -456,10 +470,15 @@ public class Signature {
String boundDesc = b.acceptTV(new TypeToDescriptor()); String boundDesc = b.acceptTV(new TypeToDescriptor());
// System.out.println("GetBounds: " + boundDesc); // 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 {
sw.visitClassBound().visitClassType(boundDesc);
sw.visitClassBound().visitEnd();
}
genAndBounds.put(g.getName(), boundDesc); genAndBounds.put(g.getName(), boundDesc);
} }
sw.visitClassBound().visitEnd(); // sw.visitClassBound().visitEnd();
} }
public String toString() { public String toString() {

@@ -0,0 +1,51 @@
package de.dhbwstuttgart.bytecode.utilities;
import java.util.ArrayList;
import java.util.List;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
public class ConstraintsFinder {
private List<TPHConstraint> allConstaints;
public ConstraintsFinder(List<TPHConstraint> allConstaints) {
super();
this.allConstaints = allConstaints;
}
public List<List<TPHConstraint>> findConstraints() {
List<List<TPHConstraint>> result = new ArrayList<>();
List<TPHConstraint> visitedCons = new ArrayList<>();
for(TPHConstraint c : allConstaints) {
if(c.getRel() == Relation.EXTENDS) {
// get constraints with the same left side
List<TPHConstraint> cons = getConstraints(c,visitedCons);
if(cons.size()>1)
result.add(cons);
}
}
return result;
}
private List<TPHConstraint> getConstraints(TPHConstraint c, List<TPHConstraint> visitedCons) {
List<TPHConstraint> res = new ArrayList<>();
for(TPHConstraint cons : allConstaints) {
if(!isVisited(cons,visitedCons) && cons.getLeft().equals(c.getLeft())) {
res.add(cons);
visitedCons.add(cons);
}
}
return res;
}
private boolean isVisited(TPHConstraint cons, List<TPHConstraint> visitedCons) {
for(TPHConstraint c : visitedCons) {
if(c.getLeft().equals(cons.getLeft()) && c.getRight().equals(cons.getRight()))
return true;
}
return false;
}
}

@@ -2,14 +2,19 @@ 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 name;
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
private final ArrayList<String> localTphs = new ArrayList<>();
public MethodAndTPH(String name) { public MethodAndTPH(String name) {
this.name = name; this.name = name;
@@ -19,11 +24,19 @@ public class MethodAndTPH {
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 getName() {
return name; return name;
} }
public ArrayList<String> getLocalTphs() {
return localTphs;
}
} }

@@ -0,0 +1,255 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.utilities;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
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 de.dhbwstuttgart.bytecode.Exception.NotInCurrentPackageException;
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
import de.dhbwstuttgart.bytecode.signature.Signature;
import de.dhbwstuttgart.bytecode.signature.TypeToSignature;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.FormalParameter;
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.Method;
import de.dhbwstuttgart.syntaxtree.SourceFile;
import de.dhbwstuttgart.syntaxtree.statement.Expression;
import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression;
import de.dhbwstuttgart.syntaxtree.statement.MethodCall;
import de.dhbwstuttgart.syntaxtree.type.GenericRefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import javassist.NotFoundException;
/**
* @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);
Map<String, String> genAndBoundsClass = getGenericsAndBounds(clazz.getGenerics());
modifyGenAndBounds(genAndBoundsClass);
for (Method m : clazz.getMethods()) {
if (name.equals(m.getName())) {
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 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 String generateBCForFunN() {
ClassWriter classWriter = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS);
SignatureWriter methSig = new SignatureWriter();
int numberOfParams = 0;
SignatureVisitor paramVisitor = methSig.visitParameterType();
Iterator<Expression> itr1 = methCall.arglist.getArguments().iterator();
String methDesc = "(";
while(itr1.hasNext()) {
numberOfParams++;
// getBounds
paramVisitor.visitTypeVariable("T" + numberOfParams);
methDesc += "L" + Type.getInternalName(Object.class) + ";";
itr1.next();
}
methDesc += ")L" + Type.getInternalName(Object.class) + ";";
methSig.visitReturnType().visitTypeVariable("R");
// ")"+lam.getReturn.getBounds
Signature sig = new Signature(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);
return methDesc;
}
private void writeClassFile(byte[] bytecode, String name) {
FileOutputStream output;
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();
}
}
}

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

@@ -0,0 +1,49 @@
package de.dhbwstuttgart.bytecode.utilities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
public class NameReplacer {
private List<TPHConstraint> constraints;
private List<TPHConstraint> allConstraints;
private List<String> tphs;
private List<String> localTphs;
public NameReplacer(List<TPHConstraint> constraints, List<TPHConstraint> allConstraints,List<String> tphs, ArrayList<String> localTphs) {
super();
this.constraints = constraints;
this.allConstraints = allConstraints;
this.tphs = tphs;
this.localTphs = localTphs;
}
public Map<String, List<String>> replaceNames() {
String newName = NameGenerator.makeNewName();
ArrayList<String> names = new ArrayList<>();
for(TPHConstraint cons : constraints) {
names.add(cons.getRight());
cons.setRight(newName);
}
for(TPHConstraint cons : allConstraints) {
if(names.contains(cons.getLeft()))
cons.setLeft(newName);
if(names.contains(cons.getRight()))
cons.setRight(newName);
}
tphs.removeAll(names);
tphs.add(newName);
localTphs.removeAll(names);
localTphs.add(newName);
HashMap<String, List<String>> res = new HashMap<>();
res.put(newName, names);
return res;
}
}

File diff suppressed because it is too large Load Diff

@@ -0,0 +1,42 @@
/**
*
*/
package de.dhbwstuttgart.bytecode.utilities;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
/**
* @author fayez
*
*/
public class SimplifyResult {
private final ArrayList<TPHConstraint> classConstraints;
private final ArrayList<String> tphsClass;
private final HashMap<String, HashMap<TPHConstraint, HashSet<String>>> methodsConstraints;
public SimplifyResult(ArrayList<TPHConstraint> classConstraints, ArrayList<String> tphsClass,
HashMap<String, HashMap<TPHConstraint, HashSet<String>>> methodsConstraints) {
super();
this.classConstraints = classConstraints;
this.tphsClass = tphsClass;
this.methodsConstraints = methodsConstraints;
}
public ArrayList<TPHConstraint> getClassConstraints() {
return classConstraints;
}
public HashMap<String, HashMap<TPHConstraint, HashSet<String>>> getMethodsConstraints() {
return methodsConstraints;
}
public ArrayList<String> getTphsClass() {
return tphsClass;
}
}

@@ -3,6 +3,8 @@ package de.dhbwstuttgart.core;
import de.dhbwstuttgart.bytecode.BytecodeGen; import de.dhbwstuttgart.bytecode.BytecodeGen;
import de.dhbwstuttgart.bytecode.Exception.BytecodeGeneratorError;
import de.dhbwstuttgart.bytecode.utilities.SimplifyResult;
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.NullToken;
@@ -34,6 +36,7 @@ import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask; import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
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;
@@ -41,20 +44,31 @@ 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.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 java.util.stream.Stream;
import org.antlr.v4.parse.ANTLRParser.throwsSpec_return; 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 {
final CompilationEnvironment environment; final CompilationEnvironment environment;
Boolean resultmodel = true; Boolean resultmodel = false;
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?
/**
* Äußerste Liste der Source-Files.
* Danach Liste der Klassen in Source File.
* Danach Map Klassenname
*/
private List<List<HashMap<String, SimplifyResult>>> simplifyResultsSF = new ArrayList<>();
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException { public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
this(Arrays.asList(sourceFile)); this(Arrays.asList(sourceFile));
} }
@@ -274,7 +288,7 @@ public class JavaTXCompiler {
} }
*/ */
public UnifyResultModel typeInferenceAsync() 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()) {
@@ -284,12 +298,14 @@ public class JavaTXCompiler {
final ConstraintSet<Pair> cons = getConstraints(); final ConstraintSet<Pair> cons = getConstraints();
Set<Set<UnifyPair>> results = new HashSet<>(); Set<Set<UnifyPair>> results = new HashSet<>();
UnifyResultModel urm = new UnifyResultModel(); UnifyResultModel urm = null;
//urm.addUnifyResultListener(resultListener);
try { try {
FileWriter logFile = new FileWriter(new File(System.getProperty("user.dir")+"/src/test/java/logFiles/"+"log_"+sourceFiles.keySet().iterator().next().getName())); 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.addUnifyResultListener(resultListener);
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons); ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
Function<UnifyPair, UnifyPair> distributeInnerVars = Function<UnifyPair, UnifyPair> distributeInnerVars =
@@ -401,7 +417,7 @@ 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, cons, urm); unify.unifyAsync(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm);
} }
catch (IOException e) { catch (IOException e) {
System.err.println("kein LogFile"); System.err.println("kein LogFile");
@@ -421,8 +437,8 @@ public class JavaTXCompiler {
final ConstraintSet<Pair> cons = getConstraints(); final ConstraintSet<Pair> cons = getConstraints();
Set<Set<UnifyPair>> results = new HashSet<>(); Set<Set<UnifyPair>> results = new HashSet<>();
try { try {
FileWriter logFile = new FileWriter(new File(System.getProperty("user.dir")+"/src/test/java/logFiles/"+"log_"+sourceFiles.keySet().iterator().next().getName())); Writer logFile = //new OutputStreamWriter(new NullOutputStream());
new FileWriter(new File(System.getProperty("user.dir")+"/src/test/java/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);
@@ -538,10 +554,10 @@ public class JavaTXCompiler {
}).collect(Collectors.toCollection(ArrayList::new)); }).collect(Collectors.toCollection(ArrayList::new));
if (resultmodel) { if (resultmodel) {
/* UnifyResultModel Anfang */ /* UnifyResultModel Anfang */
UnifyResultModel urm = new UnifyResultModel(); 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, cons, urm); unify.unifyParallel(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, urm);
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();
@@ -549,8 +565,8 @@ public class JavaTXCompiler {
} }
/* UnifyResultModel End */ /* UnifyResultModel End */
else { else {
Set<Set<UnifyPair>> result = unify.unify(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, cons); //Set<Set<UnifyPair>> result = unify.unify(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure));
//Set<Set<UnifyPair>> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, cons); Set<Set<UnifyPair>> result = unify.unifyOderConstraints(unifyCons.getUndConstraints(), oderConstraints, finiteClosure, logFile, log, new UnifyResultModel(cons, finiteClosure));
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();
@@ -636,7 +652,7 @@ public class JavaTXCompiler {
return ret; return ret;
} }
// um pfad erweitern // um pfad erweitern
public void generateBytecode(String path) throws ClassNotFoundException, IOException { public void generateBytecode(String path) throws ClassNotFoundException, IOException, BytecodeGeneratorError {
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);
@@ -644,6 +660,7 @@ public class JavaTXCompiler {
BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult,sf,path); BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult,sf,path);
// BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult.get(0)); // BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult.get(0));
bytecodeGen.visit(sf); bytecodeGen.visit(sf);
this.simplifyResultsSF.add(bytecodeGen.getSimplifyResultsList());
this.writeClassFile(bytecodeGen.getClassFiles(), path); this.writeClassFile(bytecodeGen.getClassFiles(), path);
} }
} }
@@ -660,4 +677,8 @@ public class JavaTXCompiler {
System.out.println(name+".class file generated"); System.out.println(name+".class file generated");
} }
} }
public List<List<HashMap<String, SimplifyResult>>> getSimplifyResults() {
return simplifyResultsSF;
}
} }

@@ -3,31 +3,37 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.antlr.Java8Parser; import de.dhbwstuttgart.parser.antlr.Java8Parser;
import de.dhbwstuttgart.parser.antlr.Java8Parser.UnannClassType_lfno_unannClassOrInterfaceTypeContext;
import de.dhbwstuttgart.parser.scope.GenericsRegistry; import de.dhbwstuttgart.parser.scope.GenericsRegistry;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.parser.scope.JavaClassRegistry; import de.dhbwstuttgart.parser.scope.JavaClassRegistry;
import de.dhbwstuttgart.syntaxtree.GenericDeclarationList; import de.dhbwstuttgart.syntaxtree.GenericDeclarationList;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory; import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
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.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TypeGenerator { public class TypeGenerator {
public static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.UnannClassOrInterfaceTypeContext unannClassOrInterfaceTypeContext, JavaClassRegistry reg, GenericsRegistry generics) { public static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.UnannClassOrInterfaceTypeContext unannClassOrInterfaceTypeContext, JavaClassRegistry reg, GenericsRegistry generics) {
Java8Parser.TypeArgumentsContext arguments; Java8Parser.TypeArgumentsContext arguments=null;
/* PL 2019-03-19 auskommentiert ANFANG
if(unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType() != null){ if(unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType() != null){
arguments = unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().typeArguments(); arguments = unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().typeArguments();
}else{// if(unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType() != null){ }else{// if(unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType() != null){
arguments = unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().unannClassType_lfno_unannClassOrInterfaceType().typeArguments(); arguments = unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().unannClassType_lfno_unannClassOrInterfaceType().typeArguments();
} }
PL 2019-03-19 auskommentiert ENDE */
/** /**
* Problem sind hier die verschachtelten Typen mit verschachtelten Typargumenten * Problem sind hier die verschachtelten Typen mit verschachtelten Typargumenten
* Beispiel: Typ<String>.InnererTyp<Integer> * Beispiel: Typ<String>.InnererTyp<Integer>
@@ -35,6 +41,28 @@ public class TypeGenerator {
String name = unannClassOrInterfaceTypeContext.getText(); String name = unannClassOrInterfaceTypeContext.getText();
if(name.contains("<")){ if(name.contains("<")){
name = name.split("<")[0]; //Der Typ ist alles vor den ersten Argumenten name = name.split("<")[0]; //Der Typ ist alles vor den ersten Argumenten
/* Fuer Debug-Zwecke
unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType();
unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().getText();
//unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().unannClassType_lfno_unannClassOrInterfaceType().typeArguments();
//UnannClassType_lfno_unannClassOrInterfaceTypeContext
unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType(0);
unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType(0).getText();
unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType(1);
unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType(1).getText();
unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().getText();
//unannClassOrInterfaceTypeContext.unannInterfaceType_lf_unannClassOrInterfaceType();
//unannClassOrInterfaceTypeContext.unannInterfaceType_lf_unannClassOrInterfaceType(0).getText();
//unannClassOrInterfaceTypeContext.unannInterfaceType_lf_unannClassOrInterfaceType(1).getText();
//unannClassOrInterfaceTypeContext.unannInterfaceType_lfno_unannClassOrInterfaceType().getText();
*/
int lastElement = new ArrayList<>(unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType()).size()-1;
if (lastElement >=0) {//qualifizierter Name z.B.: java.util.Vector
arguments = unannClassOrInterfaceTypeContext.unannClassType_lf_unannClassOrInterfaceType(lastElement).typeArguments();
}
else { //unqualifizierter Name z.B.: Vector
arguments = unannClassOrInterfaceTypeContext.unannClassType_lfno_unannClassOrInterfaceType().typeArguments();
}
} }
return convertTypeName(name, arguments, unannClassOrInterfaceTypeContext.getStart(), reg, generics); return convertTypeName(name, arguments, unannClassOrInterfaceTypeContext.getStart(), reg, generics);
} }
@@ -132,6 +160,18 @@ public class TypeGenerator {
throw new NotImplementedException(); throw new NotImplementedException();
} }
} }
public static RefTypeOrTPHOrWildcardOrGeneric convert(Java8Parser.WildcardContext wildcardContext, JavaClassRegistry reg, GenericsRegistry generics) {
if(wildcardContext.wildcardBounds() != null){
if(wildcardContext.wildcardBounds().getText().substring(0, 7).equals("extends")){
return new ExtendsWildcardType(convert(wildcardContext.wildcardBounds().referenceType(), reg, generics), wildcardContext.getStart());
}else{
return new SuperWildcardType(convert(wildcardContext.wildcardBounds().referenceType(), reg, generics), wildcardContext.getStart());
}
}else{
throw new NotImplementedException(); //Wildcard ohne Bound
}
}
public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName(String name, Token offset, JavaClassRegistry reg, GenericsRegistry generics){ public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName(String name, Token offset, JavaClassRegistry reg, GenericsRegistry generics){
return convertTypeName(name, null, offset, reg, generics); return convertTypeName(name, null, offset, reg, generics);
@@ -139,12 +179,17 @@ public class TypeGenerator {
public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName( public static RefTypeOrTPHOrWildcardOrGeneric convertTypeName(
String name, Java8Parser.TypeArgumentsContext typeArguments, Token offset, JavaClassRegistry reg, GenericsRegistry generics){ String name, Java8Parser.TypeArgumentsContext typeArguments, Token offset, JavaClassRegistry reg, GenericsRegistry generics){
if(!reg.contains(name)){ //Dann könnte es ein Generische Type sein if(!reg.contains(name)){ //Dann könnte es ein generischer Type oder ein FunN$$-Type sein
if(generics.contains(name)){ if(generics.contains(name)){
return new GenericRefType(name, offset); return new GenericRefType(name, offset);
}else{ }else{
Pattern p = Pattern.compile("Fun(\\d+)[$][$]");
Matcher m = p.matcher(name);
if (m.matches()) {//es ist FunN$$-Type
return new RefType(new JavaClassName(name), convert(typeArguments, reg, generics), offset);
} else {
throw new TypeinferenceException("Der Typ "+ name + " ist nicht vorhanden",offset); throw new TypeinferenceException("Der Typ "+ name + " ist nicht vorhanden",offset);
} }}
} }
if(typeArguments == null){ if(typeArguments == null){
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
@@ -162,7 +207,7 @@ public class TypeGenerator {
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
for(Java8Parser.TypeArgumentContext arg : typeArguments.typeArgumentList().typeArgument()){ for(Java8Parser.TypeArgumentContext arg : typeArguments.typeArgumentList().typeArgument()){
if(arg.wildcard() != null){ if(arg.wildcard() != null){
throw new NotImplementedException(); ret.add(convert(arg.wildcard(), reg, generics));
}else{ }else{
ret.add(convert(arg.referenceType(), reg, generics)); ret.add(convert(arg.referenceType(), reg, generics));
} }

@@ -80,6 +80,9 @@ public abstract class AbstractASTWalker implements ASTVisitor{
for(Field f : classOrInterface.getFieldDecl()){ for(Field f : classOrInterface.getFieldDecl()){
f.accept(this); f.accept(this);
} }
for(Constructor c : classOrInterface.getConstructors()){
c.accept(this);
}
for(Method m : classOrInterface.getMethods()){ for(Method m : classOrInterface.getMethods()){
m.accept(this); m.accept(this);
} }

@@ -1,6 +1,7 @@
package de.dhbwstuttgart.syntaxtree.factory; package de.dhbwstuttgart.syntaxtree.factory;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.Writer;
import java.util.*; import java.util.*;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
@@ -30,7 +31,7 @@ public class UnifyTypeFactory {
private static ArrayList<PlaceholderType> PLACEHOLDERS = new ArrayList<>(); private static ArrayList<PlaceholderType> PLACEHOLDERS = new ArrayList<>();
public static FiniteClosure generateFC(List<ClassOrInterface> fromClasses, FileWriter logFile) throws ClassNotFoundException { public static FiniteClosure generateFC(List<ClassOrInterface> fromClasses, Writer logFile) throws ClassNotFoundException {
/* /*
Die transitive Hülle muss funktionieren. Die transitive Hülle muss funktionieren.
Man darf schreiben List<A> extends AL<A> Man darf schreiben List<A> extends AL<A>
@@ -67,9 +68,6 @@ public class UnifyTypeFactory {
public static UnifyType convert(RefTypeOrTPHOrWildcardOrGeneric t, Boolean innerType){ public static UnifyType convert(RefTypeOrTPHOrWildcardOrGeneric t, Boolean innerType){
if(t instanceof GenericRefType){ if(t instanceof GenericRefType){
return UnifyTypeFactory.convert((GenericRefType)t, innerType); return UnifyTypeFactory.convert((GenericRefType)t, innerType);
}else
if(t instanceof FunN){
return UnifyTypeFactory.convert((FunN)t, innerType);
}else if(t instanceof TypePlaceholder){ }else if(t instanceof TypePlaceholder){
return UnifyTypeFactory.convert((TypePlaceholder)t, innerType); return UnifyTypeFactory.convert((TypePlaceholder)t, innerType);
}else if(t instanceof ExtendsWildcardType){ }else if(t instanceof ExtendsWildcardType){
@@ -85,13 +83,13 @@ public class UnifyTypeFactory {
public static UnifyType convert(RefType t, Boolean innerType){ public static UnifyType convert(RefType t, Boolean innerType){
//Check if it is a FunN Type: //Check if it is a FunN Type:
Pattern p = Pattern.compile("Fun(\\d+)"); Pattern p = Pattern.compile("Fun(\\d+)[$][$]");
Matcher m = p.matcher(t.getName().toString()); Matcher m = p.matcher(t.getName().toString());
boolean b = m.matches(); boolean b = m.matches();
if(b){ if(b){
Integer N = Integer.valueOf(m.group(1)); Integer N = Integer.valueOf(m.group(1));
if((N + 1) == t.getParaList().size()){ if((N + 1) == t.getParaList().size()){
return convert(new FunN(t.getParaList()), false); return convertFunN(t.getParaList(), false);
} }
} }
UnifyType ret; UnifyType ret;
@@ -102,16 +100,16 @@ 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;
} }
public static UnifyType convert(FunN t, Boolean innerType){ public static UnifyType convertFunN(List<RefTypeOrTPHOrWildcardOrGeneric> paraList, Boolean innerType){
UnifyType ret; UnifyType ret;
List<UnifyType> params = new ArrayList<>(); List<UnifyType> params = new ArrayList<>();
if(t.getParaList() != null && t.getParaList().size() > 0){ if(paraList != null && paraList.size() > 0){
for(RefTypeOrTPHOrWildcardOrGeneric pT : t.getParaList()){ for(RefTypeOrTPHOrWildcardOrGeneric pT : paraList){
params.add(UnifyTypeFactory.convert(pT, false)); params.add(UnifyTypeFactory.convert(pT, false));
} }
} }
@@ -138,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){
@@ -224,18 +222,21 @@ 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;
} }
public static RefTypeOrTPHOrWildcardOrGeneric convert(FunNType t, Map<String,TypePlaceholder> tphs) { public static RefTypeOrTPHOrWildcardOrGeneric convert(FunNType t, Map<String,TypePlaceholder> tphs) {
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;
} }

@@ -1,41 +0,0 @@
package de.dhbwstuttgart.syntaxtree.type;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import java.util.List;
/**
* @see Spezifikation "Complete Typeinference in Java 8" von Martin Plümicke
* "interface FunN<R,T1, T2, ... ,TN> { R apply(T1 arg1, T2 arg2, ... , TN argN); }"
* @author A10023 - Andreas Stadelmeier
*
* Bemerkung:
* FunN ist ein RefType. Der RefType ist nicht mit einem FunNInterface verbunden.
*
*/
public class FunN extends RefType {
/**
* @author Andreas Stadelmeier, a10023
* Benötigt für den Typinferenzalgorithmus für Java 8
* Generiert einen RefType auf eine FunN<R,T1,...,TN> - Klasse.
* @param params
* @return
*/
public FunN(List<RefTypeOrTPHOrWildcardOrGeneric> params) {
super(new JavaClassName("Fun"+(params.size()-1)), params, new NullToken());
}
/**
* Spezieller Konstruktor um eine FunN ohne Returntype zu generieren
protected FunN(List<? extends Type> list){
super("",0);
if(list==null)throw new NullPointerException();
setT(list);
this.name = new JavaClassName("Fun"+list.size());//getName();
}
*/
}

@@ -1,9 +1,6 @@
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;

@@ -32,7 +32,7 @@ public class TypeInsertFactory {
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)))); return new TypeInsert(insertPoint, new HashSet<>());
} }
private static TypeInsertPoint createGenericInsert(Set<GenericInsertPair> toInsert, ClassOrInterface cl, Method m){ private static TypeInsertPoint createGenericInsert(Set<GenericInsertPair> toInsert, ClassOrInterface cl, Method m){

@@ -8,7 +8,7 @@ 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;
public TypeInsertPoint(Token point, String toInsert){ public TypeInsertPoint(Token point, String toInsert){
@@ -28,6 +28,14 @@ public class TypeInsertPoint {
return insertString; return insertString;
} }
public Token getToken() {
return this.point;
}
public void setToken(Token point) {
this.point = point;
}
/* 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

@@ -21,7 +21,7 @@ import java.util.Optional;
public class FunNClass extends ClassOrInterface { public class FunNClass extends ClassOrInterface {
public FunNClass(List<GenericRefType> funNParams) { public FunNClass(List<GenericRefType> funNParams) {
super(0, new JavaClassName("Fun"+(funNParams.size())), new ArrayList<>(), Optional.empty() /* eingefuegt PL 2018-11-24 */, super(0, new JavaClassName("Fun"+(funNParams.size()-1)), new ArrayList<>(), Optional.empty() /* eingefuegt PL 2018-11-24 */,
createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams), createMethods(funNParams), new ArrayList<>(), createGenerics(funNParams),
ASTFactory.createObjectType(), true, new ArrayList<>(), new NullToken()); ASTFactory.createObjectType(), true, new ArrayList<>(), new NullToken());

@@ -1,10 +1,10 @@
package de.dhbwstuttgart.typeinference.assumptions; package de.dhbwstuttgart.typeinference.assumptions;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.TypeScope;
import de.dhbwstuttgart.syntaxtree.type.FunN;
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;
@@ -63,7 +63,7 @@ public class MethodAssumption extends Assumption{
} }
RefTypeOrTPHOrWildcardOrGeneric receiverType; RefTypeOrTPHOrWildcardOrGeneric receiverType;
if(receiver instanceof FunNClass){ if(receiver instanceof FunNClass){
receiverType = new FunN(params); receiverType = new RefType(new JavaClassName(receiver.getClassName().toString()+"$$"), params, new NullToken()); // new FunN(params);
}else{ }else{
receiverType = new RefType(receiver.getClassName(), params, new NullToken()); receiverType = new RefType(receiver.getClassName(), params, new NullToken());
} }

@@ -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() + ")";
}
} }

@@ -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() + ")";
}
} }

@@ -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() + ")";
}
} }

@@ -8,10 +8,10 @@ import java.util.Set;
public class ResolvedType{ public class ResolvedType{
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;
} }
} }

@@ -6,11 +6,16 @@ import de.dhbwstuttgart.syntaxtree.type.*;
import java.util.HashSet; import java.util.HashSet;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
public class ResultSet { public class ResultSet {
public final Set<ResultPair> results; public final Set<ResultPair> results;
public Set<ResultPair<TypePlaceholder, TypePlaceholder>> genIns;
public ResultSet(Set<ResultPair> results){ public ResultSet(Set<ResultPair> results){
this.results = results; this.results = results;
this.genIns = results.stream().filter(a -> a instanceof PairTPHsmallerTPH)
//.map(b -> new GenericInsertPair( (TypePlaceholder)(b.getLeft()), (TypePlaceholder)(b.getRight())))
.collect(Collectors.toCollection(HashSet::new));
} }
public ResolvedType resolveType(RefTypeOrTPHOrWildcardOrGeneric type) { public ResolvedType resolveType(RefTypeOrTPHOrWildcardOrGeneric type) {

@@ -65,7 +65,9 @@ public class TYPEStmt implements StatementVisitor{
//lambdaParams.add(0,tphRetType); //lambdaParams.add(0,tphRetType);
constraintsSet.addUndConstraint( constraintsSet.addUndConstraint(
new Pair(lambdaExpression.getType(), new Pair(lambdaExpression.getType(),
new FunN(lambdaParams),PairOperator.EQUALSDOT)); new RefType(new JavaClassName("Fun"+(lambdaParams.size()-1)+"$$"), lambdaParams, new NullToken()),
//new FunN(lambdaParams),
PairOperator.EQUALSDOT));
constraintsSet.addUndConstraint( constraintsSet.addUndConstraint(
new Pair(lambdaExpression.getReturnType(), new Pair(lambdaExpression.getReturnType(),
tphRetType,PairOperator.EQUALSDOT)); tphRetType,PairOperator.EQUALSDOT));

@@ -4,10 +4,12 @@ import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Queue; import java.util.Queue;
import java.util.Set; import java.util.Set;
import java.util.Stack; import java.util.Stack;
import java.util.function.Function;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.DebugException;
@@ -28,6 +30,7 @@ import de.dhbwstuttgart.typeinference.unify.distributeVariance;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.Writer;
/** /**
* Implementation of the type inference rules. * Implementation of the type inference rules.
@@ -36,13 +39,13 @@ import java.io.IOException;
*/ */
public class RuleSet implements IRuleSet{ public class RuleSet implements IRuleSet{
FileWriter logFile; Writer logFile;
public RuleSet() { public RuleSet() {
super(); super();
} }
RuleSet(FileWriter logFile) { RuleSet(Writer logFile) {
this.logFile = logFile; this.logFile = logFile;
} }
@@ -619,8 +622,12 @@ public class RuleSet implements IRuleSet{
return succ ? permutation : new int[0]; return succ ? permutation : new int[0];
} }
@Override
public Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs) { public Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs) {
return subst(pairs, new ArrayList<>());
}
@Override
public Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs, List<Set<Set<UnifyPair>>> oderConstraints) {
HashMap<UnifyType, Integer> typeMap = new HashMap<>(); HashMap<UnifyType, Integer> typeMap = new HashMap<>();
Stack<UnifyType> occuringTypes = new Stack<>(); Stack<UnifyType> occuringTypes = new Stack<>();
@@ -660,13 +667,35 @@ public class RuleSet implements IRuleSet{
if(lhsType != null if(lhsType != null
//&& !((rhsType = pair.getRhsType()) instanceof PlaceholderType) //PL geloescht am 2017-09-29 Begründung: auch Typvariablen muessen ersetzt werden. //&& !((rhsType = pair.getRhsType()) instanceof PlaceholderType) //PL geloescht am 2017-09-29 Begründung: auch Typvariablen muessen ersetzt werden.
&& typeMap.get(lhsType) > 1 // The type occurs in more pairs in the set than just the recent pair. && typeMap.get(lhsType) > 1 // The type occurs in more pairs in the set than just the recent pair.
&& !rhsType.getTypeParams().occurs(lhsType)) { && !rhsType.getTypeParams().occurs(lhsType)
&& !((rhsType instanceof WildcardType) && ((WildcardType)rhsType).getWildcardedType().equals(lhsType))) //PL eigefuegt 2018-02-18
{
Unifier uni = new Unifier(lhsType, rhsType); Unifier uni = new Unifier(lhsType, rhsType);
result = result.stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(ArrayList::new)); result = result.stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(ArrayList::new));
result1 = result1.stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(LinkedList::new)); result1 = result1.stream().map(x -> uni.apply(pair,x)).collect(Collectors.toCollection(LinkedList::new));
Function<? super Set<UnifyPair>,? extends HashSet<UnifyPair>> applyUni = b -> b.stream().map(
x -> uni.apply(pair,x)).collect(Collectors.toCollection(HashSet::new));
List<Set<Set<UnifyPair>>> oderConstraintsRet = new ArrayList<>();
for(Set<Set<UnifyPair>> oc : oderConstraints) {
//Set<Set<UnifyPair>> ocRet = new HashSet<>();
//for(Set<UnifyPair> cs : oc) {
Set<Set<UnifyPair>> csRet = oc.stream().map(applyUni).collect(Collectors.toCollection(HashSet::new));
oderConstraintsRet.add(csRet);
//}
}
oderConstraints.replaceAll(oc -> oc.stream().map(applyUni).collect(Collectors.toCollection(HashSet::new)));
/*
oderConstraints = oderConstraints.stream().map(
a -> a.stream().map(applyUni
//b -> b.stream().map(
// x -> uni.apply(pair,x)).collect(Collectors.toCollection(HashSet::new) )
).collect(Collectors.toCollection(HashSet::new))
).collect(Collectors.toList(ArrayList::new));
}
*/
applied = true; applied = true;
} }
result.add(pair); result.add(pair);
} }
@@ -945,6 +974,8 @@ public class RuleSet implements IRuleSet{
UnifyType extendedType = ((ExtendsType)lhsType).getExtendedType(); UnifyType extendedType = ((ExtendsType)lhsType).getExtendedType();
if (extendedType.equals(rhsType)) return Optional.empty(); //PL 2019-02-18 eingefügt ? extends a <.? a
boolean isGen = extendedType instanceof PlaceholderType && !((PlaceholderType) extendedType).isGenerated(); boolean isGen = extendedType instanceof PlaceholderType && !((PlaceholderType) extendedType).isGenerated();
Set<UnifyPair> result = new HashSet<>(); Set<UnifyPair> result = new HashSet<>();
@@ -971,6 +1002,8 @@ public class RuleSet implements IRuleSet{
UnifyType superedType = ((SuperType)lhsType).getSuperedType(); UnifyType superedType = ((SuperType)lhsType).getSuperedType();
if (superedType.equals(rhsType)) return Optional.empty(); //PL 2019-02-18 eingefügt ? super a <.? a
boolean isGen = superedType instanceof PlaceholderType && !((PlaceholderType) superedType).isGenerated(); boolean isGen = superedType instanceof PlaceholderType && !((PlaceholderType) superedType).isGenerated();
Set<UnifyPair> result = new HashSet<>(); Set<UnifyPair> result = new HashSet<>();

@@ -1,6 +1,8 @@
package de.dhbwstuttgart.typeinference.unify; package de.dhbwstuttgart.typeinference.unify;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
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;
@@ -13,26 +15,73 @@ import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair; import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
public class TypeUnify { public class TypeUnify {
public Set<Set<UnifyPair>> unify(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log, ConstraintSet<Pair> cons) {
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, new UnifyResultModel(), cons); /**
* unify parallel ohne result modell
* @param undConstrains
* @param oderConstraints
* @param fc
* @param logFile
* @param log
* @param cons
* @return
*/
public Set<Set<UnifyPair>> unify(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret) {
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret);
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();
try {
logFile.write("\nnoShortendElements: " + unifyTask.noShortendElements + "\n");
logFile.flush();
}
catch (IOException e) {
System.err.println("no log-File");
}
return res; return res;
} }
public UnifyResultModel unifyAsync(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log, ConstraintSet<Pair> cons, UnifyResultModel ret) { /**
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, cons); * unify asynchron mit Rückgabe UnifyResultModel ohne dass alle results gesammelt sind
* @param undConstrains
* @param oderConstraints
* @param fc
* @param logFile
* @param log
* @param cons
* @param ret
* @return
*/
public UnifyResultModel unifyAsync(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret) {
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret);
ForkJoinPool pool = new ForkJoinPool(); ForkJoinPool pool = new ForkJoinPool();
pool.invoke(unifyTask); pool.invoke(unifyTask);
return ret; return ret;
} }
public UnifyResultModel unifyParallel(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log, ConstraintSet<Pair> cons, UnifyResultModel ret) { /**
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret, cons); * unify parallel mit Rückgabe UnifyResultModel nachdem alle results gesammelt sind
* @param undConstrains
* @param oderConstraints
* @param fc
* @param logFile
* @param log
* @param cons
* @param ret
* @return
*/
public UnifyResultModel unifyParallel(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret) {
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, true, logFile, log, 0, ret);
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();
try {
logFile.write("\nnoShortendElements: " + unifyTask.noShortendElements +"\n");
logFile.flush();
}
catch (IOException e) {
System.err.println("no log-File");
}
return ret; return ret;
} }
@@ -44,9 +93,26 @@ public class TypeUnify {
} }
*/ */
public Set<Set<UnifyPair>> unifyOderConstraints(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, FileWriter logFile, Boolean log, ConstraintSet<Pair> cons) { /**
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, false, logFile, log, 0, new UnifyResultModel(), cons); * unify sequentiell mit oderconstraints
* @param undConstrains
* @param oderConstraints
* @param fc
* @param logFile
* @param log
* @param cons
* @return
*/
public Set<Set<UnifyPair>> unifyOderConstraints(Set<UnifyPair> undConstrains, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, Writer logFile, Boolean log, UnifyResultModel ret) {
TypeUnifyTask unifyTask = new TypeUnifyTask(undConstrains, oderConstraints, fc, false, logFile, log, 0, ret);
Set<Set<UnifyPair>> res = unifyTask.compute(); Set<Set<UnifyPair>> res = unifyTask.compute();
try {
logFile.write("\nnoShortendElements: " + unifyTask.noShortendElements +"\n");
logFile.flush();
}
catch (IOException e) {
System.err.println("no log-File");
}
return res; return res;
} }

@@ -1,6 +1,8 @@
package de.dhbwstuttgart.typeinference.unify; package de.dhbwstuttgart.typeinference.unify;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
@@ -15,8 +17,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, FileWriter logFile, Boolean log, int rekTiefe, UnifyResultModel urm, ConstraintSet<Pair> cons) { 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) {
super(eq, oderConstraints, fc, parallel, logFile, log, rekTiefe, urm, cons); super(eq, oderConstraints, fc, parallel, logFile, log, rekTiefe, urm);
this.setToFlatten = setToFlatten; this.setToFlatten = setToFlatten;
this.nextSetElement = nextSetElement; this.nextSetElement = nextSetElement;
} }
@@ -31,12 +33,23 @@ public class TypeUnify2Task extends TypeUnifyTask {
System.out.println("two"); System.out.println("two");
} }
one = true; one = true;
Set<Set<UnifyPair>> res = unify2(setToFlatten, eq, oderConstraintsField, fc, parallel, rekTiefeField); Set<Set<UnifyPair>> res = unify2(setToFlatten, eq, oderConstraintsField, fc, parallel, rekTiefeField, true);
/*if (isUndefinedPairSetSet(res)) { /*if (isUndefinedPairSetSet(res)) {
return new HashSet<>(); } return new HashSet<>(); }
else else
*/ */
noOfThread--; noOfThread--;
return res; return res;
}
public void closeLogFile() {
try {
logFile.close();
}
catch (IOException ioE) {
System.err.println("no log-File" + thNo);
}
} }
} }

@@ -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,8 @@ 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 com.google.common.collect.Ordering; import com.google.common.collect.Ordering;
@@ -68,7 +74,6 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
* Fuer die Threads * Fuer die Threads
*/ */
UnifyResultModel urm; UnifyResultModel urm;
ConstraintSet<de.dhbwstuttgart.typeinference.constraints.Pair> cons;
protected static int noOfThread = 0; protected static int noOfThread = 0;
private static int totalnoOfThread = 0; private static int totalnoOfThread = 0;
int thNo; int thNo;
@@ -76,7 +81,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
Integer MaxNoOfThreads = 8; Integer MaxNoOfThreads = 8;
public static final String rootDirectory = System.getProperty("user.dir")+"/test/logFiles/"; public static final String rootDirectory = System.getProperty("user.dir")+"/test/logFiles/";
FileWriter logFile; Writer logFile;
/** /**
* The implementation of setOps that will be used during the unification * The implementation of setOps that will be used during the unification
@@ -115,6 +120,8 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
static int noBacktracking; static int noBacktracking;
static Integer noShortendElements = 0;
public TypeUnifyTask() { public TypeUnifyTask() {
rules = new RuleSet(); rules = new RuleSet();
} }
@@ -133,7 +140,8 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
} }
*/ */
public TypeUnifyTask(Set<UnifyPair> eq, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, FileWriter logFile, Boolean log, int rekTiefe, UnifyResultModel urm, ConstraintSet<de.dhbwstuttgart.typeinference.constraints.Pair> cons2) {
public TypeUnifyTask(Set<UnifyPair> eq, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, Writer logFile, Boolean log, int rekTiefe, UnifyResultModel urm) {
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));
@@ -153,16 +161,23 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
this.parallel = parallel; this.parallel = parallel;
this.logFile = logFile; this.logFile = logFile;
this.log = log; this.log = log;
noOfThread++;
totalnoOfThread++;
//writeLog("thNo1 " + thNo);
thNo = totalnoOfThread;
writeLog("thNo2 " + thNo);
try {
this.logFile = //new OutputStreamWriter(new NullOutputStream());
new FileWriter(new File(System.getProperty("user.dir")+"/src/test/java/logFiles/"+"Thread_"+thNo));
//logFile.write("");
}
catch (IOException e) {
System.err.println("log-File nicht vorhanden");
}
rules = new RuleSet(logFile); rules = new RuleSet(logFile);
this.rekTiefeField = rekTiefe; this.rekTiefeField = rekTiefe;
this.urm = urm; this.urm = urm;
this.cons = cons2;
noOfThread++;
totalnoOfThread++;
writeLog("thNo1 " + thNo);
thNo = totalnoOfThread;
writeLog("thNo2 " + thNo);
} }
} }
@@ -212,9 +227,17 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
ArrayList<Set<Set<UnifyPair>>> remainingOderconstraints = oderConstraintsField.stream() ArrayList<Set<Set<UnifyPair>>> remainingOderconstraints = oderConstraintsField.stream()
.filter(x -> x.size()>1) .filter(x -> x.size()>1)
.collect(Collectors.toCollection(ArrayList::new)); .collect(Collectors.toCollection(ArrayList::new));
Set<Set<UnifyPair>> res = unify(neweq, remainingOderconstraints, fc, parallel, rekTiefeField); Set<Set<UnifyPair>> res = unify(neweq, remainingOderconstraints, fc, parallel, rekTiefeField, true);
noOfThread--; noOfThread--;
if (isUndefinedPairSetSet(res)) { return new HashSet<>(); } try {
logFile.close();
}
catch (IOException ioE) {
System.err.println("no log-File");
}
if (isUndefinedPairSetSet(res)) {
throw new TypeinferenceException("Unresolved constraints: " + res.toString(), new NullToken()); //return new HashSet<>();
}
else return res; else return res;
} }
/* /*
@@ -229,253 +252,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
*/ */
public Set<Set<UnifyPair>> computeCartesianRecursiveOderConstraints(Set<Set<UnifyPair>> fstElems, List<Set<Set<UnifyPair>>> topLevelSets, IFiniteClosure fc, boolean parallel, int rekTiefe) {
//ArrayList<Set<Set<UnifyPair>>> remainingSets = new ArrayList<>(topLevelSets);
fstElems.addAll(topLevelSets.stream()
.filter(x -> x.size()==1)
.map(y -> y.stream().findFirst().get())
.collect(Collectors.toCollection(HashSet::new)));
ArrayList<Set<Set<UnifyPair>>> remainingSets = topLevelSets.stream()
.filter(x -> x.size()>1)
.collect(Collectors.toCollection(ArrayList::new));
if (remainingSets.isEmpty()) {//Alle Elemente sind 1-elementig
Set<UnifyPair> eq = new HashSet<>();
fstElems.stream().forEach(x -> eq.addAll(x));
Set<Set<UnifyPair>> result = unify(eq, new ArrayList<>(), fc, parallel, rekTiefe);
return result;
}
Set<Set<UnifyPair>> nextSet = remainingSets.remove(0);
writeLog("nextSet: " + nextSet.toString());
List<Set<UnifyPair>> nextSetasList =new ArrayList<>(nextSet);
try {
//List<Set<UnifyPair>>
//nextSetasList = oup.sortedCopy(nextSet);//new ArrayList<>(nextSet);
}
catch (java.lang.IllegalArgumentException e) {
System.out.print("");
}
Set<Set<UnifyPair>> result = new HashSet<>();
int variance = 0;
Optional<Integer> xi = nextSetasList.stream().map(x -> x.stream().filter(y -> y.getLhsType() instanceof PlaceholderType)
.filter(z -> ((PlaceholderType)z.getLhsType()).getVariance() != 0)
.map(c -> ((PlaceholderType)c.getLhsType()).getVariance())
.reduce((a,b)-> {if (a==b) return a; else return 0; }))
.filter(d -> d.isPresent())
.map(e -> e.get())
.findAny();
if (xi.isPresent()) {
variance = xi.get();
}
//if (variance == 1 && nextSetasList.size() > 1) {
// List<Set<UnifyPair>> al = new ArrayList<>(nextSetasList.size());
// for (int ii = 0; ii < nextSetasList.size();ii++) {
// al.add(0,nextSetasList.get(ii));
// }
// nextSetasList = al;
//}
//Set<UnifyPair> a = nextSetasListIt.next();
/*if (nextSetasList.size()>1) {zu loeschen
if (nextSetasList.iterator().next().iterator().next().getLhsType().getName().equals("D"))
System.out.print("");
if (variance == 1) {
a_next = oup.max(nextSetasList.iterator());
}
else if (variance == -1) {
a_next = oup.min(nextSetasList.iterator());
}
else if (variance == 0) {
a_next = nextSetasList.iterator().next();
}
}
else {
a_next = nextSetasList.iterator().next();
}
*/
if (!nextSetasList.iterator().hasNext())
System.out.print("");
if (nextSetasList.iterator().next().stream().filter(x -> x.getLhsType().getName().equals("D")).findFirst().isPresent() && nextSetasList.size()>1)
System.out.print("");
writeLog("nextSetasList: " + nextSetasList.toString());
while (nextSetasList.size() > 0) { //(nextSetasList.size() != 0) {
Set<UnifyPair> a = null;
if (variance == 1) {
a = oup.max(nextSetasList.iterator());
nextSetasList.remove(a);
}
else if (variance == -1) {
a = oup.min(nextSetasList.iterator());
nextSetasList.remove(a);
}
else if (variance == 0) {
a = nextSetasList.remove(0);
}
//writeLog("nextSet: " + nextSetasList.toString()+ "\n");
//nextSetasList.remove(a);
/* zu loeschen
if (nextSetasList.size() > 0) {
if (nextSetasList.size()>1) {
if (variance == 1) {
a_next = oup.max(nextSetasList.iterator());
}
else if (variance == -1) {
a_next = oup.min(nextSetasList.iterator());
}
else {
a_next = nextSetasList.iterator().next();
}
}
else {
a_next = nextSetasList.iterator().next();
}
}
*/
//PL 2018-03-01
//TODO: 1. Maximum und Minimum unterscheiden
//TODO: 2. compare noch für alle Elmemente die nicht X =. ty sind erweitern
//for(Set<UnifyPair> a : newSet) {
i++;
Set<Set<UnifyPair>> elems = new HashSet<Set<UnifyPair>>(fstElems);
elems.add(a);
Set<Set<UnifyPair>> res = new HashSet<>();
if (remainingSets.isEmpty()) {
noou++;
writeLog("Vor unify Aufruf: " + eq.toString());
writeLog("No of Unify " + noou);
System.out.println(noou);
Set<UnifyPair> eq = new HashSet<>();
elems.stream().forEach(x -> eq.addAll(x));
res = unify(eq, new ArrayList<>(), fc, parallel, rekTiefe);
}
else {//duerfte gar nicht mehr vorkommen PL 2018-04-03
res = computeCartesianRecursiveOderConstraints(elems, remainingSets, fc, parallel, rekTiefe);
}
if (!isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result)) {
//wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen
result = res;
}
else {
if ((isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result))
|| (!isUndefinedPairSetSet(res) && !isUndefinedPairSetSet(result))
|| result.isEmpty()) {
//alle Fehlerfaelle und alle korrekten Ergebnis jeweils adden
result.addAll(res);
}
//else {
//wenn Korrekte Ergebnisse da und Feherfälle dazukommen Fehlerfälle ignorieren
// if (isUndefinedPairSetSet(res) && !isUndefinedPairSetSet(result)) {
// result = result;
// }
//}
}
/* auskommentiert um alle Max und min Betrachtung auszuschalten ANFANG */
if (!result.isEmpty() && !isUndefinedPairSetSet(res)) {
if (nextSetasList.iterator().hasNext() && nextSetasList.iterator().next().stream().filter(x -> x.getLhsType().getName().equals("B")).findFirst().isPresent() && nextSetasList.size()>1)
System.out.print("");
Iterator<Set<UnifyPair>> nextSetasListIt = new ArrayList<Set<UnifyPair>>(nextSetasList).iterator();
if (variance == 1) {
System.out.println("");
while (nextSetasListIt.hasNext()) {
Set<UnifyPair> a_next = nextSetasListIt.next();
if (a.equals(a_next) ||
(oup.compare(a, a_next) == 1)) {
nextSetasList.remove(a_next);
}
else {
System.out.println("");
}
}
}
else { if (variance == -1) {
System.out.println("");
while (nextSetasListIt.hasNext()) {
Set<UnifyPair> a_next = nextSetasListIt.next();
if (a.equals(a_next) ||
(oup.compare(a, a_next) == -1)) {
nextSetasList.remove(0);
}
else {
System.out.println("");
}
}
}
else if (variance == 0) {
//break;
}}
}
/* auskommentiert um alle Max und min Betrachtung auszuschalten ENDE */
/* PL 2018-11-05 wird falsch weil es auf der obersten Ebene ist.
if (isUndefinedPairSetSet(res)) {
int nofstred= 0;
Set<UnifyPair> abhSubst = res.stream()
.map(b ->
b.stream()
.map(x -> x.getAllSubstitutions())
.reduce((y,z) -> { y.addAll(z); return y;}).get())
.reduce((y,z) -> { y.addAll(z); return y;}).get();
Set<UnifyPair> b = a;//effective final a
Set<UnifyPair> durchschnitt = abhSubst.stream()
.filter(x -> b.contains(x))
//.filter(y -> abhSubst.contains(y))
.collect(Collectors.toCollection(HashSet::new));
//Set<PlaceholderType> vars = durchschnitt.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new));
int len = nextSetasList.size();
Set<UnifyPair> undefRes = res.stream().reduce((y,z) -> { y.addAll(z); return y;}).get(); //flatten aller undef results
Set<Pair<Set<UnifyPair>, UnifyPair>> reducedUndefResSubstGroundedBasePair = undefRes.stream()
.map(x -> { Set<UnifyPair> su = x.getAllSubstitutions(); //alle benutzten Substitutionen
su.add(x.getGroundBasePair()); // urspruengliches Paar
su.removeAll(durchschnitt); //alle aktuell genänderten Paare entfernen
return new Pair<>(su, x.getGroundBasePair());})
.collect(Collectors.toCollection(HashSet::new));
if (res.size() > 1) {
System.out.println();
}
nextSetasList = nextSetasList.stream().filter(x -> {
//Boolean ret = false;
//for (PlaceholderType var : vars) {
// ret = ret || x.stream().map(b -> b.getLhsType().equals(var)).reduce((c,d) -> c || d).get();
//}
return (!x.containsAll(durchschnitt));//Was passiert wenn durchschnitt leer ist??
})//.filter(y -> couldBecorrect(reducedUndefResSubstGroundedBasePair, y)) //fuer testzwecke auskommentiert um nofstred zu bestimmen PL 2018-10-10
.collect(Collectors.toCollection(ArrayList::new));
nofstred = nextSetasList.size();
//NOCH NICHT korrekt PL 2018-10-12
//nextSetasList = nextSetasList.stream().filter(y -> couldBecorrect(reducedUndefResSubstGroundedBasePair, y))
// .collect(Collectors.toCollection(ArrayList::new));
writeLog("res (undef): " + res.toString());
writeLog("abhSubst: " + abhSubst.toString());
writeLog("a: " + a.toString());
writeLog("Durchschnitt: " + durchschnitt.toString());
writeLog("nextSet: " + nextSet.toString());
writeLog("nextSetasList: " + nextSetasList.toString());
writeLog("Number first erased Elements (undef): " + (len - nofstred));
writeLog("Number second erased Elements (undef): " + (nofstred- nextSetasList.size()));
writeLog("Number erased Elements (undef): " + (len - nextSetasList.size()));
noAllErasedElements = noAllErasedElements + (len - nextSetasList.size());
writeLog("Number of all erased Elements (undef): " + noAllErasedElements.toString());
noBacktracking++;
writeLog("Number of Backtracking: " + noBacktracking);
System.out.println("");
}
*/
//if (nextSetasList.size() == 0 && isUndefinedPairSetSet(result) && nextSet.size() > 1) {
// return result;
//}
//else {
// result.removeIf(y -> isUndefinedPairSet(y));
//}
//else result.stream().filter(y -> !isUndefinedPairSet(y));
} // End of while (nextSetasList.size() > 0)
return result;
}
/** /**
* Computes all principal type unifiers for a set of constraints. * Computes all principal type unifiers for a set of constraints.
@@ -483,7 +260,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
* @param fc The finite closure * @param fc The finite closure
* @return The set of all principal type unifiers * @return The set of all principal type unifiers
*/ */
protected Set<Set<UnifyPair>> unify(final Set<UnifyPair> eq, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, int rekTiefe) { protected Set<Set<UnifyPair>> unify(final Set<UnifyPair> eq, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, int rekTiefe, Boolean finalresult) {
//Set<UnifyPair> aas = eq.stream().filter(x -> x.getLhsType().getName().equals("AA") //&& x.getPairOp().equals(PairOperator.SMALLERDOT) //Set<UnifyPair> aas = eq.stream().filter(x -> x.getLhsType().getName().equals("AA") //&& x.getPairOp().equals(PairOperator.SMALLERDOT)
// ).collect(Collectors.toCollection(HashSet::new)); // ).collect(Collectors.toCollection(HashSet::new));
//writeLog(nOfUnify.toString() + " AA: " + aas.toString()); //writeLog(nOfUnify.toString() + " AA: " + aas.toString());
@@ -518,8 +295,19 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
return ret; return ret;
} }
Set<UnifyPair> eq0;
Set<UnifyPair> eq0Prime;
Optional<Set<UnifyPair>> eqSubst = Optional.of(eq);
do {
eq0Prime = eqSubst.get();
eq0 = applyTypeUnificationRules(eq0Prime, fc);
eqSubst = rules.subst(eq0, oderConstraints);
} while (eqSubst.isPresent());
Set<UnifyPair> eq0 = applyTypeUnificationRules(eq, fc); eq0.forEach(x -> x.disableCondWildcards());
writeLog(nOfUnify.toString() + " Unifikation nach applyTypeUnificationRules: " + eq.toString());
writeLog(nOfUnify.toString() + " Oderconstraints nach applyTypeUnificationRules: " + oderConstraints.toString());
/* /*
* Step 2 and 3: Create a subset eq1s of pairs where both sides are TPH and eq2s of the other pairs * Step 2 and 3: Create a subset eq1s of pairs where both sides are TPH and eq2s of the other pairs
@@ -548,6 +336,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
} }
// Add the set of [a =. Theta | (a=. Theta) in Eq2'] // Add the set of [a =. Theta | (a=. Theta) in Eq2']
//TODO: Occurscheck anwenden als Fehler identifizieren
Set<UnifyPair> bufferSet = eq2s.stream() Set<UnifyPair> bufferSet = eq2s.stream()
.filter(x -> x.getPairOp() == PairOperator.EQUALSDOT && x.getLhsType() instanceof PlaceholderType) .filter(x -> x.getPairOp() == PairOperator.EQUALSDOT && x.getLhsType() instanceof PlaceholderType)
.collect(Collectors.toSet()); .collect(Collectors.toSet());
@@ -583,6 +372,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
Set<Set<UnifyPair>> error = new HashSet<>(); Set<Set<UnifyPair>> error = new HashSet<>();
undefinedPairs = undefinedPairs.stream().map(x -> { x.setUndefinedPair(); return x;}).collect(Collectors.toCollection(HashSet::new)); undefinedPairs = undefinedPairs.stream().map(x -> { x.setUndefinedPair(); return x;}).collect(Collectors.toCollection(HashSet::new));
error.add(undefinedPairs); error.add(undefinedPairs);
undefinedPairs.forEach(x -> writeLog("AllSubst: " +x.getAllSubstitutions().toString()));
return error; return error;
} }
@@ -623,12 +413,12 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//Aufruf von computeCartesianRecursive ANFANG //Aufruf von computeCartesianRecursive ANFANG
//writeLog("topLevelSets: " + topLevelSets.toString()); //writeLog("topLevelSets: " + topLevelSets.toString());
return computeCartesianRecursive(new HashSet<>(), new ArrayList<>(topLevelSets), eq, oderConstraintsOutput, fc, parallel, rekTiefe); return computeCartesianRecursive(new HashSet<>(), new ArrayList<>(topLevelSets), eq, oderConstraintsOutput, fc, parallel, rekTiefe, finalresult);
} }
Set<Set<UnifyPair>> unify2(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, int rekTiefe) { Set<Set<UnifyPair>> unify2(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, List<Set<Set<UnifyPair>>> oderConstraints, IFiniteClosure fc, boolean parallel, int rekTiefe, Boolean finalresult) {
//Aufruf von computeCartesianRecursive ENDE //Aufruf von computeCartesianRecursive ENDE
//keine Ahnung woher das kommt //keine Ahnung woher das kommt
@@ -656,9 +446,13 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
* Step 5: Substitution * Step 5: Substitution
*/ */
//writeLog("vor Subst: " + eqPrime); //writeLog("vor Subst: " + eqPrime);
Optional<Set<UnifyPair>> eqPrimePrime = rules.subst(eqPrime); writeLog("vor Subst: " + oderConstraints);
String ocString = oderConstraints.toString();
List<Set<Set<UnifyPair>>> newOderConstraints = new ArrayList<>(oderConstraints);
Optional<Set<UnifyPair>> eqPrimePrime = rules.subst(eqPrime, newOderConstraints);
Set<Set<UnifyPair>> unifyres1 = null; Set<Set<UnifyPair>> unifyres1 = null;
Set<Set<UnifyPair>> unifyres2 = null; Set<Set<UnifyPair>> unifyres2 = null;
if (!ocString.equals(newOderConstraints.toString())) writeLog("nach Subst: " + newOderConstraints);
//writeLog("nach Subst: " + eqPrimePrime); //writeLog("nach Subst: " + eqPrimePrime);
/* /*
* Step 6 a) Restart (fork) for pairs where subst was applied * Step 6 a) Restart (fork) for pairs where subst was applied
@@ -693,34 +487,26 @@ 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);
Set<Set<UnifyPair>> eqPrimePrimeSetRet = eqPrimePrimeSet.stream().map(x -> { if (finalresult && isSolvedForm(eqPrime)) {
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> { writeLog("eqPrime:" + eqPrime.toString()+"\n");
if (y.getPairOp() == PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT); urm.notify(eqPrimePrimeSet);
return y; //alle Paare a <.? b erden durch a =. b ersetzt }
}).collect(Collectors.toCollection(HashSet::new)));
if (res.isPresent()) {//wenn subst ein Erg liefert wurde was veraendert
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), fc);
}
else return x; //wenn nichts veraendert wurde wird x zurueckgegeben
}).collect(Collectors.toCollection(HashSet::new));
urm.notify(eqPrimePrimeSetRet.stream().map((unifyPairs ->
new ResultSet(UnifyTypeFactory.convert(unifyPairs, de.dhbwstuttgart.typeinference.constraints.Pair.generateTPHMap(cons))))).collect(Collectors.toList()));
} }
else if(eqPrimePrime.isPresent()) { else if(eqPrimePrime.isPresent()) {
Set<Set<UnifyPair>> unifyres = unifyres1 = unify(eqPrimePrime.get(), oderConstraints, fc, parallel, rekTiefe); Set<Set<UnifyPair>> unifyres = unifyres1 = unify(eqPrimePrime.get(), newOderConstraints, fc, parallel, rekTiefe, finalresult);
eqPrimePrimeSet.addAll(unifyres); eqPrimePrimeSet.addAll(unifyres);
} }
else { else {
Set<Set<UnifyPair>> unifyres = unifyres2 = unify(eqPrime, oderConstraints, fc, parallel, rekTiefe); Set<Set<UnifyPair>> unifyres = unifyres2 = unify(eqPrime, newOderConstraints, fc, parallel, rekTiefe, finalresult);
eqPrimePrimeSet.addAll(unifyres); eqPrimePrimeSet.addAll(unifyres);
@@ -752,7 +538,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) { 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)
@@ -762,11 +548,11 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
.filter(x -> x.size()>1) .filter(x -> x.size()>1)
.collect(Collectors.toCollection(ArrayList::new)); .collect(Collectors.toCollection(ArrayList::new));
if (remainingSets.isEmpty()) {//Alle Elemente sind 1-elementig if (remainingSets.isEmpty()) {//Alle Elemente sind 1-elementig
Set<Set<UnifyPair>> result = unify2(fstElems, eq, oderConstraints, fc, parallel, rekTiefe); Set<Set<UnifyPair>> result = unify2(fstElems, eq, oderConstraints, fc, parallel, rekTiefe, finalresult);
return result; return result;
} }
Set<Set<UnifyPair>> nextSet = remainingSets.remove(0); Set<Set<UnifyPair>> nextSet = remainingSets.remove(0);
writeLog("nextSet: " + nextSet.toString()); if (finalresult) writeLog("nextSet: " + nextSet.toString());
List<Set<UnifyPair>> nextSetasList =new ArrayList<>(nextSet); List<Set<UnifyPair>> nextSetasList =new ArrayList<>(nextSet);
try { try {
//List<Set<UnifyPair>> //List<Set<UnifyPair>>
@@ -777,16 +563,35 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
} }
Set<Set<UnifyPair>> result = new HashSet<>(); Set<Set<UnifyPair>> result = new HashSet<>();
int variance = 0; int variance = 0;
Optional<Integer> xi = nextSetasList.stream().map(x -> x.stream().filter(y -> y.getLhsType() instanceof PlaceholderType)
.filter(z -> ((PlaceholderType)z.getLhsType()).getVariance() != 0) ArrayList<UnifyPair> zeroNextElem = new ArrayList<>(nextSetasList.get(0));
.map(c -> ((PlaceholderType)c.getLhsType()).getVariance()) UnifyPair fstBasePair = zeroNextElem.remove(0).getBasePair();
.reduce((a,b)-> {if (a==b) return a; else return 2; })) //2 kommt insbesondere bei Oder-Constraints vor
.filter(d -> d.isPresent()) if (fstBasePair != null) {
.map(e -> e.get()) Boolean sameBase = true;
.findAny(); for (UnifyPair ele : nextSetasList.get(0)) {//check ob a <. ty base oder ob Ueberladung
if (xi.isPresent()) { sameBase = sameBase && ele.getBasePair() != null && ele.getBasePair().equals(fstBasePair);
variance = xi.get(); }
} if (sameBase) {
Optional<Integer> xi = nextSetasList.stream().map(x -> x.stream().filter(y -> y.getLhsType() instanceof PlaceholderType)
.filter(z -> ((PlaceholderType)z.getLhsType()).getVariance() != 0)
.map(c -> ((PlaceholderType)c.getLhsType()).getVariance())
.reduce((a,b)-> {if (a==b) return a; else return 0; })) //2 kommt insbesondere bei Oder-Constraints vor
.filter(d -> d.isPresent())
.map(e -> e.get())
.findAny();
if (xi.isPresent()) {
variance = xi.get();
}
}
else {
variance = 2;
}
}
else {
variance = 2;
}
//if (variance == 1 && nextSetasList.size() > 1) { //if (variance == 1 && nextSetasList.size() > 1) {
// List<Set<UnifyPair>> al = new ArrayList<>(nextSetasList.size()); // List<Set<UnifyPair>> al = new ArrayList<>(nextSetasList.size());
// for (int ii = 0; ii < nextSetasList.size();ii++) { // for (int ii = 0; ii < nextSetasList.size();ii++) {
@@ -816,7 +621,43 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
System.out.print(""); System.out.print("");
if (nextSetasList.iterator().next().stream().filter(x -> x.getLhsType().getName().equals("D")).findFirst().isPresent() && nextSetasList.size()>1) if (nextSetasList.iterator().next().stream().filter(x -> x.getLhsType().getName().equals("D")).findFirst().isPresent() && nextSetasList.size()>1)
System.out.print(""); System.out.print("");
writeLog("nextSetasList: " + nextSetasList.toString()); if (finalresult) writeLog("nextSetasList: " + nextSetasList.toString());
Set<UnifyPair> nextSetElem = nextSetasList.get(0);
if (finalresult) writeLog("BasePair1: " + nextSetElem + " " + nextSetElem.iterator().next().getBasePair());
/* sameEqSet-Bestimmung: Wenn a = ty \in nextSet dann enthaelt sameEqSet alle Paare a < ty1 oder ty2 < a aus fstElems */
Set<UnifyPair> sameEqSet = new HashSet<>();
if (variance != 2) {
Optional<UnifyPair> optOrigPair = nextSetElem.stream().filter(x -> (
//x.getBasePair() != null && ist gegeben wenn variance != 2
//x.getBasePair().getPairOp().equals(PairOperator.SMALLERDOT) &&
(x.getPairOp().equals(PairOperator.EQUALSDOT)
/*
(x.getBasePair().getLhsType() instanceof PlaceholderType
&& x.getLhsType().equals(x.getBasePair().getLhsType()))
|| (x.getBasePair().getRhsType() instanceof PlaceholderType
&& x.getLhsType().equals(x.getBasePair().getRhsType())
*/
))).filter(x -> //Sicherstellen, dass bei a = ty a auch wirklich die gesuchte Typvariable ist
x.getLhsType().equals(x.getBasePair().getLhsType()) ||
x.getLhsType().equals(x.getBasePair().getRhsType())
).findFirst();
writeLog("optOrigPair: " + optOrigPair);
if (optOrigPair.isPresent()) {
UnifyPair origPair = optOrigPair.get();
UnifyType tyVar;
if (!((tyVar = origPair.getLhsType()) instanceof PlaceholderType)) {
tyVar = origPair.getRhsType();
}
UnifyType tyVarEF = tyVar;
sameEqSet = fstElems.stream().map(xx -> xx.iterator().next())
.filter(x -> (((x.getLhsType().equals(tyVarEF) && !(x.getRhsType() instanceof PlaceholderType))
|| (x.getRhsType().equals(tyVarEF) && !(x.getLhsType() instanceof PlaceholderType)))))
.collect(Collectors.toCollection(HashSet::new));
}
}
/* sameEqSet-Bestimmung Ende */
Set<UnifyPair> a = null; Set<UnifyPair> a = null;
while (nextSetasList.size() > 0) { //(nextSetasList.size() != 0) { while (nextSetasList.size() > 0) { //(nextSetasList.size() != 0) {
Set<UnifyPair> a_last = a; Set<UnifyPair> a_last = a;
@@ -916,7 +757,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//for(Set<UnifyPair> a : newSet) { //for(Set<UnifyPair> a : newSet) {
i++; i++;
Set<Set<UnifyPair>> elems = new HashSet<Set<UnifyPair>>(fstElems); Set<Set<UnifyPair>> elems = new HashSet<Set<UnifyPair>>(fstElems);
writeLog("a1: " + rekTiefe + " "+ "variance: "+ variance + " " + a.toString()+ "\n"); if (finalresult) writeLog("a1: " + rekTiefe + " "+ "variance: "+ variance + " " + a.toString()+ "\n");
//elems.add(a); PL 2019-01-20 Muss weg, weil das in jeweiligen Thread erfolgen muss. Fuer den sequentiellen Fall //elems.add(a); PL 2019-01-20 Muss weg, weil das in jeweiligen Thread erfolgen muss. Fuer den sequentiellen Fall
//im else-Zweig //im else-Zweig
//if (remainingSets.isEmpty()) {//muss immer gegeben sein, weil nur 1 Element der topLevelSets mehr als ein Elemet enthaelt //if (remainingSets.isEmpty()) {//muss immer gegeben sein, weil nur 1 Element der topLevelSets mehr als ein Elemet enthaelt
@@ -924,6 +765,37 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
Set<Set<UnifyPair>> res = new HashSet<>(); Set<Set<UnifyPair>> res = new HashSet<>();
Set<Set<Set<UnifyPair>>> add_res = new HashSet<>(); Set<Set<Set<UnifyPair>>> add_res = new HashSet<>();
Set<Set<UnifyPair>> aParDef = new HashSet<>(); Set<Set<UnifyPair>> aParDef = new HashSet<>();
/* PL 2019-03-11 Anfang eingefuegt Vergleich mit anderen Paaren ggf. loeschen */
if (variance != 2 && !sameEqSet.isEmpty()) {
Optional<UnifyPair> optAPair = a.stream().filter(x -> (
//x.getBasePair() != null && ist gegeben wenn variance != 2
//x.getBasePair().getPairOp().equals(PairOperator.SMALLERDOT) &&
(x.getPairOp().equals(PairOperator.EQUALSDOT)
/*
(x.getBasePair().getLhsType() instanceof PlaceholderType
&& x.getLhsType().equals(x.getBasePair().getLhsType()))
|| (x.getBasePair().getRhsType() instanceof PlaceholderType
&& x.getLhsType().equals(x.getBasePair().getRhsType())
*/
))).filter(x -> //Sicherstellen, dass bei a = ty a auch wirklich die gesuchte Typvariable ist
x.getLhsType().equals(x.getBasePair().getLhsType()) ||
x.getLhsType().equals(x.getBasePair().getRhsType())
).findFirst();
if (optAPair.isPresent()) {//basepair ist entweder a <. Ty oder ty <. a
UnifyPair aPair = optAPair.get();
//writeLog("optOrigPair: " + optOrigPair + " " + "aPair: " + aPair+ " " + "aPair.basePair(): " + aPair.getBasePair());
writeLog("variance: " + new Integer(variance).toString() + "sameEqSet:" + sameEqSet);
if (!checkA(aPair, sameEqSet, elems, result)) {
a = null;
noShortendElements++;
continue;
}
}
}
/* PL 2019-03-11 Ende eingefuegt Vergleich mit anderen Paaren ggf. loeschen */
if(parallel && (variance == 1) && noOfThread <= MaxNoOfThreads) { if(parallel && (variance == 1) && noOfThread <= MaxNoOfThreads) {
Set<TypeUnify2Task> forks = new HashSet<>(); Set<TypeUnify2Task> forks = new HashSet<>();
Set<UnifyPair> newEqOrig = new HashSet<>(eq); Set<UnifyPair> newEqOrig = new HashSet<>(eq);
@@ -932,7 +804,7 @@ 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, cons); TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, rekTiefe, urm);
//forks.add(forkOrig); //forks.add(forkOrig);
forkOrig.fork(); forkOrig.fork();
/* FORK ENDE */ /* FORK ENDE */
@@ -946,11 +818,40 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
synchronized (this) { nextSetasList.remove(nSaL); synchronized (this) { nextSetasList.remove(nSaL);
writeLog("1 RM" + nSaL.toString()); writeLog("1 RM" + nSaL.toString());
} }
/* PL 2019-03-13 Anfang eingefuegt Vergleich mit anderen Paaren ggf. loeschen */
Optional<UnifyPair> optAPair = nSaL.stream().filter(x -> (
//x.getBasePair() != null && ist gegeben wenn variance != 2
//x.getBasePair().getPairOp().equals(PairOperator.SMALLERDOT) &&
(x.getPairOp().equals(PairOperator.EQUALSDOT)
/*
(x.getBasePair().getLhsType() instanceof PlaceholderType
&& x.getLhsType().equals(x.getBasePair().getLhsType()))
|| (x.getBasePair().getRhsType() instanceof PlaceholderType
&& x.getLhsType().equals(x.getBasePair().getRhsType())
*/
))).filter(x -> //Sicherstellen, dass bei a = ty a auch wirklich die gesuchte Typvariable ist
x.getLhsType().equals(x.getBasePair().getLhsType()) ||
x.getLhsType().equals(x.getBasePair().getRhsType())
).findFirst();
if (optAPair.isPresent()) {//basepair ist entweder a <. Ty oder ty <. a
UnifyPair aPair = optAPair.get();
//writeLog("optOrigPair: " + optOrigPair + " " + "aPair: " + aPair+ " " + "aPair.basePair(): " + aPair.getBasePair());
writeLog("variance: " + new Integer(variance).toString() + "sameEqSet:" + sameEqSet);
if (!sameEqSet.isEmpty() && !checkA(aPair, sameEqSet, elems, result)) {
nSaL = null;
noShortendElements++;
continue;
}
}
/* PL 2019-03-13 Ende eingefuegt Vergleich mit anderen Paaren ggf. loeschen */
Set<UnifyPair> newEq = new HashSet<>(eq); Set<UnifyPair> newEq = new HashSet<>(eq);
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, cons); TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, rekTiefe, urm);
forks.add(fork); forks.add(fork);
fork.fork(); fork.fork();
} }
@@ -958,7 +859,11 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
/* FORK ANFANG */ /* FORK ANFANG */
synchronized (this) { synchronized (this) {
noOfThread--;
writeLog("wait "+ forkOrig.thNo);
res = forkOrig.join(); res = forkOrig.join();
forkOrig.writeLog("final Orig 1");
forkOrig.closeLogFile();
//Set<Set<UnifyPair>> fork_res = forkOrig.join(); //Set<Set<UnifyPair>> fork_res = forkOrig.join();
writeLog("JoinOrig " + new Integer(forkOrig.thNo).toString()); writeLog("JoinOrig " + new Integer(forkOrig.thNo).toString());
//noOfThread--; an das Ende von compute verschoben //noOfThread--; an das Ende von compute verschoben
@@ -966,6 +871,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
}; };
/* FORK ENDE */ /* FORK ENDE */
forks.forEach(x -> writeLog("wait: " + x.thNo));
for(TypeUnify2Task fork : forks) { for(TypeUnify2Task fork : forks) {
synchronized (this) { synchronized (this) {
Set<Set<UnifyPair>> fork_res = fork.join(); Set<Set<UnifyPair>> fork_res = fork.join();
@@ -977,8 +883,11 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
if (!isUndefinedPairSetSet(fork_res)) { if (!isUndefinedPairSetSet(fork_res)) {
aParDef.add(fork.getNextSetElement()); aParDef.add(fork.getNextSetElement());
} }
fork.writeLog("final 1");
fork.closeLogFile();
}; };
} }
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<>();
@@ -988,7 +897,7 @@ 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, cons); TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, rekTiefe, urm);
//forks.add(forkOrig); //forks.add(forkOrig);
forkOrig.fork(); forkOrig.fork();
/* FORK ENDE */ /* FORK ENDE */
@@ -1002,11 +911,40 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
synchronized (this) { nextSetasList.remove(nSaL); synchronized (this) { nextSetasList.remove(nSaL);
writeLog("-1 RM" + nSaL.toString()); writeLog("-1 RM" + nSaL.toString());
} }
/* PL 2019-03-13 Anfang eingefuegt Vergleich mit anderen Paaren ggf. loeschen */
Optional<UnifyPair> optAPair = nSaL.stream().filter(x -> (
//x.getBasePair() != null && ist gegeben wenn variance != 2
//x.getBasePair().getPairOp().equals(PairOperator.SMALLERDOT) &&
(x.getPairOp().equals(PairOperator.EQUALSDOT)
/*
(x.getBasePair().getLhsType() instanceof PlaceholderType
&& x.getLhsType().equals(x.getBasePair().getLhsType()))
|| (x.getBasePair().getRhsType() instanceof PlaceholderType
&& x.getLhsType().equals(x.getBasePair().getRhsType())
*/
))).filter(x -> //Sicherstellen, dass bei a = ty a auch wirklich die gesuchte Typvariable ist
x.getLhsType().equals(x.getBasePair().getLhsType()) ||
x.getLhsType().equals(x.getBasePair().getRhsType())
).findFirst();
if (optAPair.isPresent()) {//basepair ist entweder a <. Ty oder ty <. a
UnifyPair aPair = optAPair.get();
//writeLog("optOrigPair: " + optOrigPair + " " + "aPair: " + aPair+ " " + "aPair.basePair(): " + aPair.getBasePair());
writeLog("variance: " + new Integer(variance).toString() + "sameEqSet:" + sameEqSet);
if (!sameEqSet.isEmpty() && !checkA(aPair, sameEqSet, elems, result)) {
nSaL = null;
noShortendElements++;
continue;
}
}
/* PL 2019-03-13 Ende eingefuegt Vergleich mit anderen Paaren ggf. loeschen */
Set<UnifyPair> newEq = new HashSet<>(eq); Set<UnifyPair> newEq = new HashSet<>(eq);
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, cons); TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, rekTiefe, urm);
forks.add(fork); forks.add(fork);
fork.fork(); fork.fork();
} }
@@ -1014,7 +952,11 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
/* FORK ANFANG */ /* FORK ANFANG */
synchronized (this) { synchronized (this) {
noOfThread--;
writeLog("wait "+ forkOrig.thNo);
res = forkOrig.join(); res = forkOrig.join();
forkOrig.writeLog("final Orig -1");
forkOrig.closeLogFile();
//Set<Set<UnifyPair>> fork_res = forkOrig.join(); //Set<Set<UnifyPair>> fork_res = forkOrig.join();
writeLog("JoinOrig " + new Integer(forkOrig.thNo).toString()); writeLog("JoinOrig " + new Integer(forkOrig.thNo).toString());
//noOfThread--; an das Ende von compute verschoben //noOfThread--; an das Ende von compute verschoben
@@ -1022,6 +964,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
}; };
/* FORK ENDE */ /* FORK ENDE */
forks.forEach(x -> writeLog("wait: " + x.thNo));
for(TypeUnify2Task fork : forks) { for(TypeUnify2Task fork : forks) {
synchronized (this) { synchronized (this) {
Set<Set<UnifyPair>> fork_res = fork.join(); Set<Set<UnifyPair>> fork_res = fork.join();
@@ -1033,19 +976,22 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
if (!isUndefinedPairSetSet(fork_res)) { if (!isUndefinedPairSetSet(fork_res)) {
aParDef.add(fork.getNextSetElement()); aParDef.add(fork.getNextSetElement());
} }
fork.writeLog("final -1");
fork.closeLogFile();
}; };
} }
noOfThread++;
} else { } else {
if(parallel && (variance == 2) && noOfThread <= MaxNoOfThreads) { if(parallel && (variance == 2) && noOfThread <= MaxNoOfThreads) {
writeLog("var2einstieg"); writeLog("var2einstieg");
Set<TypeUnifyTask> forks = new HashSet<>(); Set<TypeUnify2Task> forks = new HashSet<>();
Set<UnifyPair> newEqOrig = new HashSet<>(eq); Set<UnifyPair> newEqOrig = new HashSet<>(eq);
Set<Set<UnifyPair>> newElemsOrig = new HashSet<>(elems); Set<Set<UnifyPair>> newElemsOrig = new HashSet<>(elems);
List<Set<Set<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints); List<Set<Set<UnifyPair>>> newOderConstraintsOrig = new ArrayList<>(oderConstraints);
newElemsOrig.add(a); newElemsOrig.add(a);
/* FORK ANFANG */ /* FORK ANFANG */
TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, rekTiefe, urm, cons); TypeUnify2Task forkOrig = new TypeUnify2Task(newElemsOrig, newEqOrig, newOderConstraintsOrig, a, fc, parallel, logFile, log, rekTiefe, urm);
//forks.add(forkOrig); //forks.add(forkOrig);
forkOrig.fork(); forkOrig.fork();
/* FORK ENDE */ /* FORK ENDE */
@@ -1061,7 +1007,7 @@ 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, cons); TypeUnify2Task fork = new TypeUnify2Task(newElems, newEq, newOderConstraints, nSaL, fc, parallel, logFile, log, rekTiefe, urm);
forks.add(fork); forks.add(fork);
fork.fork(); fork.fork();
} }
@@ -1069,26 +1015,33 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
/* FORK ANFANG */ /* FORK ANFANG */
synchronized (this) { synchronized (this) {
noOfThread--;
writeLog("wait "+ forkOrig.thNo);
res = forkOrig.join(); res = forkOrig.join();
forkOrig.writeLog("final Orig 2");
forkOrig.closeLogFile();
//Set<Set<UnifyPair>> fork_res = forkOrig.join(); //Set<Set<UnifyPair>> fork_res = forkOrig.join();
writeLog("JoinOrig " + new Integer(forkOrig.thNo).toString()); writeLog("JoinOrig " + new Integer(forkOrig.thNo).toString());
//noOfThread--; an das Ende von compute verschoben //noOfThread--; an das Ende von compute verschoben
//add_res.add(fork_res); //vermutlich falsch //add_res.add(fork_res); //vermutlich falsch
}; };
/* FORK ENDE */ /* FORK ENDE */
forks.forEach(x -> writeLog("wait: " + x.thNo));
for(TypeUnifyTask fork : forks) { for(TypeUnify2Task fork : forks) {
synchronized (this) { synchronized (this) {
Set<Set<UnifyPair>> fork_res = fork.join(); Set<Set<UnifyPair>> fork_res = fork.join();
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);
fork.writeLog("final 2");
fork.closeLogFile();
}; };
}} }
else { noOfThread++;
} 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
res = unify2(elems, eq, oderConstraints, fc, parallel, rekTiefe); res = unify2(elems, eq, oderConstraints, fc, parallel, rekTiefe, finalresult);
}}} }}}
if (!isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result)) { if (!isUndefinedPairSetSet(res) && isUndefinedPairSetSet(result)) {
//wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen //wenn korrektes Ergebnis gefunden alle Fehlerfaelle loeschen
@@ -1124,6 +1077,7 @@ 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());}); 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
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))
@@ -1170,10 +1124,14 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
writeLog("RES var=1 ADD:" + result.toString() + " " + res.toString()); writeLog("RES var=1 ADD:" + result.toString() + " " + res.toString());
result.addAll(res); result.addAll(res);
}}} }}}
}
catch (NullPointerException e) {
writeLog("NullPointerException: " + a_last.toString());
}
} }
else { else {
//alle Fehlerfaelle und alle korrekten Ergebnis jeweils adden //alle Fehlerfaelle und alle korrekten Ergebnis jeweils adden
writeLog("RES Fst:" + result.toString() + " " + res.toString()); writeLog("RES Fst: reuslt: " + result.toString() + " res: " + res.toString());
result.addAll(res); result.addAll(res);
} }
} }
@@ -1393,7 +1351,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
// .collect(Collectors.toCollection(ArrayList::new)); // .collect(Collectors.toCollection(ArrayList::new));
writeLog("res (undef): " + res.toString()); writeLog("res (undef): " + res.toString());
writeLog("abhSubst: " + abhSubst.toString()); writeLog("abhSubst: " + abhSubst.toString());
writeLog("a2: " + rekTiefe + " " + a.toString()); if (finalresult) writeLog("a2: " + rekTiefe + " " + a.toString());
writeLog("Durchschnitt: " + durchschnitt.toString()); writeLog("Durchschnitt: " + durchschnitt.toString());
writeLog("nextSet: " + nextSet.toString()); writeLog("nextSet: " + nextSet.toString());
writeLog("nextSetasList: " + nextSetasList.toString()); writeLog("nextSetasList: " + nextSetasList.toString());
@@ -1420,6 +1378,46 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
return result; return result;
} }
protected Boolean checkA (UnifyPair aPair, Set<UnifyPair> sameEqSet, Set<Set<UnifyPair>> elems, Set<Set<UnifyPair>> result) {
writeLog("checkA: " + aPair + "sameEqSet: " + sameEqSet);
for (UnifyPair sameEq : sameEqSet) {
if (sameEq.getLhsType() instanceof PlaceholderType) {
Set<UnifyPair> localEq = new HashSet<>();
Set<UnifyPair> unitedSubst = new HashSet<>(aPair.getAllSubstitutions());
unitedSubst.addAll(aPair.getAllBases());
unitedSubst.addAll(sameEq.getAllSubstitutions());
unitedSubst.addAll(sameEq.getAllBases());
localEq.add(new UnifyPair(aPair.getRhsType(), sameEq.getRhsType(), sameEq.getPairOp(), unitedSubst, null));
Set<Set<UnifyPair>> localRes = unify(localEq, new ArrayList<>(), fc, false, 0, false);
if (isUndefinedPairSetSet(localRes)) {
if (result.isEmpty() || isUndefinedPairSetSet(result)) {
result.addAll(localRes);
}
//writeLog("FALSE: " + aPair + "sameEqSet: " + sameEqSet);
return false;
}
}
else {
Set<UnifyPair> localEq = new HashSet<>();
Set<UnifyPair> unitedSubst = new HashSet<>(aPair.getAllSubstitutions());
unitedSubst.addAll(aPair.getAllBases());
unitedSubst.addAll(sameEq.getAllSubstitutions());
unitedSubst.addAll(sameEq.getAllBases());
localEq.add(new UnifyPair(sameEq.getLhsType(), aPair.getRhsType(), sameEq.getPairOp(), unitedSubst, null));
Set<Set<UnifyPair>> localRes = unify(localEq, new ArrayList<>(), fc, false, 0, false);
if (isUndefinedPairSetSet(localRes)) {
if (result.isEmpty() || isUndefinedPairSetSet(result)) {
result.addAll(localRes);
}
//writeLog("FALSE: " + aPair + "sameEqSet: " + sameEqSet);
return false;
}
}
}
//writeLog("TRUE: " + aPair + "sameEqSet: " + sameEqSet);
return true;
}
protected boolean couldBecorrect(Set<Pair<Set<UnifyPair>, UnifyPair>> reducedUndefResSubstGroundedBasePair, Set<UnifyPair> nextElem) { protected boolean couldBecorrect(Set<Pair<Set<UnifyPair>, UnifyPair>> reducedUndefResSubstGroundedBasePair, Set<UnifyPair> nextElem) {
return reducedUndefResSubstGroundedBasePair.stream() return reducedUndefResSubstGroundedBasePair.stream()
.map(pair -> { .map(pair -> {
@@ -1752,7 +1750,11 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
Bei allen die Abhaengigkeit der Elemente aus eq2sAsList als evtl. als Substitution Bei allen die Abhaengigkeit der Elemente aus eq2sAsList als evtl. als Substitution
hinzufuegen hinzufuegen
*/ */
Set<UnifyPair> consideredElements = new HashSet<>();
for(UnifyPair pair : eq2sAsList) { for(UnifyPair pair : eq2sAsList) {
if (consideredElements.contains(pair)) {
continue;
}
PairOperator pairOp = pair.getPairOp(); PairOperator pairOp = pair.getPairOp();
UnifyType lhsType = pair.getLhsType(); UnifyType lhsType = pair.getLhsType();
UnifyType rhsType = pair.getRhsType(); UnifyType rhsType = pair.getRhsType();
@@ -1776,7 +1778,70 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
remElem.add(new UnifyPair(pair.getLhsType(), new SuperType(pair.getRhsType()), PairOperator.EQUALSDOT)); remElem.add(new UnifyPair(pair.getLhsType(), new SuperType(pair.getRhsType()), PairOperator.EQUALSDOT));
x1.remove(remElem); x1.remove(remElem);
} }
/* ZU LOESCHEN ANFANG
//System.out.println(x1); //System.out.println(x1);
Set<UnifyPair> sameEqSet = eq2sAsList.stream()
.filter(x -> ((x.getLhsType().equals(lhsType) || x.getRhsType().equals(lhsType)) && !x.equals(pair)))
.collect(Collectors.toCollection(HashSet::new));
consideredElements.addAll(sameEqSet);
Set<Set<UnifyPair>> x2 = x1;
Set<Set<UnifyPair>> x1Res = new HashSet<>();
writeLog("pair:\n" + pair.toString());
writeLog("x1 Start:\n" + x1.toString());
writeLog("sameEqSet:\n" + sameEqSet.toString());
for (UnifyPair sameEq : sameEqSet) {
writeLog("x1 Original:\n" + x1.toString());
if (sameEq.getLhsType() instanceof PlaceholderType) {
x1 = x1.stream().filter(y -> {
UnifyPair type = y.stream().filter(z -> z.getLhsType().equals(lhsType)).findFirst().get();
Set<UnifyPair> localEq = new HashSet<>();
Set<UnifyPair> unitedSubst = new HashSet<>(type.getSubstitution());
unitedSubst.addAll(sameEq.getSubstitution());
localEq.add(new UnifyPair(type.getRhsType(), sameEq.getRhsType(), sameEq.getPairOp(), unitedSubst, null));
Set<Set<UnifyPair>> localRes = unify(localEq, new ArrayList<>(), fc, false, 0, false);
Boolean localCorr = !isUndefinedPairSetSet(localRes);
if (!localCorr) {
collectErr.addAll(localRes);
}
else {
localRes.forEach(z -> z.addAll(y));
x1Res.addAll(localRes);
}
return localCorr;
}
).collect(Collectors.toCollection(HashSet::new));
}
else {
x1 = x1.stream().filter(y -> {
UnifyPair type = y.stream().filter(z -> z.getLhsType().equals(lhsType)).findFirst().get();
Set<UnifyPair> localEq = new HashSet<>();
Set<UnifyPair> unitedSubst = new HashSet<>(type.getSubstitution());
unitedSubst.addAll(sameEq.getSubstitution());
localEq.add(new UnifyPair(sameEq.getLhsType(), type.getRhsType(), sameEq.getPairOp(), unitedSubst, null));
Set<Set<UnifyPair>> localRes = unify(localEq, new ArrayList<>(), fc, false, 0, false);
Boolean localCorr = !isUndefinedPairSetSet(localRes);
if (!localCorr) {
collectErr.addAll(localRes);
}
else {
localRes.forEach(z -> z.addAll(y));
x1Res.addAll(localRes);
}
return localCorr;
}
).collect(Collectors.toCollection(HashSet::new));
}
writeLog("x1 nach Loeschung von " + sameEq.toString()+" :\n" + x1.toString());
}
Set<Set<UnifyPair>> x1ResPrime;
if (sameEqSet.isEmpty()) {
x1ResPrime = x1;
}
else {
x1ResPrime = x1Res;
}
result.get(0).add(x1ResPrime);
ZU LOESCHEN ENDE */
result.get(0).add(x1); result.get(0).add(x1);
if (x1.isEmpty()) { if (x1.isEmpty()) {
undefined.add(pair); //Theta ist nicht im FC => Abbruch undefined.add(pair); //Theta ist nicht im FC => Abbruch

@@ -1,13 +1,31 @@
package de.dhbwstuttgart.typeinference.unify; package de.dhbwstuttgart.typeinference.unify;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import de.dhbwstuttgart.syntaxtree.factory.UnifyTypeFactory;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
import de.dhbwstuttgart.typeinference.result.ResultSet; import de.dhbwstuttgart.typeinference.result.ResultSet;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
public class UnifyResultModel { public class UnifyResultModel {
ConstraintSet<de.dhbwstuttgart.typeinference.constraints.Pair> cons;
IFiniteClosure fc;
public UnifyResultModel(ConstraintSet<de.dhbwstuttgart.typeinference.constraints.Pair> cons,
IFiniteClosure fc) {
this.cons = cons;
this.fc = fc;
}
private List<UnifyResultListener> listeners = new ArrayList<>(); private List<UnifyResultListener> listeners = new ArrayList<>();
public void addUnifyResultListener(UnifyResultListener listenerToAdd) { public void addUnifyResultListener(UnifyResultListener listenerToAdd) {
@@ -18,7 +36,20 @@ public class UnifyResultModel {
listeners.remove(listenerToRemove); listeners.remove(listenerToRemove);
} }
public void notify(List<ResultSet> newResult) { public void notify(Set<Set<UnifyPair>> eqPrimePrimeSet) {
Set<Set<UnifyPair>> eqPrimePrimeSetRet = eqPrimePrimeSet.stream().map(x -> {
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
if (y.getPairOp() == PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT);
return y; //alle Paare a <.? b erden durch a =. b ersetzt
}).collect(Collectors.toCollection(HashSet::new)));
if (res.isPresent()) {//wenn subst ein Erg liefert wurde was veraendert
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), fc);
}
else return x; //wenn nichts veraendert wurde wird x zurueckgegeben
}).collect(Collectors.toCollection(HashSet::new));
List<ResultSet> newResult = eqPrimePrimeSetRet.stream().map(unifyPairs ->
new ResultSet(UnifyTypeFactory.convert(unifyPairs, de.dhbwstuttgart.typeinference.constraints.Pair.generateTPHMap(cons))))
.collect(Collectors.toList());
UnifyResultEvent evt = new UnifyResultEvent(newResult); UnifyResultEvent evt = new UnifyResultEvent(newResult);
for (UnifyResultListener listener : listeners) { for (UnifyResultListener listener : listeners) {

@@ -1,5 +1,6 @@
package de.dhbwstuttgart.typeinference.unify.interfaces; package de.dhbwstuttgart.typeinference.unify.interfaces;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
@@ -85,6 +86,13 @@ public interface IRuleSet {
public Optional<UnifyPair> adaptExt(UnifyPair pair, IFiniteClosure fc); public Optional<UnifyPair> adaptExt(UnifyPair pair, IFiniteClosure fc);
public Optional<UnifyPair> adaptSup(UnifyPair pair, IFiniteClosure fc); public Optional<UnifyPair> adaptSup(UnifyPair pair, IFiniteClosure fc);
/**
* Applies the subst-Rule to a set of pairs (usually Eq').
* @param pairs The set of pairs where the subst rule should apply.
* @return An optional of the modified set, if there were any substitutions. An empty optional if there were no substitutions.
*/
public Optional<Set<UnifyPair>> subst(Set<UnifyPair> pairs, List<Set<Set<UnifyPair>>> oderConstraints);
/** /**
* Applies the subst-Rule to a set of pairs (usually Eq'). * Applies the subst-Rule to a set of pairs (usually Eq').
* @param pairs The set of pairs where the subst rule should apply. * @param pairs The set of pairs where the subst rule should apply.

@@ -2,6 +2,7 @@ package de.dhbwstuttgart.typeinference.unify.model;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
@@ -12,6 +13,7 @@ import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.BiFunction; import java.util.function.BiFunction;
import java.util.function.BinaryOperator; import java.util.function.BinaryOperator;
import java.util.function.Predicate;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import com.google.common.collect.Ordering; import com.google.common.collect.Ordering;
@@ -32,7 +34,7 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
public class FiniteClosure //extends Ordering<UnifyType> //entfernt PL 2018-12-11 public class FiniteClosure //extends Ordering<UnifyType> //entfernt PL 2018-12-11
implements IFiniteClosure { implements IFiniteClosure {
FileWriter logFile; Writer logFile;
static Boolean log = false; static Boolean log = false;
public void setLogTrue() { public void setLogTrue() {
log = true; log = true;
@@ -66,7 +68,7 @@ implements IFiniteClosure {
/** /**
* Creates a new instance using the inheritance tree defined in the pairs. * Creates a new instance using the inheritance tree defined in the pairs.
*/ */
public FiniteClosure(Set<UnifyPair> pairs, FileWriter logFile) { public FiniteClosure(Set<UnifyPair> pairs, Writer logFile) {
this.logFile = logFile; this.logFile = logFile;
this.pairs = new HashSet<>(pairs); this.pairs = new HashSet<>(pairs);
inheritanceGraph = new HashMap<UnifyType, Node<UnifyType>>(); inheritanceGraph = new HashMap<UnifyType, Node<UnifyType>>();
@@ -656,11 +658,16 @@ implements IFiniteClosure {
if (left.getName().equals("Matrix") || right.getName().equals("Matrix")) if (left.getName().equals("Matrix") || right.getName().equals("Matrix"))
System.out.println(""); System.out.println("");
/* /*
pairop = PairOperator.SMALLERDOTWC;
List<UnifyType> al = new ArrayList<>(); List<UnifyType> al = new ArrayList<>();
PlaceholderType xx =new PlaceholderType("xx"); PlaceholderType xx =new PlaceholderType("xx");
al.add(xx); al.add(xx);
left = new ExtendsType(new ReferenceType("Vector", new TypeParams(al))); left = new ExtendsType(new ReferenceType("Vector", new TypeParams(al)));
right = new ReferenceType("Vector", new TypeParams(new ArrayList<>(al)));
List<UnifyType> alr = new ArrayList<>();
UnifyType exx = new ExtendsType(xx);
alr.add(exx);
right = new ExtendsType(new ReferenceType("Vector", new TypeParams(alr)));
*/ */
/* /*
List<UnifyType> al = new ArrayList<>(); List<UnifyType> al = new ArrayList<>();
@@ -711,8 +718,13 @@ implements IFiniteClosure {
} }
catch (IOException e) { catch (IOException e) {
System.err.println("no LogFile");}} System.err.println("no LogFile");}}
//Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok. //Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok.
long smallerLen = smallerRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)).count(); Predicate<UnifyPair> delFun = x -> !((x.getLhsType() instanceof PlaceholderType ||
x.getRhsType() instanceof PlaceholderType)
&& !((x.getLhsType() instanceof WildcardType) && //? extends/super a <.? a
((WildcardType)x.getLhsType()).getWildcardedType().equals(x.getRhsType()))
);
long smallerLen = smallerRes.stream().filter(delFun).count();
if (smallerLen == 0) return -1; if (smallerLen == 0) return -1;
else { else {
up = new UnifyPair(right, left, pairop); up = new UnifyPair(right, left, pairop);
@@ -728,7 +740,7 @@ implements IFiniteClosure {
catch (IOException e) { catch (IOException e) {
System.err.println("no LogFile");}} System.err.println("no LogFile");}}
//Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok. //Gleichungen der Form a <./=. Theta oder Theta <./=. a oder a <./=. b sind ok.
long greaterLen = greaterRes.stream().filter(x -> !(x.getLhsType() instanceof PlaceholderType || x.getRhsType() instanceof PlaceholderType)).count(); long greaterLen = greaterRes.stream().filter(delFun).count();
if (greaterLen == 0) return 1; if (greaterLen == 0) return 1;
else return 0; else return 0;
} }

@@ -22,7 +22,7 @@ public class FunNType extends UnifyType {
* Creates a FunN-Type with the specified TypeParameters. * Creates a FunN-Type with the specified TypeParameters.
*/ */
protected FunNType(TypeParams p) { protected FunNType(TypeParams p) {
super("Fun"+(p.size()-1), p); super("Fun"+(p.size()-1)+"$$", p);
} }
/** /**

@@ -1,9 +1,11 @@
package de.dhbwstuttgart.typeinference.unify.model; package de.dhbwstuttgart.typeinference.unify.model;
import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.HashSet; import java.util.HashSet;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.Set; import java.util.Set;
import java.util.function.BinaryOperator; import java.util.function.BinaryOperator;
@@ -30,14 +32,25 @@ public class OrderingUnifyPair extends Ordering<Set<UnifyPair>> {
* in dem compare(Theta, Theta') aufgerufen wird. * in dem compare(Theta, Theta') aufgerufen wird.
*/ */
public int compareEq (UnifyPair left, UnifyPair right) { public int compareEq (UnifyPair left, UnifyPair right) {
try {
//if (left.getRhsType() instanceof WildcardType || right.getRhsType() instanceof WildcardType) {//PL 2019-01-12 ausgetauscht //if (left.getRhsType() instanceof WildcardType || right.getRhsType() instanceof WildcardType) {//PL 2019-01-12 ausgetauscht
if (((PlaceholderType)left.getLhsType()).isInnerType() && ((PlaceholderType)right.getLhsType()).isInnerType()) { if (((PlaceholderType)left.getLhsType()).isInnerType() && ((PlaceholderType)right.getLhsType()).isInnerType()) {
return fc.compare(left.getRhsType(), right.getRhsType(), PairOperator.SMALLERDOTWC); return fc.compare(left.getRhsType(), right.getRhsType(), PairOperator.SMALLERDOTWC);
} }
else { else {
return fc.compare(left.getRhsType(), right.getRhsType(), PairOperator.SMALLERDOT); return fc.compare(left.getRhsType(), right.getRhsType(), PairOperator.SMALLERDOT);
}}
catch (ClassCastException e) {
try {
((FiniteClosure)fc).logFile.write("ClassCastException: " + left.toString() +"\n\n");
((FiniteClosure)fc).logFile.flush();
}
catch (IOException ie) {
}
return -99;
} }
} }
/* /*
public int compareEq (UnifyPair left, UnifyPair right) { public int compareEq (UnifyPair left, UnifyPair right) {
if (left == null || right == null) if (left == null || right == null)
@@ -115,6 +128,43 @@ public class OrderingUnifyPair extends Ordering<Set<UnifyPair>> {
* @see com.google.common.collect.Ordering#compare(java.lang.Object, java.lang.Object) * @see com.google.common.collect.Ordering#compare(java.lang.Object, java.lang.Object)
*/ */
public int compare (Set<UnifyPair> left, Set<UnifyPair> right) { public int compare (Set<UnifyPair> left, Set<UnifyPair> right) {
/*
//pairop = PairOperator.SMALLERDOTWC;
List<UnifyType> al = new ArrayList<>();
PlaceholderType xx = PlaceholderType.freshPlaceholder();
al.add(xx);
UnifyType t1 = new ExtendsType(new ReferenceType("Vector", new TypeParams(al)));
//PlaceholderType yy =new PlaceholderType("yy");
List<UnifyType> alr = new ArrayList<>();
UnifyType exx = new ExtendsType(xx);
alr.add(exx);
UnifyType t2 = new ExtendsType(new ReferenceType("Vector", new TypeParams(alr)));
PlaceholderType a = PlaceholderType.freshPlaceholder();
a.setInnerType(true);
UnifyPair p1 = new UnifyPair(a, t1, PairOperator.SMALLERDOTWC);
PlaceholderType b = PlaceholderType.freshPlaceholder();
b.setInnerType(true);
UnifyPair p2 = new UnifyPair(b, t2, PairOperator.SMALLERDOTWC);
List<UnifyType> al3 = new ArrayList<>();
al3.add(a);
List<UnifyType> al4 = new ArrayList<>();
al4.add(b);
UnifyPair p3 = new UnifyPair(new PlaceholderType("c"), new ReferenceType("Vector", new TypeParams(al3)), PairOperator.EQUALSDOT);
UnifyPair p4 = new UnifyPair(new PlaceholderType("c"), new ReferenceType("Vector", new TypeParams(al4)), PairOperator.EQUALSDOT);
right = new HashSet<>();
right.add(p1);
right.add(p3);
left = new HashSet<>();
left.add(p2);
left.add(p4);
*/
if ((left.size() == 1) && right.size() == 1) { if ((left.size() == 1) && right.size() == 1) {
if (left.iterator().next().getLhsType().getName().equals("AFS")) { if (left.iterator().next().getLhsType().getName().equals("AFS")) {
System.out.println(""); System.out.println("");
@@ -198,9 +248,9 @@ public class OrderingUnifyPair extends Ordering<Set<UnifyPair>> {
//Set<PlaceholderType> varsleft = lefteq.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new)); //Set<PlaceholderType> varsleft = lefteq.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new));
//Set<PlaceholderType> varsright = righteq.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new)); //Set<PlaceholderType> varsright = righteq.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new));
//filtern des Paares a = Theta, das durch a <. Thata' generiert wurde (nur im Fall 1 relevant) andere Substitutioen werden rausgefiltert //filtern des Paares a = Theta, das durch a <. Thata' generiert wurde (nur im Fall 1 relevant) andere Substitutioen werden rausgefiltert
lefteq.removeIf(x -> !(x.getLhsType().getName().equals(x.getBasePair().getLhsType().getName()) lefteq.removeIf(x -> (x.getBasePair()!=null) && !(x.getLhsType().getName().equals(x.getBasePair().getLhsType().getName())
||x.getLhsType().getName().equals(x.getBasePair().getRhsType().getName())));//removeIf(x -> !varsright.contains(x.getLhsType())); ||x.getLhsType().getName().equals(x.getBasePair().getRhsType().getName())));//removeIf(x -> !varsright.contains(x.getLhsType()));
righteq.removeIf(x -> !(x.getLhsType().getName().equals(x.getBasePair().getLhsType().getName()) righteq.removeIf(x -> (x.getBasePair()!=null) && !(x.getLhsType().getName().equals(x.getBasePair().getLhsType().getName())
||x.getLhsType().getName().equals(x.getBasePair().getRhsType().getName())));//.removeIf(x -> !varsleft.contains(x.getLhsType())); ||x.getLhsType().getName().equals(x.getBasePair().getRhsType().getName())));//.removeIf(x -> !varsleft.contains(x.getLhsType()));
UnifyPair lseq = lefteq.iterator().next(); UnifyPair lseq = lefteq.iterator().next();
UnifyPair rseq = righteq.iterator().next(); UnifyPair rseq = righteq.iterator().next();

@@ -11,28 +11,45 @@ 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
Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded) { Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.smArg(this, fBounded); return fc.smArg(this, fBounded);

@@ -177,6 +177,20 @@ public class UnifyPair {
} }
} }
/**
* wenn in einem Paar bestehend aus 2 Typvariablen eine nicht wildcardtable ist,
* so beide auf nicht wildcardtable setzen
*/
public void disableCondWildcards() {
if (lhs instanceof PlaceholderType && rhs instanceof PlaceholderType
&& (!((PlaceholderType)lhs).isWildcardable() || !((PlaceholderType)rhs).isWildcardable()))
{
((PlaceholderType)lhs).disableWildcardtable();
((PlaceholderType)rhs).disableWildcardtable();
}
}
public Boolean wrongWildcard() { public Boolean wrongWildcard() {
return lhs.wrongWildcard() || rhs.wrongWildcard(); return lhs.wrongWildcard() || rhs.wrongWildcard();
} }
@@ -219,10 +233,12 @@ public class UnifyPair {
public String toString() { public String toString() {
String ret = ""; String ret = "";
if (lhs instanceof PlaceholderType) { if (lhs instanceof PlaceholderType) {
ret = new Integer(((PlaceholderType)lhs).getVariance()).toString() + " " + ((PlaceholderType)lhs).isInnerType(); ret = new Integer(((PlaceholderType)lhs).getVariance()).toString() + " " + ((PlaceholderType)lhs).isInnerType()
+ " " + ((PlaceholderType)lhs).isWildcardable();
} }
if (rhs instanceof PlaceholderType) { if (rhs instanceof PlaceholderType) {
ret = ret + ", " + new Integer(((PlaceholderType)rhs).getVariance()).toString() + " " + ((PlaceholderType)rhs).isInnerType(); ret = ret + ", " + new Integer(((PlaceholderType)rhs).getVariance()).toString() + " " + ((PlaceholderType)rhs).isInnerType()
+ " " + ((PlaceholderType)rhs).isWildcardable();
} }
return "(" + lhs + " " + pairOp + " " + rhs + ", " + ret + ")"; //+ ", [" + getfBounded().toString()+ "])"; return "(" + lhs + " " + pairOp + " " + rhs + ", " + ret + ")"; //+ ", [" + getfBounded().toString()+ "])";
} }

@@ -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();
}
}

@@ -32,11 +32,11 @@ public class FieldTphConsMethTest {
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("FieldTphConsMeth"); classToTest = loader.loadClass("FieldTphConsMeth");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
} }
@Test @Test
public void test() throws Exception { public void test() throws Exception {
instanceOfClass = classToTest.getConstructor(Object.class).newInstance("C");
Field a = classToTest.getDeclaredField("a"); Field a = classToTest.getDeclaredField("a");
a.setAccessible(true); a.setAccessible(true);
@@ -44,6 +44,7 @@ public class FieldTphConsMethTest {
Object result = m.invoke(instanceOfClass, 42); Object result = m.invoke(instanceOfClass, 42);
assertEquals(42,result); assertEquals(42,result);
assertEquals("C", a.get(instanceOfClass));
} }
} }

@@ -0,0 +1,66 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.Field;
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 FieldTphMMethTest {
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;
private static Object instanceOfClass2;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/FieldTphMMeth.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("FieldTphMMeth");
instanceOfClass = classToTest.getConstructor(Object.class,Object.class,Boolean.class).newInstance("C",42,true);
instanceOfClass2 = classToTest.getConstructor(Object.class,Object.class,Boolean.class).newInstance("C",42,false);
}
@Test
public void testM() throws Exception {
Method m = classToTest.getDeclaredMethod("m", Object.class,Object.class,Boolean.class);
Object result = m.invoke(instanceOfClass, "C",42,false);
assertEquals(42,result);
}
@Test
public void testWithTrue() throws Exception {
Field a = classToTest.getDeclaredField("a");
a.setAccessible(true);
assertEquals("C", a.get(instanceOfClass));
}
@Test
public void testWithFalse() throws Exception {
Field a = classToTest.getDeclaredField("a");
a.setAccessible(true);
assertEquals(42, a.get(instanceOfClass2));
}
}

@@ -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 InfTest {
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/Inf.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("Inf");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
}

@@ -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 KompTphTest {
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/KompTph.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("KompTph");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
}

@@ -4,6 +4,7 @@ import static org.junit.Assert.*;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.net.URL; import java.net.URL;
@@ -27,7 +28,7 @@ public class MatrixOpTest {
private static Object instanceOfClass_m3; private static Object instanceOfClass_m3;
@Test @Test
public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IOException, InstantiationException { public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IOException, InstantiationException, NoSuchFieldException {
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/MatrixOP.jav"; path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/MatrixOP.jav";
fileToTest = new File(path); fileToTest = new File(path);
compiler = new JavaTXCompiler(fileToTest); compiler = new JavaTXCompiler(fileToTest);
@@ -35,7 +36,7 @@ public class MatrixOpTest {
compiler.generateBytecode(pathToClassFile); compiler.generateBytecode(pathToClassFile);
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
classToTest = loader.loadClass("MatrixOP"); classToTest = loader.loadClass("MatrixOP");
/*
Vector<Vector<Integer>> vv = new Vector<Vector<Integer>>(); Vector<Vector<Integer>> vv = new Vector<Vector<Integer>>();
Vector<Integer> v1 = new Vector<Integer> (); Vector<Integer> v1 = new Vector<Integer> ();
v1.addElement(2); v1.addElement(2);
@@ -48,6 +49,7 @@ public class MatrixOpTest {
//m1.addElement(v2); //m1.addElement(v2);
vv.addElement(v1); vv.addElement(v1);
vv.addElement(v2); vv.addElement(v2);
instanceOfClass_m1 = classToTest.getDeclaredConstructor(Vector.class).newInstance(vv); //Matrix m1 = new Matrix(vv); instanceOfClass_m1 = classToTest.getDeclaredConstructor(Vector.class).newInstance(vv); //Matrix m1 = new Matrix(vv);
Vector<Vector<Integer>> vv1 = new Vector<Vector<Integer>>(); Vector<Vector<Integer>> vv1 = new Vector<Vector<Integer>>();
@@ -62,13 +64,23 @@ public class MatrixOpTest {
//m2.addElement(v4); //m2.addElement(v4);
vv1.addElement(v3); vv1.addElement(v3);
vv1.addElement(v4); vv1.addElement(v4);
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);
Field mul = classToTest.getField("mul");
mul.setAccessible(true);
Class<?> lambda = mul.get(instanceOfClass_m1).getClass();
Method apply = lambda.getMethod("apply", Object.class,Object.class);
// Damit man auf die Methode zugreifen kann
apply.setAccessible(true);
Object result = apply.invoke(mul.get(instanceOfClass_m1),instanceOfClass_m1, instanceOfClass_m2);
System.out.println(instanceOfClass_m1.toString() + " * " + instanceOfClass_m2.toString() + " = " + result.toString()); System.out.println(instanceOfClass_m1.toString() + " * " + instanceOfClass_m2.toString() + " = " + result.toString());
Vector<Vector<Integer>> res = new Vector<Vector<Integer>>(); Vector<Vector<Integer>> res = new Vector<Vector<Integer>>();
@@ -85,7 +97,7 @@ public class MatrixOpTest {
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);
*/
} }
} }

0
src/test/java/bytecode/MatrixTest.java Normal file → Executable file

@@ -12,7 +12,7 @@ import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler; import de.dhbwstuttgart.core.JavaTXCompiler;
public class FieldTph { public class TypedIDTest {
private static String path; private static String path;
private static File fileToTest; private static File fileToTest;
@@ -22,22 +22,17 @@ public class FieldTph {
private static String pathToClassFile; private static String pathToClassFile;
private static Object instanceOfClass; private static Object instanceOfClass;
@BeforeClass
public static void setUpBeforeClass() throws Exception { @Test
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/FieldTph.jav"; public void test() throws Exception {
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/TypedID.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("FieldTph"); classToTest = loader.loadClass("TypedID");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance(); instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
} }
@Test
public void test() {
Field[] fields = classToTest.getFields();
assertEquals(1, fields.length);
}
} }

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

@@ -0,0 +1,64 @@
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);
}
}

@@ -1,5 +0,0 @@
# Ignore everything in this directory
*
# Except this file
!.gitignore

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

@@ -1,22 +1,25 @@
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;
Faculty() { Faculty() {
fact = (x) -> { fact = (x) -> {
if (x == 1) { if (x == 1) {
return 1; return 1;
} }
else { else {
return x * (fact.apply(x-1)); return x * (fact.apply(x-1));
} }
}; };
} }
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 +48,4 @@ public class Faculty {
// return x * m(x-1); // return x * m(x-1);
// } // }
// } // }
}

@@ -0,0 +1,27 @@
import java.lang.Boolean;
public class FieldTphMMeth {
a;
public FieldTphMMeth(c,d,e) {
a = m(c,d,e);
}
m(b,d,e) {
if(e) {
return m3(b);
} else{
return m3(d);
}
}
m2(b) {
a = m3(b);
}
m3(b){
return b;
}
}

@@ -3,4 +3,5 @@ public class Id {
id(b){ id(b){
return b; return b;
} }
} }

@@ -0,0 +1,19 @@
public class Inf {
m(x,y,a){
var z;
var v;
var w;
var b;
y=x;
z=x;
v=y;
w=y;
y=a;
b=a;
}
}
// v w
// \ /
// z y b
// \ / \ /
// x a

@@ -0,0 +1,13 @@
public class KompTph {
public m(a, b, c) {
var d = a;
var e = a;
a = b;
c = b;
m2(a,c);
}
public m2(a,b){
m(a,a,b);
}
}

@@ -1,10 +1,10 @@
import java.util.Vector; import java.util.Vector;
import java.lang.Integer; import java.lang.Integer;
//import java.lang.Float; import java.lang.Float;
//import java.lang.Byte; //import java.lang.Byte;
//import java.lang.Boolean; //import java.lang.Boolean;
public class Matrix extends Vector<Vector<Integer>> { public class Matrix extends Vector<Vector<Integer>> {
Matrix () { Matrix () {
} }
@@ -16,10 +16,10 @@ public class Matrix extends Vector<Vector<Integer>> {
// Boolean a = this.add(vv.elementAt(i)); // Boolean a = this.add(vv.elementAt(i));
this.add(vv.elementAt(i)); this.add(vv.elementAt(i));
i=i+1; i=i+1;
} }
} }
mul(m) { mul(java.util.Vector<? extends Vector<? extends java.lang.Integer>> m) {
var ret = new Matrix(); var ret = new Matrix();
var i = 0; var i = 0;
while(i < size()) { while(i < size()) {

@@ -1,9 +1,9 @@
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>> {
MatrixOP () { MatrixOP () {
} }
@@ -18,10 +18,10 @@ public class MatrixOP extends Vector<Vector<Integer>> {
} }
} }
mul = (m1, m2) -> { public Fun2$$<java.util.Vector<? extends java.util.Vector<? extends java.lang.Integer>>, java.util.Vector<? extends java.util.Vector<? extends java.lang.Integer>>, MatrixOP> mul = (m1, m2) -> {
var ret = new MatrixOP(); var ret = new MatrixOP();
var i = 0; var i = 0;
while(i < size()) { while(i < m1.size()) {
var v1 = m1.elementAt(i); var v1 = m1.elementAt(i);
var v2 = new Vector<Integer>(); var v2 = new Vector<Integer>();
var j = 0; var j = 0;

@@ -10,8 +10,6 @@ public class OL {
} }
public class OLMain { public class OLMain {
main(x) { main(x) {

@@ -14,10 +14,10 @@ sort(in){
return merge(sort(firstHalf), sort(secondHalf)); return merge(sort(firstHalf), sort(secondHalf));
} }
*/ */
/*
void sort(ArrayList<String> a){ void sort(a){
a = merge(a,a); a = merge(a,a);
} }
*/
} }

@@ -0,0 +1,12 @@
public class TypedID/*<L extends K,K> */ {
lam = x-> x;
id(b){
return b;
}
m(){
return lam;
}
}

@@ -1,13 +1,14 @@
import java.lang.Integer; import java.lang.Integer;
class Faculty { class Faculty {
//fact;
Integer mul(Integer x, Integer y) {
Integer mul(Integer x, Integer y) {
return x; return x;
} }
m () { m () {
var fact = (Integer x) -> { var fact = (Integer x) -> {
return mul(x, fact.apply(x)); return mul(x, fact.apply(x));
}; };
return fact; return fact;

@@ -1,13 +1,8 @@
class MathStruc <A> {
class mathStruc<A> { A model;
innerOp = o -> ms -> new MathStruc<A>(o.apply(this.model, ms.model));
mathStruc(A a) { } MathStruc(A m) { model=m; }
}
A model(){ A a; return a; }
methode(){
var innerOp = o -> ms ->
new mathStruc<A>(o.apply(this.model(),ms.model()));
return innerOp;
}
}