2
0

Compare commits

..

33 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
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
40 changed files with 1224 additions and 1419 deletions

Binary file not shown.

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

@@ -1,929 +0,0 @@
package de.dhbwstuttgart.typeinference.unify;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.RecursiveTask;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet;
import de.dhbwstuttgart.typeinference.unify.interfaces.ISetOperations;
import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
import de.dhbwstuttgart.typeinference.unify.model.SuperType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import de.dhbwstuttgart.typeinference.unify.model.Unifier;
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
import de.dhbwstuttgart.typeinference.unify.model.OrderingUnifyPair;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import com.google.common.collect.Ordering;
/**
* Implementation of the type unification algorithm
* @author Florian Steurer
*/
public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
private static final long serialVersionUID = 1L;
private static int i = 0;
private boolean printtag = false;
public static final String rootDirectory = System.getProperty("user.dir")+"/test/logFiles/";
FileWriter logFile;
/**
* The implementation of setOps that will be used during the unification
*/
protected ISetOperations setOps = new GuavaSetOperations();
/**
* The implementation of the standard unify that will be used during the unification
*/
protected IUnify stdUnify = new MartelliMontanariUnify();
/**
* The implementation of the rules that will be used during the unification.
*/
protected IRuleSet rules;
protected Set<UnifyPair> eq;
protected IFiniteClosure fc;
protected Ordering<Set<UnifyPair>> oup;
protected boolean parallel;
public TypeUnifyTask() {
rules = new RuleSet();
}
public TypeUnifyTask(Set<UnifyPair> eq, IFiniteClosure fc, boolean parallel, FileWriter logFile) {
this.eq = eq;
this.fc = fc;
this.oup = new OrderingUnifyPair(fc);
this.parallel = parallel;
this.logFile = logFile;
rules = new RuleSet(logFile);
}
@Override
protected Set<Set<UnifyPair>> compute() {
return unify(eq, fc, parallel);
}
/**
* Computes all principal type unifiers for a set of constraints.
* @param eq The set of constraints
* @param fc The finite closure
* @return The set of all principal type unifiers
*/
protected Set<Set<UnifyPair>> unify(Set<UnifyPair> eq, IFiniteClosure fc, boolean parallel) {
/*
* Step 1: Repeated application of reduce, adapt, erase, swap
*/
writeLog("Unifikation: " + eq.toString());
eq = eq.stream().map(x -> {x.setVariance((byte)-1); return x;}).collect(Collectors.toCollection(HashSet::new));
Set<UnifyPair> eq0 = applyTypeUnificationRules(eq, fc);
/*
* Step 2 and 3: Create a subset eq1s of pairs where both sides are TPH and eq2s of the other pairs
*/
Set<UnifyPair> eq1s = new HashSet<>();
Set<UnifyPair> eq2s = new HashSet<>();
splitEq(eq0, eq1s, eq2s);
/*
* Step 4: Create possible typings
*
* "Manche Autoren identifizieren die Paare (a, (b,c)) und ((a,b),c)
* mit dem geordneten Tripel (a,b,c), wodurch das kartesische Produkt auch assoziativ wird." - Wikipedia
*/
// There are up to 10 toplevel set. 8 of 10 are the result of the
// cartesian product of the sets created by pattern matching.
List<Set<Set<UnifyPair>>> topLevelSets = new ArrayList<>();
//System.out.println(eq2s);
if(eq1s.size() != 0) { // Do not add empty sets or the cartesian product will always be empty.
Set<Set<UnifyPair>> wrap = new HashSet<>();
wrap.add(eq1s);
topLevelSets.add(wrap); // Add Eq1'
}
// Add the set of [a =. Theta | (a=. Theta) in Eq2']
Set<UnifyPair> bufferSet = eq2s.stream()
.filter(x -> x.getPairOp() == PairOperator.EQUALSDOT && x.getLhsType() instanceof PlaceholderType)
.collect(Collectors.toSet());
if(bufferSet.size() != 0) { // Do not add empty sets or the cartesian product will always be empty.
Set<Set<UnifyPair>> wrap = new HashSet<>();
wrap.add(bufferSet);
topLevelSets.add(wrap);
eq2s.removeAll(bufferSet);
}
// Sets that originate from pair pattern matching
// Sets of the "second level"
Set<UnifyPair> undefinedPairs = new HashSet<>();
if (printtag) System.out.println("eq2s " + eq2s);
//writeLog("BufferSet: " + bufferSet.toString()+"\n");
Set<Set<Set<Set<UnifyPair>>>> secondLevelSets = calculatePairSets(eq2s, fc, undefinedPairs);
//PL 2017-09-20: Im calculatePairSets wird möglicherweise O .< java.lang.Integer
//nicht ausgewertet Faculty Beispiel im 1. Schritt
//PL 2017-10-03 geloest, muesste noch mit FCs mit kleineren
//Typen getestet werden.
if (printtag) System.out.println("secondLevelSets:" +secondLevelSets);
// If pairs occured that did not match one of the cartesian product cases,
// those pairs are contradictory and the unification is impossible.
if(!undefinedPairs.isEmpty()) {
writeLog("UndefinedPairs; " + undefinedPairs);
Set<Set<UnifyPair>> error = new HashSet<>();
error.add(undefinedPairs);
return error;
}
/* Up to here, no cartesian products are calculated.
* filters for pairs and sets can be applied here */
// Alternative: Sub cartesian products of the second level (pattern matched) sets
// "the big (x)"
/* for(Set<Set<Set<UnifyPair>>> secondLevelSet : secondLevelSets) {
//System.out.println("secondLevelSet "+secondLevelSet.size());
List<Set<Set<UnifyPair>>> secondLevelSetList = new ArrayList<>(secondLevelSet);
Set<List<Set<UnifyPair>>> cartResult = setOps.cartesianProduct(secondLevelSetList);
//System.out.println("CardResult: "+cartResult.size());
// Flatten and add to top level sets
Set<Set<UnifyPair>> flat = new HashSet<>();
int j = 0;
for(List<Set<UnifyPair>> s : cartResult) {
j++;
//System.out.println("s from CardResult: "+cartResult.size() + " " + j);
Set<UnifyPair> flat1 = new HashSet<>();
for(Set<UnifyPair> s1 : s)
flat1.addAll(s1);
flat.add(flat1);
}
//topLevelSets.add(flat);
}
*/
//Alternative KEIN KARTESISCHES PRODUKT der secondlevel Ebene bilden
for(Set<Set<Set<UnifyPair>>> secondLevelSet : secondLevelSets) {
for (Set<Set<UnifyPair>> secondlevelelem : secondLevelSet) {
topLevelSets.add(secondlevelelem);
}
}
//System.out.println(topLevelSets);
//System.out.println();
//Aufruf von computeCartesianRecursive ANFANG
return computeCartesianRecursive(new HashSet<>(), new ArrayList<>(topLevelSets), eq, fc, parallel);
}
Set<Set<UnifyPair>> unify2(Set<Set<UnifyPair>> setToFlatten, Set<UnifyPair> eq, IFiniteClosure fc, boolean parallel) {
//Aufruf von computeCartesianRecursive ENDE
//keine Ahnung woher das kommt
//Set<Set<UnifyPair>> setToFlatten = topLevelSets.stream().map(x -> x.iterator().next()).collect(Collectors.toCollection(HashSet::new));
//Muss auskommentiert werden, wenn computeCartesianRecursive ANFANG
// Cartesian product over all (up to 10) top level sets
//Set<Set<Set<UnifyPair>>> eqPrimeSet = setOps.cartesianProduct(topLevelSets)
// .stream().map(x -> new HashSet<>(x))
// .collect(Collectors.toCollection(HashSet::new));
//Muss auskommentiert werden, wenn computeCartesianRecursive ENDE
Set<Set<UnifyPair>> eqPrimePrimeSet = new HashSet<>();
Set<TypeUnifyTask> forks = new HashSet<>();
//Muss auskommentiert werden, wenn computeCartesianRecursive ANFANG
//for(Set<Set<UnifyPair>> setToFlatten : eqPrimeSet) {
// Flatten the cartesian product
//Muss auskommentiert werden, wenn computeCartesianRecursive ENDE
Set<UnifyPair> eqPrime = new HashSet<>();
setToFlatten.stream().forEach(x -> eqPrime.addAll(x));
/*
* Step 5: Substitution
*/
//System.out.println("vor Subst: " + eqPrime);
Optional<Set<UnifyPair>> eqPrimePrime = rules.subst(eqPrime);
/*
* Step 6 a) Restart (fork) for pairs where subst was applied
*/
if(parallel) {
if (eqPrime.equals(eq)) //PL 2017-09-29 auskommentiert und durch
//(!eqPrimePrime.isPresent()) //PL 2071-09-29 dies ersetzt
//Begruendung: Wenn in der Substitution keine Veraenderung
//(!eqPrimePrime.isPresent()) erfolgt ist, ist das Ergebnis erzielt.
eqPrimePrimeSet.add(eqPrime);
else if(eqPrimePrime.isPresent()) {
//System.out.println("nextStep: " + eqPrimePrime.get());
TypeUnifyTask fork = new TypeUnifyTask(eqPrimePrime.get(), fc, true, logFile);
forks.add(fork);
fork.fork();
}
else {
//System.out.println("nextStep: " + eqPrime);
TypeUnifyTask fork = new TypeUnifyTask(eqPrime, fc, true, logFile);
forks.add(fork);
fork.fork();
}
}
else { // sequentiell (Step 6b is included)
if (printtag) System.out.println("nextStep: " + eqPrimePrime);
if (eqPrime.equals(eq)) { //PL 2017-09-29 auskommentiert und durch
//(!eqPrimePrime.isPresent()) //PL 2071-09-29 dies ersetzt
//Begruendung: Wenn in der Substitution keine Veraenderung
//(!eqPrimePrime.isPresent()) erfolgt ist, ist das Ergebnis erzielt.
try {
if (isSolvedForm(eqPrime)) {
logFile.write(eqPrime.toString()+"\n");
logFile.flush();
}
}
catch (IOException e) { }
eqPrimePrimeSet.add(eqPrime);
}
else if(eqPrimePrime.isPresent()) {
Set<Set<UnifyPair>> unifyres = unify(eqPrimePrime.get(), fc, false);
eqPrimePrimeSet.addAll(unifyres);
}
else {
Set<Set<UnifyPair>> unifyres = unify(eqPrime, fc, false);
eqPrimePrimeSet.addAll(unifyres);
}
}
//Muss auskommentiert werden, wenn computeCartesianRecursive ANFANG
//}
//Muss auskommentiert werden, wenn computeCartesianRecursive ENDE
/*
* Step 6 b) Build the union over everything.
*/
if(parallel)
for(TypeUnifyTask fork : forks)
eqPrimePrimeSet.addAll(fork.join());
/*
* Step 7: Filter empty sets;
*/
eqPrimePrimeSet = eqPrimePrimeSet.stream().filter(x -> isSolvedForm(x)).collect(Collectors.toCollection(HashSet::new));
if (!eqPrimePrimeSet.isEmpty())
writeLog("Result " + eqPrimePrimeSet.toString());
return eqPrimePrimeSet;
}
Set<Set<UnifyPair>> computeCartesianRecursive(Set<Set<UnifyPair>> fstElems, ArrayList<Set<Set<UnifyPair>>> topLevelSets, Set<UnifyPair> eq, IFiniteClosure fc, boolean parallel) {
ArrayList<Set<Set<UnifyPair>>> remainingSets = new ArrayList<>(topLevelSets);
Set<Set<UnifyPair>> nextSet = remainingSets.remove(0);
ArrayList<Set<UnifyPair>> nextSetasList = new ArrayList<>(nextSet);
Set<Set<UnifyPair>> result = new HashSet<>();
int i = 0;
byte variance = nextSetasList.iterator().next().iterator().next().getVariance();
Set<UnifyPair> a_next = null;
if (nextSetasList.iterator().next().iterator().next().getLhsType().getName().equals("D"))
System.out.print("");
if (nextSetasList.size()>1) {
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();
}
while (nextSetasList.size() != 0) {
Set<UnifyPair> a = a_next;
//writeLog("nextSet: " + nextSetasList.toString()+ "\n");
nextSetasList.remove(a);
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);
if (remainingSets.isEmpty()) {
result.addAll(unify2(elems, eq, fc, parallel));
System.out.println("");
}
else {
result.addAll(computeCartesianRecursive(elems, remainingSets, eq, fc, parallel));
}
if (!result.isEmpty()) {
if (variance == 1) {
if (a.iterator().next().getLhsType().getName().equals("WL"))
System.out.print("");
if (a.equals(a_next) ||
(oup.compare(a, a_next) == 1)) {
System.out.print("");
break;
}
else {
System.out.print("");
}
}
else { if (variance == -1) {
if (a.iterator().next().getLhsType().getName().equals("A"))
System.out.print("");
if (a.equals(a_next) || (oup.compare(a, a_next) == -1)) {
System.out.print("");
break;
}
else {
System.out.print("");
}
}
else if (variance == 0) {
break;
}
}
}
}
return result;
}
protected boolean isUndefinedPairSet(Set<Set<UnifyPair>> s) {
boolean res = true;
if (s.size() ==1) {
s.iterator().next().stream().forEach(x -> { res = res && x.isUndefinedPair(); return; });
return res;
}
}
/**
* Checks whether a set of pairs is in solved form.
* @param eqPrimePrime The set of pair
* @return True if in solved form, false otherwise.
*/
protected boolean isSolvedForm(Set<UnifyPair> eqPrimePrime) {
for(UnifyPair pair : eqPrimePrime) {
UnifyType lhsType = pair.getLhsType();
UnifyType rhsType = pair.getRhsType();
if(!(lhsType instanceof PlaceholderType))
return false;
// If operator is not equals, both sides must be placeholders
if(pair.getPairOp() != PairOperator.EQUALSDOT && !(rhsType instanceof PlaceholderType))
return false;
}
return true;
}
/**
* Repeatedly applies type unification rules to a set of equations.
* This is step one of the unification algorithm.
* @return The set of pairs that results from repeated application of the inference rules.
*/
public Set<UnifyPair> applyTypeUnificationRules(Set<UnifyPair> eq, IFiniteClosure fc) {
/*
* Rule Application Strategy:
*
* 1. Swap all pairs and erase all erasable pairs
* 2. Apply all possible rules to a single pair, then move it to the result set.
* Iterating over pairs first, then iterating over rules prevents the application
* of rules to a "finished" pair over and over.
* 2.1 Apply all rules repeatedly except for erase rules. If
* the application of a rule creates new pairs, check immediately
* against the erase rules.
*/
LinkedHashSet<UnifyPair> targetSet = new LinkedHashSet<UnifyPair>();
LinkedList<UnifyPair> eqQueue = new LinkedList<>();
/*
* Swap all pairs and erase all erasable pairs
*/
eq.forEach(x -> swapAddOrErase(x, fc, eqQueue));
/*
* Apply rules until the queue is empty
*/
while(!eqQueue.isEmpty()) {
UnifyPair pair = eqQueue.pollFirst();
// ReduceUp, ReduceLow, ReduceUpLow
Optional<UnifyPair> opt = rules.reduceUpLow(pair);
opt = opt.isPresent() ? opt : rules.reduceLow(pair);
opt = opt.isPresent() ? opt : rules.reduceUp(pair);
opt = opt.isPresent() ? opt : rules.reduceWildcardLow(pair);
opt = opt.isPresent() ? opt : rules.reduceWildcardLowRight(pair);
opt = opt.isPresent() ? opt : rules.reduceWildcardUp(pair);
opt = opt.isPresent() ? opt : rules.reduceWildcardUpRight(pair);
//PL 2018-03-06 auskommentiert muesste falsch sein vgl. JAVA_BSP/Wildcard6.java
//opt = opt.isPresent() ? opt : rules.reduceWildcardLowUp(pair);
//opt = opt.isPresent() ? opt : rules.reduceWildcardUpLow(pair);
//opt = opt.isPresent() ? opt : rules.reduceWildcardLeft(pair);
// Reduce TPH
opt = opt.isPresent() ? opt : rules.reduceTph(pair);
// One of the rules has been applied
if(opt.isPresent()) {
swapAddOrErase(opt.get(), fc, eqQueue);
continue;
}
// Reduce1, Reduce2, ReduceExt, ReduceSup, ReduceEq
//try {
// logFile.write("PAIR1 " + pair + "\n");
// logFile.flush();
//}
//catch (IOException e) { }
Optional<Set<UnifyPair>> optSet = rules.reduce1(pair, fc);
optSet = optSet.isPresent() ? optSet : rules.reduce2(pair);
optSet = optSet.isPresent() ? optSet : rules.reduceExt(pair, fc);
optSet = optSet.isPresent() ? optSet : rules.reduceSup(pair, fc);
optSet = optSet.isPresent() ? optSet : rules.reduceEq(pair);
// ReduceTphExt, ReduceTphSup
optSet = optSet.isPresent() ? optSet : rules.reduceTphExt(pair);
optSet = optSet.isPresent() ? optSet : rules.reduceTphSup(pair);
// FunN Rules
optSet = optSet.isPresent() ? optSet : rules.reduceFunN(pair);
optSet = optSet.isPresent() ? optSet : rules.greaterFunN(pair);
optSet = optSet.isPresent() ? optSet : rules.smallerFunN(pair);
// One of the rules has been applied
if(optSet.isPresent()) {
optSet.get().forEach(x -> swapAddOrErase(x, fc, eqQueue));
continue;
}
// Adapt, AdaptExt, AdaptSup
//try {
// logFile.write("PAIR2 " + pair + "\n");
// logFile.flush();
//}
//catch (IOException e) { }
opt = rules.adapt(pair, fc);
opt = opt.isPresent() ? opt : rules.adaptExt(pair, fc);
opt = opt.isPresent() ? opt : rules.adaptSup(pair, fc);
// One of the rules has been applied
if(opt.isPresent()) {
swapAddOrErase(opt.get(), fc, eqQueue);
continue;
}
// None of the rules has been applied
targetSet.add(pair);
}
return targetSet;
}
/**
* Applies the rule swap to a pair if possible. Then adds the pair to the set if no erase rule applies.
* If an erase rule applies, the pair is not added (erased).
* @param pair The pair to swap and add or erase.
* @param collection The collection to which the pairs are added.
*/
protected void swapAddOrErase(UnifyPair pair, IFiniteClosure fc, Collection<UnifyPair> collection) {
Optional<UnifyPair> opt = rules.swap(pair);
UnifyPair pair2 = opt.isPresent() ? opt.get() : pair;
if(rules.erase1(pair2, fc) || rules.erase3(pair2) || rules.erase2(pair2, fc))
return;
collection.add(pair2);
}
/**
* Splits the equation eq into a set eq1s where both terms are type variables,
* and a set eq2s where one of both terms is not a type variable.
* @param eq Set of pairs to be splitted.
* @param eq1s Subset of eq where both terms are type variables.
* @param eq2s eq/eq1s.
*/
protected void splitEq(Set<UnifyPair> eq, Set<UnifyPair> eq1s, Set<UnifyPair> eq2s) {
for(UnifyPair pair : eq)
if(pair.getLhsType() instanceof PlaceholderType && pair.getRhsType() instanceof PlaceholderType)
eq1s.add(pair);
else
eq2s.add(pair);
}
/**
* Creates sets of pairs specified in the fourth step. Does not calculate cartesian products.
* @param undefined All pairs that did not match one of the 8 cases are added to this set.
* @return The set of the eight cases (without empty sets). Each case is a set, containing sets generated
* from the pairs that matched the case. Each generated set contains singleton sets or sets with few elements
* (as in case 1 where sigma is added to the innermost set).
*/
protected Set<Set<Set<Set<UnifyPair>>>> calculatePairSets(Set<UnifyPair> eq2s, IFiniteClosure fc, Set<UnifyPair> undefined) {
List<Set<Set<Set<UnifyPair>>>> result = new ArrayList<>(8);
// Init all 8 cases
for(int i = 0; i < 8; i++)
result.add(new HashSet<>());
Boolean first = true;
for(UnifyPair pair : eq2s) {
PairOperator pairOp = pair.getPairOp();
UnifyType lhsType = pair.getLhsType();
UnifyType rhsType = pair.getRhsType();
// Case 1: (a <. Theta')
if(pairOp == PairOperator.SMALLERDOT && lhsType instanceof PlaceholderType) {
//System.out.println(pair);
if (first) { //writeLog(pair.toString()+"\n");
Set<Set<UnifyPair>> x1 = unifyCase1((PlaceholderType) pair.getLhsType(), pair.getRhsType(), (byte)1, fc);
//System.out.println(x1);
result.get(0).add(x1);
}
else {
Set<UnifyPair> s1 = new HashSet<>();
s1.add(pair);
Set<Set<UnifyPair>> s2 = new HashSet<>();
s2.add(s1);
result.get(0).add(s2);
}
}
// Case 2: (a <.? ? ext Theta')
else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType && rhsType instanceof ExtendsType)
if (first) { //writeLog(pair.toString()+"\n");
result.get(1).add(unifyCase2((PlaceholderType) pair.getLhsType(), (ExtendsType) pair.getRhsType(), (byte)0, fc));
}
else {
Set<UnifyPair> s1 = new HashSet<>();
s1.add(pair);
Set<Set<UnifyPair>> s2 = new HashSet<>();
s2.add(s1);
result.get(1).add(s2);
}
// Case 3: (a <.? ? sup Theta')
else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType && rhsType instanceof SuperType)
if (first) { //writeLog(pair.toString()+"\n");
result.get(2).add(unifyCase3((PlaceholderType) lhsType, (SuperType) rhsType, (byte)0, fc));
}
else {
Set<UnifyPair> s1 = new HashSet<>();
s1.add(pair);
Set<Set<UnifyPair>> s2 = new HashSet<>();
s2.add(s1);
result.get(2).add(s2);
}
// Case 4 was replaced by an inference rule
// Case 4: (a <.? Theta')
//else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType)
// result.get(3).add(unifyCase4((PlaceholderType) lhsType, rhsType, fc));
// Case 5: (Theta <. a)
else if(pairOp == PairOperator.SMALLERDOT && rhsType instanceof PlaceholderType)
if (first) { //writeLog(pair.toString()+"\n");
if (rhsType.getName().equals("A"))
System.out.println();
result.get(4).add(unifyCase5(lhsType, (PlaceholderType) rhsType, (byte)-1, fc));
}
else {
Set<UnifyPair> s1 = new HashSet<>();
s1.add(pair);
Set<Set<UnifyPair>> s2 = new HashSet<>();
s2.add(s1);
result.get(4).add(s2);
}
// Case 6 was replaced by an inference rule.
// Case 6: (? ext Theta <.? a)
//else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof ExtendsType && rhsType instanceof PlaceholderType)
// result.get(5).add(unifyCase6((ExtendsType) lhsType, (PlaceholderType) rhsType, fc));
// Case 7 was replaced by an inference rule
// Case 7: (? sup Theta <.? a)
//else if(pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof SuperType && rhsType instanceof PlaceholderType)
// result.get(6).add(unifyCase7((SuperType) lhsType, (PlaceholderType) rhsType, fc));
// Case 8: (Theta <.? a)
else if(pairOp == PairOperator.SMALLERDOTWC && rhsType instanceof PlaceholderType)
if (first) { //writeLog(pair.toString()+"\n");
result.get(7).add(
unifyCase8(lhsType, (PlaceholderType) rhsType, (byte)0, fc));
}
else {
Set<UnifyPair> s1 = new HashSet<>();
s1.add(pair);
Set<Set<UnifyPair>> s2 = new HashSet<>();
s2.add(s1);
result.get(7).add(s2);
}
// Case unknown: If a pair fits no other case, then the type unification has failed.
// Through application of the rules, every pair should have one of the above forms.
// Pairs that do not have one of the aboves form are contradictory.
else {
// If a pair is not defined, the unificiation will fail, so the loop can be stopped here.
undefined.add(pair);
break;
}
first = false;
}
// Filter empty sets or sets that only contain an empty set.
return result.stream().map(x -> x.stream().filter(y -> y.size() > 0).collect(Collectors.toCollection(HashSet::new)))
.filter(x -> x.size() > 0).collect(Collectors.toCollection(HashSet::new));
}
/**
* Cartesian product Case 1: (a <. Theta')
*/
protected Set<Set<UnifyPair>> unifyCase1(PlaceholderType a, UnifyType thetaPrime, byte variance, IFiniteClosure fc) {
Set<Set<UnifyPair>> result = new HashSet<>();
boolean allGen = thetaPrime.getTypeParams().size() > 0;
for(UnifyType t : thetaPrime.getTypeParams())
if(!(t instanceof PlaceholderType) || !((PlaceholderType) t).isGenerated()) {
allGen = false;
break;
}
Set<UnifyType> cs = fc.getAllTypesByName(thetaPrime.getName());//cs= [java.util.Vector<NP>, java.util.Vector<java.util.Vector<java.lang.Integer>>, ????java.util.Vector<gen_hv>???]
//PL 18-02-06 entfernt, kommt durch unify wieder rein
//cs.add(thetaPrime);
//PL 18-02-06 entfernt
for(UnifyType c : cs) {
//PL 18-02-05 getChildren durch smaller ersetzt in getChildren werden die Varianlen nicht ersetzt.
Set<UnifyType> thetaQs = fc.smaller(c).stream().collect(Collectors.toCollection(HashSet::new));
//Set<UnifyType> thetaQs = fc.getChildren(c).stream().collect(Collectors.toCollection(HashSet::new));
//thetaQs.add(thetaPrime); //PL 18-02-05 wieder geloescht
//PL 2017-10-03: War auskommentiert habe ich wieder einkommentiert,
//da children offensichtlich ein echtes kleiner und kein kleinergleich ist
//PL 18-02-06: eingefuegt, thetaQs der Form V<V<...>> <. V'<V<...>> werden entfernt
thetaQs = thetaQs.stream().filter(ut -> ut.getTypeParams().arePlaceholders()).collect(Collectors.toCollection(HashSet::new));
//PL 18-02-06: eingefuegt
Set<UnifyType> thetaQPrimes = new HashSet<>();
TypeParams cParams = c.getTypeParams();
if(cParams.size() == 0)
thetaQPrimes.add(c);
else {
ArrayList<Set<UnifyType>> candidateParams = new ArrayList<>();
for(UnifyType param : cParams)
candidateParams.add(fc.grArg(param));
for(TypeParams tp : permuteParams(candidateParams))
thetaQPrimes.add(c.setTypeParams(tp));
}
for(UnifyType tqp : thetaQPrimes) {
//System.out.println(tqp.toString());
//i++;
//System.out.println(i);
//if (i == 62)
// System.out.println(tqp.toString());
Optional<Unifier> opt = stdUnify.unify(tqp, thetaPrime);
if (!opt.isPresent())
continue;
Unifier unifier = opt.get();
unifier.swapPlaceholderSubstitutions(thetaPrime.getTypeParams());
Set<UnifyPair> substitutionSet = new HashSet<>();
for (Entry<PlaceholderType, UnifyType> sigma : unifier)
substitutionSet.add(new UnifyPair(sigma.getKey(), sigma.getValue(), PairOperator.EQUALSDOT));
//List<UnifyType> freshTphs = new ArrayList<>(); PL 18-02-06 in die For-Schleife verschoben
for (UnifyType tq : thetaQs) {
Set<UnifyType> smaller = fc.smaller(unifier.apply(tq));
for(UnifyType theta : smaller) {
List<UnifyType> freshTphs = new ArrayList<>();
Set<UnifyPair> resultPrime = new HashSet<>();
for(int i = 0; !allGen && i < theta.getTypeParams().size(); i++) {
if(freshTphs.size()-1 < i)
freshTphs.add(PlaceholderType.freshPlaceholder());
resultPrime.add(new UnifyPair(freshTphs.get(i), theta.getTypeParams().get(i), PairOperator.SMALLERDOTWC));
}
if(allGen)
resultPrime.add(new UnifyPair(a, theta, PairOperator.EQUALSDOT));
else
resultPrime.add(new UnifyPair(a, theta.setTypeParams(new TypeParams(freshTphs.toArray(new UnifyType[0]))), PairOperator.EQUALSDOT));
resultPrime.addAll(substitutionSet);
//writeLog("Substitution: " + substitutionSet.toString());
resultPrime = resultPrime.stream().map(x -> { x.setVariance(variance); return x;}).collect(Collectors.toCollection(HashSet::new));
result.add(resultPrime);
//writeLog("Result: " + resultPrime.toString());
//writeLog("MAX: " + oup.max(resultPrime.iterator()).toString());
}
}
}
}
return result;
}
/**
* Cartesian Product Case 2: (a <.? ? ext Theta')
*/
private Set<Set<UnifyPair>> unifyCase2(PlaceholderType a, ExtendsType extThetaPrime, byte variance, IFiniteClosure fc) {
Set<Set<UnifyPair>> result = new HashSet<>();
UnifyType aPrime = PlaceholderType.freshPlaceholder();
UnifyType extAPrime = new ExtendsType(aPrime);
UnifyType thetaPrime = extThetaPrime.getExtendedType();
Set<UnifyPair> resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, thetaPrime, PairOperator.SMALLERDOT));
result.add(resultPrime);
resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, extAPrime, PairOperator.EQUALSDOT));
resultPrime.add(new UnifyPair(aPrime, thetaPrime, PairOperator.SMALLERDOT));
resultPrime = resultPrime.stream().map(x -> { x.setVariance(variance); return x;}).collect(Collectors.toCollection(HashSet::new));
result.add(resultPrime);
//writeLog("Result: " + resultPrime.toString());
return result;
}
/**
* Cartesian Product Case 3: (a <.? ? sup Theta')
*/
private Set<Set<UnifyPair>> unifyCase3(PlaceholderType a, SuperType subThetaPrime, byte variance, IFiniteClosure fc) {
Set<Set<UnifyPair>> result = new HashSet<>();
UnifyType aPrime = PlaceholderType.freshPlaceholder();
UnifyType supAPrime = new SuperType(aPrime);
UnifyType thetaPrime = subThetaPrime.getSuperedType();
Set<UnifyPair> resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(thetaPrime, a, PairOperator.SMALLERDOT));
result.add(resultPrime);
//writeLog(resultPrime.toString());
resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, supAPrime, PairOperator.EQUALSDOT));
resultPrime.add(new UnifyPair(thetaPrime, aPrime, PairOperator.SMALLERDOT));
resultPrime = resultPrime.stream().map(x -> { x.setVariance(variance); return x;}).collect(Collectors.toCollection(HashSet::new));
result.add(resultPrime);
//writeLog(resultPrime.toString());
return result;
}
/**
* Cartesian Product Case 5: (Theta <. a)
*/
private Set<Set<UnifyPair>> unifyCase5(UnifyType theta, PlaceholderType a, byte variance, IFiniteClosure fc) {
Set<Set<UnifyPair>> result = new HashSet<>();
boolean allGen = theta.getTypeParams().size() > 0;
for(UnifyType t : theta.getTypeParams())
if(!(t instanceof PlaceholderType) || !((PlaceholderType) t).isGenerated()) {
allGen = false;
break;
}
for(UnifyType thetaS : fc.greater(theta)) {
Set<UnifyPair> resultPrime = new HashSet<>();
UnifyType[] freshTphs = new UnifyType[thetaS.getTypeParams().size()];
for(int i = 0; !allGen && i < freshTphs.length; i++) {
freshTphs[i] = PlaceholderType.freshPlaceholder();
resultPrime.add(new UnifyPair(thetaS.getTypeParams().get(i), freshTphs[i], PairOperator.SMALLERDOTWC));
}
if(allGen)
resultPrime.add(new UnifyPair(a, thetaS, PairOperator.EQUALSDOT));
else
resultPrime.add(new UnifyPair(a, thetaS.setTypeParams(new TypeParams(freshTphs)), PairOperator.EQUALSDOT));
resultPrime = resultPrime.stream().map(x -> { x.setVariance(variance); return x;}).collect(Collectors.toCollection(HashSet::new));
result.add(resultPrime);
//writeLog(resultPrime.toString());
}
return result;
}
/**
* Cartesian Product Case 8: (Theta <.? a)
*/
private Set<Set<UnifyPair>> unifyCase8(UnifyType theta, PlaceholderType a, byte variance, IFiniteClosure fc) {
Set<Set<UnifyPair>> result = new HashSet<>();
//for(UnifyType thetaS : fc.grArg(theta)) {
Set<UnifyPair> resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, theta, PairOperator.EQUALSDOT));
result.add(resultPrime);
//writeLog(resultPrime.toString());
UnifyType freshTph = PlaceholderType.freshPlaceholder();
resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, new ExtendsType(freshTph), PairOperator.EQUALSDOT));
resultPrime.add(new UnifyPair(theta, freshTph, PairOperator.SMALLERDOT));
result.add(resultPrime);
//writeLog(resultPrime.toString());
resultPrime = new HashSet<>();
resultPrime.add(new UnifyPair(a, new SuperType(freshTph), PairOperator.EQUALSDOT));
resultPrime.add(new UnifyPair(freshTph, theta, PairOperator.SMALLERDOT));
resultPrime = resultPrime.stream().map(x -> { x.setVariance(variance); return x;}).collect(Collectors.toCollection(HashSet::new));
result.add(resultPrime);
//writeLog(resultPrime.toString());
//}
return result;
}
/**
* Takes a set of candidates for each position and computes all possible permutations.
* @param candidates The length of the list determines the number of type params. Each set
* contains the candidates for the corresponding position.
*/
protected Set<TypeParams> permuteParams(ArrayList<Set<UnifyType>> candidates) {
Set<TypeParams> result = new HashSet<>();
permuteParams(candidates, 0, result, new UnifyType[candidates.size()]);
return result;
}
/**
* Takes a set of candidates for each position and computes all possible permutations.
* @param candidates The length of the list determines the number of type params. Each set
* contains the candidates for the corresponding position.
* @param idx Idx for the current permutatiton.
* @param result Set of all permutations found so far
* @param current The permutation of type params that is currently explored
*/
private void permuteParams(ArrayList<Set<UnifyType>> candidates, int idx, Set<TypeParams> result, UnifyType[] current) {
if(candidates.size() == idx) {
result.add(new TypeParams(Arrays.copyOf(current, current.length)));
return;
}
Set<UnifyType> localCandidates = candidates.get(idx);
for(UnifyType t : localCandidates) {
current[idx] = t;
permuteParams(candidates, idx+1, result, current);
}
}
void writeLog(String str) {
try {
logFile.write(str+"\n");
logFile.flush();
}
catch (IOException e) { }
}
}

@@ -1,117 +0,0 @@
package de.dhbwstuttgart.typeinference.unify.model;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
/**
* A pair which contains two types and an operator, e.q. (Integer <. a).
* @author Florian Steurer
*/
public class UnifyPair {
/**
* The type on the left hand side of the pair.
*/
private final UnifyType lhs;
/**
* The type on the right hand side of the pair.
*/
private final UnifyType rhs;
/**
* The operator that determines the relation between the left and right hand side type.
*/
private PairOperator pairOp;
private byte variance = 0;
private boolean undefinedPair = false;
private final int hashCode;
/**
* Creates a new instance of the pair.
* @param lhs The type on the left hand side of the pair.
* @param rhs The type on the right hand side of the pair.
* @param op The operator that determines the relation between the left and right hand side type.
*/
public UnifyPair(UnifyType lhs, UnifyType rhs, PairOperator op) {
this.lhs = lhs;
this.rhs = rhs;
pairOp = op;
// Caching hashcode
hashCode = 17 + 31 * lhs.hashCode() + 31 * rhs.hashCode() + 31 * pairOp.hashCode();
}
/**
* Returns the type on the left hand side of the pair.
*/
public UnifyType getLhsType() {
return lhs;
}
/**
* Returns the type on the right hand side of the pair.
*/
public UnifyType getRhsType() {
return rhs;
}
/**
* Returns the operator that determines the relation between the left and right hand side type.
*/
public PairOperator getPairOp() {
return pairOp;
}
public byte getVariance() {
return variance;
}
public void setVariance(byte v) {
variance = v;
}
public boolean isUndefinedPair() {
return undefinedPair;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof UnifyPair))
return false;
if(obj.hashCode() != this.hashCode())
return false;
UnifyPair other = (UnifyPair) obj;
return other.getPairOp() == pairOp
&& other.getLhsType().equals(lhs)
&& other.getRhsType().equals(rhs);
}
@Override
public int hashCode() {
return hashCode;
}
@Override
public String toString() {
return "(" + lhs + " " + pairOp + " " + rhs + ")";
}
/*
public List<? extends PlaceholderType> getInvolvedPlaceholderTypes() {
ArrayList<PlaceholderType> ret = new ArrayList<>();
ret.addAll(lhs.getInvolvedPlaceholderTypes());
ret.addAll(rhs.getInvolvedPlaceholderTypes());
return ret;
}
*/
}

@@ -17,6 +17,7 @@ import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.Type;
import de.dhbwstuttgart.bytecode.Exception.BytecodeGeneratorError;
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
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.NormalMethod;
import de.dhbwstuttgart.bytecode.utilities.Simplify;
import de.dhbwstuttgart.bytecode.utilities.SimplifyResult;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.Literal;
@@ -44,11 +46,11 @@ import de.dhbwstuttgart.typeinference.result.ResultPair;
import de.dhbwstuttgart.typeinference.result.ResultSet;
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;
public static RefTypeOrTPHOrWildcardOrGeneric THISTYPE = null;
String className;
private boolean isInterface;
@@ -56,186 +58,222 @@ public class BytecodeGen implements ASTVisitor {
private ResultSet resultSet;
private SourceFile sf;
private String path;
private Optional<Constructor> fieldInitializations;
private int indexOfFirstParam = 0;
private String superClass;
private ArrayList<TypePlaceholder> tphsClass;
// stores parameter, local vars and the next index on the local variable table, which use for aload_i, astore_i,...
private ArrayList<String> tphsClass;
// 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<>();
// stores generics and their bounds of class
HashMap<String, String> genericsAndBounds = new HashMap<>();
private int constructorPos = 0;
private final TPHExtractor tphExtractor = new TPHExtractor();
private final ArrayList<GenericInsertPair> commonPairs = new ArrayList<>();
HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes = new HashMap<>();
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes = new HashMap<>();
byte[] bytecode;
HashMap<String,byte[]> classFiles;
ArrayList<String> methodNameAndParamsT = new ArrayList<>();
public BytecodeGen(HashMap<String,byte[]> classFiles, List<ResultSet> listOfResultSets,SourceFile sf ,String path) {
HashMap<String, byte[]> classFiles;
private final ArrayList<String> methodNameAndParamsT = new ArrayList<>();
private final ArrayList<String> fieldNameAndParamsT = new ArrayList<>();
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.listOfResultSets = listOfResultSets;
this.sf = sf;
this.path = path;
}
@Override
public void visit(SourceFile sourceFile) {
for(ClassOrInterface cl : sourceFile.getClasses()) {
for (ClassOrInterface cl : sourceFile.getClasses()) {
System.out.println("in Class: " + cl.getClassName().toString());
BytecodeGen classGen = new BytecodeGen(classFiles, listOfResultSets, sf, path);
cl.accept(classGen);
simplifyResultsList.add(classGen.getSimplifyResults());
classGen.writeClass(cl.getClassName().toString());
}
}
/**
* Associates the bytecode of the class that was build with the classWriter {@link #cw}
* with the class name in the map {@link #classFiles}
* Associates the bytecode of the class that was build with the classWriter
* {@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
*/
private void writeClass(String name) {
bytecode = cw.toByteArray();
classFiles.put(name, bytecode);
}
public HashMap<String,byte[]> getClassFiles() {
public HashMap<String, byte[]> getClassFiles() {
return classFiles;
}
@Override
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();
// resultSet = listOfResultSets.get(0);
boolean isConsWithNoParamsVisited = false;
boolean isVisited = false;
for(ResultSet rs : listOfResultSets) {
for (ResultSet rs : listOfResultSets) {
superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor());
resultSet = rs;
tphExtractor.setResultSet(resultSet);
// Nur einmal ausführen!!
if(!isVisited) {
if (!isVisited) {
classOrInterface.accept(tphExtractor);
getCommonTPHS(tphExtractor);
tphsClass = new ArrayList<>();
for(TypePlaceholder t : tphExtractor.allTPHS.keySet()) {
if(!tphExtractor.allTPHS.get(t))
for (String t : tphExtractor.allTPHS.keySet()) {
if (!tphExtractor.allTPHS.get(t))
tphsClass.add(t);
}
String sig = null;
/* if class has generics then creates signature
* Signature looks like:
* <E:Ljava/...>Superclass
/*
* if class has generics then creates signature Signature looks like:
* <E:Ljava/...>Superclass
*/
if(classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty() ||
classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<")
if (classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty()
|| classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<")
|| !tphsClass.isEmpty()) {
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraintsClass(tphExtractor,tphsClass);
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify
.simplifyConstraintsClass(tphExtractor, tphsClass);
ArrayList<TPHConstraint> consClass = new ArrayList<>();
for(TPHConstraint cons : constraints.keySet()) {
TypePlaceholder right = null;
for(TypePlaceholder tph : tphsClass) {
if(cons.getLeft().equals(tph.getName())) {
for (TPHConstraint cons : constraints.keySet()) {
String right = null;
boolean isToAdd = false;
for (String tph : tphsClass) {
if (cons.getLeft().equals(tph)) {
consClass.add(cons);
right = getTPH(cons.getRight());
try {
right = getTPH(cons.getRight());
isToAdd = true;
} catch (NoSuchElementException e) {
continue;
}
}
}
if(right != null) {
if (isToAdd) {
tphsClass.add(right);
removeFromMethod(right.getName());
removeFromMethod(right);
right = null;
isToAdd = false;
}
// if(right != null) {
// tphsClass.add(right);
// removeFromMethod(right);
// right = null;
// }
}
Signature signature = new Signature(classOrInterface, genericsAndBounds,commonPairs,tphsClass, consClass);
SimplifyResult sRes = new SimplifyResult(consClass, tphsClass, new HashMap<>());
simplifyResults.put(className, sRes);
Signature signature = new Signature(classOrInterface, genericsAndBounds, commonPairs, tphsClass,
consClass);
sig = signature.toString();
System.out.println("Signature: => " + sig);
}
cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString()
, sig, classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null);
cw.visit(Opcodes.V1_8, acc, classOrInterface.getClassName().toString(), sig,
classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()), null);
isVisited = true;
}
for(Field f : classOrInterface.getFieldDecl()) {
for (Field f : classOrInterface.getFieldDecl()) {
f.accept(this);
}
for(Constructor c : classOrInterface.getConstructors()) {
for (Constructor c : classOrInterface.getConstructors()) {
// if(!isConsWithNoParamsVisited) {
c.accept(this);
c.accept(this);
// }
// if(!c.getParameterList().iterator().hasNext())
// isConsWithNoParamsVisited = true;
}
for(Method m : classOrInterface.getMethods()) {
for (Method m : classOrInterface.getMethods()) {
m.accept(this);
}
}
}
private void removeFromMethod(String name) {
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
for (MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
ArrayList<String> toRemove = new ArrayList<>();
for(String tph : m.getTphs()) {
if(tph.equals(name)) {
for (String tph : m.getTphs()) {
if (tph.equals(name)) {
toRemove.add(tph);
}
}
if(!toRemove.isEmpty()) {
if (!toRemove.isEmpty()) {
m.getTphs().removeAll(toRemove);
return;
}
}
}
private TypePlaceholder getTPH(String name) {
for(TypePlaceholder tph: tphExtractor.allTPHS.keySet()) {
if(tph.getName().equals(name))
private String getTPH(String name) {
for (String tph : tphExtractor.allTPHS.keySet()) {
if (tph.equals(name))
return tph;
}
throw new NoSuchElementException("TPH "+name +" does not exist");
throw new NoSuchElementException("TPH " + name + " does not exist");
}
private void getCommonTPHS(TPHExtractor tphExtractor) {
// Gemeinsame TPHs
ArrayList<TypePlaceholder> cTPHs = new ArrayList<>();
ArrayList<String> cTPHs = new ArrayList<>();
// Alle TPHs der Felder speichern
for(TypePlaceholder tph : tphExtractor.allTPHS.keySet()) {
if(!tphExtractor.allTPHS.get(tph))
for (String tph : tphExtractor.allTPHS.keySet()) {
if (!tphExtractor.allTPHS.get(tph))
cTPHs.add(tph);
}
}
@@ -243,156 +281,179 @@ public class BytecodeGen implements ASTVisitor {
@Override
public void visit(Constructor field) {
System.out.println("ResultSet: ");
resultSet.results.forEach(a->{
resultSet.results.forEach(a -> {
System.out.println(a.getLeft().toString() + " = " + a.getRight().toString());
});
System.out.println("---------------");
// stores generics and their bounds of method
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
field.getParameterList().accept(this);
String methParamTypes = field.name+"%%";
String methParamTypes = field.name + "%%";
Iterator<FormalParameter> itr = field.getParameterList().iterator();
while(itr.hasNext()) {
while (itr.hasNext()) {
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())+";";
}
if(methodNameAndParamsT.contains(methParamTypes)) {
System.out.println("ignore - Method: "+field.name +" , paramsType: "+methParamTypes);
if (methodNameAndParamsT.contains(methParamTypes)) {
System.out.println("ignore - Method: " + field.name + " , paramsType: " + methParamTypes);
return;
}
methodNameAndParamsT.add(methParamTypes);
System.out.println("Method: "+field.name +" , paramsType: "+methParamTypes);
System.out.println("Method: " + field.name + " , paramsType: " + methParamTypes);
String desc = null;
boolean hasGen = false;
for(String paramName : methodParamsAndTypes.keySet()) {
for (String paramName : methodParamsAndTypes.keySet()) {
String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature());
System.out.println(typeOfParam);
if(genericsAndBounds.containsKey(typeOfParam) ||typeOfParam.contains("$")
|| typeOfParam.contains("<")) {
if (genericsAndBounds.containsKey(typeOfParam) || typeOfParam.contains("$") || typeOfParam.contains("<")) {
hasGen = true;
break;
}
}
String sig = null;
if(hasGen) {
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(field.name, tphExtractor,tphsClass);
Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,constraints);
if (hasGen) {
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(field.name, tphExtractor,
tphsClass);
Signature signature = new Signature(field, genericsAndBounds, methodParamsAndTypes, resultSet, constraints);
sig = signature.toString();
}
if(field.getParameterList().iterator().hasNext())
if (field.getParameterList().iterator().hasNext())
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));
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);
mv.visitCode();
mv.visitCode();
Block block = fieldInitializations.get().block;
constructorPos += 1;
BytecodeGenMethod gen = new BytecodeGenMethod(className,superClass,resultSet,field, mv,paramsAndLocals,cw,
genericsAndBoundsMethod,genericsAndBounds,isInterface,classFiles, sf,path, block, constructorPos);
if(!field.getParameterList().iterator().hasNext() && !(field.block.statements.get(field.block.statements.size()-1) instanceof ReturnVoid)) {
BytecodeGenMethod gen = new BytecodeGenMethod(className, superClass, resultSet, field, mv, paramsAndLocals, cw,
genericsAndBoundsMethod, genericsAndBounds, isInterface, classFiles, sf, path, block, constructorPos);
if (!field.getParameterList().iterator().hasNext()
&& !(field.block.statements.get(field.block.statements.size() - 1) instanceof ReturnVoid)) {
mv.visitInsn(Opcodes.RETURN);
}
mv.visitMaxs(0, 0);
mv.visitEnd();
}
@Override
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
String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
// String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
String methParamTypes = retType+method.name+"%%";
String methParamTypes = retType + method.name + "%%";
method.getParameterList().accept(this);
Iterator<FormalParameter> itr = method.getParameterList().iterator();
while(itr.hasNext()) {
while (itr.hasNext()) {
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())+";";
}
if(methodNameAndParamsT.contains(methParamTypes)) {
if (methodNameAndParamsT.contains(methParamTypes)) {
return;
}
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
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
String methDesc = null;
// Method getModifiers() ?
int acc = isInterface?Opcodes.ACC_ABSTRACT:method.modifier;
int acc = isInterface ? Opcodes.ACC_ABSTRACT : method.modifier;
System.out.println(acc);
/*Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist*/
boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.subSequence(0, 4).equals("TPH ") ||
resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature()).contains("<");
/*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()) {
/* Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist */
boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.contains("TPH ")
|| resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature())
.contains("<");
/*
* 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.substring(0, 4).equals("TPH ")||sigOfParam.contains("<")) {
if (genericsAndBounds.containsKey(typeOfParam) || typeOfParam.contains("TPH ")
|| sigOfParam.contains("<")) {
hasGenInParameterList = true;
break;
}
}
}
//TODO: Test if the return-type or any of the parameter is a parameterized type. (VP)
//then create the descriptor with the new syntax.
// TODO: Test if the return-type or any of the parameter is a parameterized
// type. (VP)
// then create the descriptor with the new syntax.
String sig = null;
/* method.getGenerics: <....> RT method(..)
* */
/*
* method.getGenerics: <....> RT method(..)
*/
boolean hasGen = method.getGenerics().iterator().hasNext() || hasGenInParameterList;
/* if method has generics or return type is TPH, create signature */
// 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());
tphExtractor.allCons.forEach(c->System.out.println(c.toString()));
tphExtractor.allCons.forEach(c -> System.out.println(c.toString()));
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);
Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet,constraints);
Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,
methodParamsAndTypes, resultSet, constraints);
sig = signature.toString();
}
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);
if (simplifyResults.containsKey(className)) {
simplifyResults.get(className).getMethodsConstraints().put(methParamTypes, constraints);
} else {
SimplifyResult sRes = new SimplifyResult(new ArrayList<>(), new ArrayList<>(), new HashMap<>());
sRes.getMethodsConstraints().put(methParamTypes, constraints);
simplifyResults.put(className, sRes);
}
}
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.visitEnd();
}
public HashMap<String, SimplifyResult> getSimplifyResults() {
return simplifyResults;
}
@Override
public void visit(ParameterList formalParameters) {
paramsAndLocals = new HashMap<>();
methodParamsAndTypes = new HashMap<>();
Iterator<FormalParameter> itr = formalParameters.iterator();
int i = 1;
while(itr.hasNext()) {
while (itr.hasNext()) {
FormalParameter fp = itr.next();
paramsAndLocals.put(fp.getName(), i);
methodParamsAndTypes.put(fp.getName(), resultSet.resolveType(fp.getType()).resolvedType);
@@ -400,39 +461,39 @@ public class BytecodeGen implements ASTVisitor {
i++;
}
}
@Override
public void visit(FormalParameter formalParameter) {
formalParameter.getType().accept(this);
}
@Override
public void visit(RefType refType) {
type = "L"+refType.toString()+";";
type = "L" + refType.toString() + ";";
}
@Override
public void visit(SuperWildcardType superWildcardType) {
// TODO Auto-generated method stub
}
@Override
public void visit(TypePlaceholder typePlaceholder) {
// TODO Auto-generated method stub
}
@Override
public void visit(ExtendsWildcardType extendsWildcardType) {
// TODO Auto-generated method stub
}
@Override
public void visit(GenericRefType genericRefType) {
// TODO Auto-generated method stub
}
// ??
@@ -440,41 +501,51 @@ public class BytecodeGen implements ASTVisitor {
public void visit(FieldVar fieldVar) {
System.out.println("In FieldVar ---");
// 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();
}
@Override
public void visit(Field field) {
System.out.println("In Field ---");
String des = "L";
if(resultSet.resolveType(field.getType()).resolvedType instanceof TypePlaceholder) {
if (resultSet.resolveType(field.getType()).resolvedType instanceof TypePlaceholder) {
des += Type.getInternalName(Object.class);
} else {
des += resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToDescriptor());
}
des +=";";
des += ";";
System.out.println(des);
String sig = resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToSignature());
System.out.println(sig);
if(sig.charAt(sig.length()-1) != (";").charAt(0)) {
sig +=";";
if (sig.charAt(sig.length() - 1) != (";").charAt(0)) {
sig += ";";
}
cw.visitField(field.modifier, field.getName(),
des, sig,
null);
String nameAndDesc = field.getName() + "%%" + des;
String nameAndSig = field.getName() + "%%" + sig;
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
public void visit(LambdaExpression lambdaExpression) {
// TODO Auto-generated method stub
}
@Override
public void visit(Assign assign) {
// TODO Auto-generated method stub
}
@Override
@@ -485,151 +556,151 @@ public class BytecodeGen implements ASTVisitor {
@Override
public void visit(Block block) {
// TODO Auto-generated method stub
}
@Override
public void visit(CastExpr castExpr) {
// TODO Auto-generated method stub
}
@Override
public void visit(EmptyStmt emptyStmt) {
// TODO Auto-generated method stub
}
@Override
public void visit(ForStmt forStmt) {
// TODO Auto-generated method stub
}
@Override
public void visit(IfStmt ifStmt) {
// TODO Auto-generated method stub
}
@Override
public void visit(InstanceOf instanceOf) {
// TODO Auto-generated method stub
}
@Override
public void visit(LocalVar localVar) {
// TODO Auto-generated method stub
}
@Override
public void visit(LocalVarDecl localVarDecl) {
// TODO Auto-generated method stub
}
@Override
public void visit(MethodCall methodCall) {
// TODO Auto-generated method stub
}
@Override
public void visit(NewClass methodCall) {
// TODO Auto-generated method stub
}
@Override
public void visit(NewArray newArray) {
// TODO Auto-generated method stub
}
@Override
public void visit(Return aReturn) {
// TODO Auto-generated method stub
}
@Override
public void visit(ReturnVoid aReturn) {
// TODO Auto-generated method stub
}
@Override
public void visit(StaticClassName staticClassName) {
// TODO Auto-generated method stub
}
@Override
public void visit(Super aSuper) {
// TODO Auto-generated method stub
}
@Override
public void visit(This aThis) {
// TODO Auto-generated method stub
}
@Override
public void visit(WhileStmt whileStmt) {
// TODO Auto-generated method stub
}
@Override
public void visit(DoStmt whileStmt) {
// TODO Auto-generated method stub
}
// ???
@Override
public void visit(Literal literal) {
// TODO Auto-generated method stub
}
@Override
public void visit(ArgumentList argumentList) {
// TODO Auto-generated method stub
}
@Override
public void visit(GenericTypeVar genericTypeVar) {
// TODO Auto-generated method stub
}
@Override
public void visit(GenericDeclarationList genericTypeVars) {
// TODO Auto-generated method stub
}
@Override
public void visit(AssignToField assignLeftSide) {
// TODO Auto-generated method stub
}
@Override
public void visit(AssignToLocal assignLeftSide) {
// TODO Auto-generated method stub
}
@Override
public void visit(SuperCall superCall) {
}
@Override
@@ -642,6 +713,5 @@ public class BytecodeGen implements ASTVisitor {
public void visit(UnaryExpr unaryExpr) {
throw new NotImplementedException();
}
}

@@ -33,12 +33,14 @@ 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.bytecode.utilities.KindOfLambda;
import de.dhbwstuttgart.bytecode.utilities.Lambda;
import de.dhbwstuttgart.bytecode.utilities.MethodCallHelper;
import de.dhbwstuttgart.bytecode.utilities.MethodFromMethodCall;
import de.dhbwstuttgart.bytecode.utilities.SamMethod;
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.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.ResultSet;
import javassist.NotFoundException;
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,
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.mv = mv;
@@ -149,6 +153,9 @@ public class BytecodeGenMethod implements StatementVisitor {
this.path = path;
this.lamCounter = lamCounter;
this.sf = sf;
this.genericsAndBoundsMethod = genericsAndBoundsMethod;
this.genericsAndBounds = genericsAndBounds;
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
int i = indexOfFirstParamLam;
@@ -644,7 +651,8 @@ public class BytecodeGenMethod implements StatementVisitor {
ArrayList<String> usedVars = kindOfLambda.getUsedVars();
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.visitEnd();
@@ -670,7 +678,7 @@ public class BytecodeGenMethod implements StatementVisitor {
}
methSig.visitReturnType().visitTypeVariable("R");
// ")"+lam.getReturn.getBounds
Signature sig = new Signature(lambdaExpression, numberOfParams);
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);
@@ -744,6 +752,13 @@ public class BytecodeGenMethod implements StatementVisitor {
statement = new IfStatement(ifStmt.expr, ifStmt.then_block, ifStmt.else_block);
isBinaryExp = statement.isExprBinary();
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;
}
@@ -751,105 +766,112 @@ public class BytecodeGenMethod implements StatementVisitor {
public void visit(InstanceOf instanceOf) {
}
@Override
public void visit(MethodCall methodCall) {
boolean parentBinary = isParentBinary;
System.out.println("In MethodCall = " + methodCall.name);
String receiverName = getResolvedType(methodCall.receiver.getType());
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();
// This will be used if the class is not standard class (not in API)
ClassLoader cLoader2;
java.lang.reflect.Method methodRefl = null;
String clazz = receiverName.replace("/", ".");
String methCallType = resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor());
String[] typesOfParams = getTypes(methodCall.arglist.getArguments());
try {
if(receiverName.contains("<")) {
if (receiverName.contains("<")) {
clazz = clazz.substring(0, receiverName.indexOf("<"));
}
java.lang.reflect.Method[] methods = cLoader.loadClass(clazz).getMethods();
System.out.println("Methods of " + receiverName + " ");
methodRefl = getMethod(methodCall.name,methodCall.arglist.getArguments().size(),methods);
} catch (Exception e) {
// try {
// cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)});
// java.lang.reflect.Method[] methods = cLoader2.loadClass(clazz).getMethods();
// System.out.println("Methods of " + receiverName + " ");
// for(int i = 0; i<methods.length; i++) {
// System.out.println(methods[i]);
// }
// methodRefl = getMethod(methodCall.name,methodCall.arglist.getArguments().size(),methCallType, typesOfParams,methods);
// }catch (Exception e2) {
String superClass = "";
// TODO: Test SubMatrix.jav
while(true) {
for(ClassOrInterface cl : sf.getClasses()) {
if(receiverName.equals(cl.getClassName().toString())) {
superClass = cl.getSuperClass().getName().toString();
methodRefl = getMethod(methodCall.name, methodCall.arglist.getArguments().size(), methods);
} catch (Exception e) {
String superClass = "";
while(true) {
try {
superClass = helper.getSuperClass(receiverName);
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;
}
} catch (NotInCurrentPackageException e2) {
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) {
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]);
if(methodRefl == null) {
toCreate = !receiverName.equals(className) && helper.isInCurrPkg(clazz);
if(toCreate) {
try {
mDesc = helper.getDesc(clazz);
} catch (NotInCurrentPackageException | NotFoundException e) {
e.printStackTrace();
}
} else if(!helper.isInCurrPkg(clazz)){
if(clazz.contains("$$")) {
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);
System.out.println("Methodcall type : " + resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor()));
String mDesc = "";
List<Boolean> argListMethCall = new LinkedList<>();
String receiverRefl="";
if(methodRefl == null) {
if(methodRefl == null && receiverName.equals(className)) {
MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(),
receiverName, genericsAndBoundsMethod, genericsAndBounds);
mDesc = method.accept(new DescriptorToString(resultSet));
methodCall.arglist.accept(this);
} else {
} else if(methodRefl != null) {
System.out.println(methodCall.name + " -> Refl != null");
receiverRefl = methodRefl.getAnnotatedReceiverType().getType().toString();
for(Parameter p:methodRefl.getParameters()) {
System.out.println(p.getName() + " und is Primitive = " + p.getType().isPrimitive());
@@ -863,9 +885,11 @@ public class BytecodeGenMethod implements StatementVisitor {
al.accept(argV);
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);
@@ -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) {
String[] types = new String[arguments.size()];
for(int i = 0; i<arguments.size(); ++i) {
@@ -1197,6 +1234,7 @@ public class BytecodeGenMethod implements StatementVisitor {
break;
case "java/lang/Boolean":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Boolean", "booleanValue", "()Z", false);
break;
case "java/lang/Byte":
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/Byte", "byteValue", "()B", false);
@@ -1234,10 +1272,16 @@ public class BytecodeGenMethod implements StatementVisitor {
visitBooleanLiteral((Boolean) value);
break;
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;
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;
case "java/lang/Integer":
// zweite Argument isLong
@@ -1248,10 +1292,16 @@ public class BytecodeGenMethod implements StatementVisitor {
visitIntegerLiteral(((Integer) value).intValue(), false);
break;
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;
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;
case "java/lang/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,7 +5,11 @@ package de.dhbwstuttgart.bytecode;
import java.util.ArrayList;
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.TPHConstraint;
@@ -13,13 +17,18 @@ import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
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.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.typeinference.result.GenericInsertPair;
import de.dhbwstuttgart.typeinference.result.ResultPair;
import de.dhbwstuttgart.typeinference.result.ResultSet;
/**
@@ -29,14 +38,14 @@ import de.dhbwstuttgart.typeinference.result.ResultSet;
public class TPHExtractor extends AbstractASTWalker {
// Alle TPHs der Felder werden iKopf der Klasse definiert
// alle TPHs der Klasse: (TPH, is in Method?)
final HashMap<TypePlaceholder, Boolean> allTPHS = new HashMap<>();
final HashMap<String, Boolean> allTPHS = new HashMap<>();
MethodAndTPH methodAndTph;
Boolean inMethod = false;
boolean inLocalOrParam = false;
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<>();
private ResultSet resultSet;
@@ -58,19 +67,80 @@ public class TPHExtractor extends AbstractASTWalker {
methodAndTph.getLocalTphs().add(resolvedTPH.getName());
}
allTPHS.put(resolvedTPH, inMethod);
resultSet.resolveType(tph).additionalGenerics.forEach(ag -> {
if (ag.contains(resolvedTPH) && ag.TA1.equals(resolvedTPH) && !contains(allPairs, ag)) {
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);
allPairs.add(ag);
TPHConstraint con = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS);
allCons.add(con);
}
TPHConstraint con = new ExtendsConstraint(ag.getLeft().getName(), ag.getRight().getName(), Relation.EXTENDS);
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) {
for (int i = 0; i < pairs.size(); ++i) {
GenericInsertPair p = pairs.get(i);

@@ -1,5 +1,6 @@
package de.dhbwstuttgart.bytecode.descriptor;
import java.util.HashMap;
import java.util.Iterator;
import org.objectweb.asm.Type;
@@ -44,17 +45,28 @@ public class DescriptorToString implements DescriptorVisitor{
if(method.hasGen()) {
String fpDesc = fp.getType().acceptTV(new TypeToDescriptor());
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)){
desc += "L"+method.getGenericsAndBounds().get(fpDesc)+ ";";
String bound = getBound(fpDesc, method.getGenericsAndBounds());
desc += "L"+bound+ ";";
}else {
// desc += "L"+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
desc += "L"+Type.getInternalName(Object.class)+ ";";
} 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)+ ";";
}else {
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"+Type.getInternalName(Object.class)+ ";";
} 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 {
@@ -93,6 +115,15 @@ public class DescriptorToString implements DescriptorVisitor{
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
public String visit(NormalConstructor constructor) {
String desc = "(";
@@ -131,7 +162,7 @@ public class DescriptorToString implements DescriptorVisitor{
while(itr.hasNext()) {
FormalParameter fp = itr.next();
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)+ ";";
}else {
desc = desc + "L"+ d + ";";
@@ -140,7 +171,7 @@ public class DescriptorToString implements DescriptorVisitor{
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)+ ";";
}else {
desc = desc + ")"+"L"+retType+";";
@@ -156,7 +187,7 @@ public class DescriptorToString implements DescriptorVisitor{
RefTypeOrTPHOrWildcardOrGeneric rt = itr.next();
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)+ ";";
}else {
desc += "L"+ d + ";";
@@ -165,7 +196,7 @@ public class DescriptorToString implements DescriptorVisitor{
}
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)+ ";";
}else {
desc = desc + ")"+"L"+retType+";";
@@ -179,7 +210,7 @@ public class DescriptorToString implements DescriptorVisitor{
for(Expression e : methodFromMethodCall.getArgList().getArguments()) {
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)+ ";";
}else {
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(d)) {
@@ -196,7 +227,7 @@ public class DescriptorToString implements DescriptorVisitor{
System.out.println("DescriptorToString retType = " + retType);
if(retType.equals("void")) {
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)+ ";";
}else {
if(methodFromMethodCall.getGenericsAndBoundsMethod().containsKey(retType)) {

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

@@ -2,14 +2,17 @@ package de.dhbwstuttgart.bytecode.utilities;
import java.util.ArrayList;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.result.GenericInsertPair;
import de.dhbwstuttgart.typeinference.result.ResultPair;
public class MethodAndTPH {
private String name;
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<>();
@@ -21,7 +24,10 @@ public class MethodAndTPH {
return tphs;
}
public ArrayList<GenericInsertPair> getPairs(){
// public ArrayList<GenericInsertPair> getPairs(){
// return pairs;
// }
public ArrayList<ResultPair<TypePlaceholder, TypePlaceholder>> getPairs(){
return pairs;
}

@@ -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;
}
public ArgumentList getArgList() {
return argList;
}

@@ -19,7 +19,7 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
public class Simplify {
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor,
ArrayList<TypePlaceholder> tphsClass) {
ArrayList<String> tphsClass) {
// 1. check if there are any simple cycles like L<R and R<L:
// a) yes => set L=R and:
// * remove both constraints
@@ -38,8 +38,10 @@ public class Simplify {
ArrayList<TPHConstraint> allCons = new ArrayList<>();
for(TPHConstraint c : tphExtractor.allCons) {
TPHConstraint nc = new TPHConstraint(c.getLeft(), c.getRight(), c.getRel());
allCons.add(nc);
if(!containsConstraint(allCons,c)) {
TPHConstraint nc = new TPHConstraint(c.getLeft(), c.getRight(), c.getRel());
allCons.add(nc);
}
}
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
@@ -382,7 +384,7 @@ public class Simplify {
if (!containTPH(methodTphs, superTphRes)) {
HashSet<String> equals = getEqualsTphsFromEqualCons(eqCons, superTphRes);
if (classTPHSContainsTPH(tphsClass, superTphRes)) {
if (tphsClass.contains(superTphRes)/*classTPHSContainsTPH(tphsClass, superTphRes)*/) {
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), equals);
} else {
result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS),
@@ -450,6 +452,15 @@ public class Simplify {
return result;
}
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 static void updateEqualCons(Map<String, List<String>> replRes, ArrayList<TPHConstraint> eqCons) {
List<String> oldNames = replRes.values().iterator().next();
String newName = replRes.keySet().iterator().next();
@@ -463,7 +474,7 @@ public class Simplify {
}
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraintsClass(TPHExtractor tphExtractor,
ArrayList<TypePlaceholder> tphsClass) {
ArrayList<String> tphsClass) {
// all constraints that will be simplified
ArrayList<TPHConstraint> allCons = tphExtractor.allCons;
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
@@ -627,7 +638,9 @@ public class Simplify {
if (isTPHInConstraint(result, sub))
continue;
if (!classTPHSContainsTPH(tphsClass, sub))
// if (!classTPHSContainsTPH(tphsClass, sub))
// continue;
if (!tphsClass.contains(sub))
continue;
if (numOfVisitedPairs >= size)
@@ -656,7 +669,7 @@ public class Simplify {
// add X at the beginning of the list.
while (subAndSuper.containsValue(subTphRes)) {
for (String tph : subAndSuper.keySet()) {
if (classTPHSContainsTPH(tphsClass, tph) && subAndSuper.get(tph).equals(subTphRes)) {
if (/*classTPHSContainsTPH(tphsClass, tph)*/tphsClass.contains(tph) && subAndSuper.get(tph).equals(subTphRes)) {
subTphRes = tph;
break;
}

@@ -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.Exception.BytecodeGeneratorError;
import de.dhbwstuttgart.bytecode.utilities.SimplifyResult;
import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.parser.JavaTXParser;
import de.dhbwstuttgart.parser.NullToken;
@@ -50,6 +52,7 @@ import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.antlr.v4.parse.ANTLRParser.throwsSpec_return;
import org.apache.commons.io.output.NullOutputStream;
//import org.apache.commons.io.output.NullOutputStream;
public class JavaTXCompiler {
@@ -58,7 +61,14 @@ public class JavaTXCompiler {
Boolean resultmodel = false;
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?
/**
* Ä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 {
this(Arrays.asList(sourceFile));
}
@@ -555,8 +565,8 @@ public class JavaTXCompiler {
}
/* UnifyResultModel End */
else {
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, new UnifyResultModel(cons, finiteClosure));
//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, new UnifyResultModel(cons, finiteClosure));
System.out.println("RESULT: " + result);
logFile.write("RES: " + result.toString()+"\n");
logFile.flush();
@@ -642,7 +652,7 @@ public class JavaTXCompiler {
return ret;
}
// 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()) {
HashMap<String,byte[]> classFiles = new HashMap<>();
SourceFile sf = sourceFiles.get(f);
@@ -650,6 +660,7 @@ public class JavaTXCompiler {
BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult,sf,path);
// BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult.get(0));
bytecodeGen.visit(sf);
this.simplifyResultsSF.add(bytecodeGen.getSimplifyResultsList());
this.writeClassFile(bytecodeGen.getClassFiles(), path);
}
}
@@ -666,4 +677,8 @@ public class JavaTXCompiler {
System.out.println(name+".class file generated");
}
}
public List<List<HashMap<String, SimplifyResult>>> getSimplifyResults() {
return simplifyResultsSF;
}
}

@@ -100,7 +100,7 @@ public class UnifyTypeFactory {
}
ret = new ReferenceType(t.getName().toString(),new TypeParams(params));
}else{
ret = new ReferenceType(t.getName().toString());
ret = new ReferenceType(t.getName().toString(), false);
}
return ret;
}
@@ -136,7 +136,7 @@ public class UnifyTypeFactory {
}
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){
@@ -222,12 +222,15 @@ public class UnifyTypeFactory {
return new PairTPHequalRefTypeOrWildcardType((TypePlaceholder)tl, (RefType) tr);
}else if(tr instanceof WildcardType){
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();
}
public static RefTypeOrTPHOrWildcardOrGeneric convert(ReferenceType t, Map<String,TypePlaceholder> tphs) {
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());
return ret;
}

@@ -1,9 +1,6 @@
package de.dhbwstuttgart.typedeployment;
import org.antlr.v4.runtime.Token;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

@@ -32,7 +32,7 @@ public class TypeInsertFactory {
ResolvedType resolvedType = resultSet.resolveType(type);
TypeInsertPoint insertPoint = new TypeInsertPoint(offset,
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){

@@ -8,7 +8,7 @@ import java.util.List;
import java.util.stream.Collectors;
public class TypeInsertPoint {
public final Token point;
public Token point;
private String insertString;
public TypeInsertPoint(Token point, String toInsert){
@@ -28,6 +28,14 @@ public class TypeInsertPoint {
return insertString;
}
public Token getToken() {
return this.point;
}
public void setToken(Token point) {
this.point = point;
}
/* PL 2018-06-19
* Zwei TypeInsertPoint's sind gleich, wenn ihre point's gleich sind
* eingefuegt damit man TypeReplaceMarker vergleichen kann

@@ -23,4 +23,9 @@ public class GenericInsertPair {
if(TA2.equals(additionalTPH))return true;
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) {
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) {
visitor.visit(this);
}
@Override
public String toString() {
return "(" + left.toString() + " < " + right.toString() + ")";
}
}

@@ -8,10 +8,10 @@ import java.util.Set;
public class ResolvedType{
public final RefTypeOrTPHOrWildcardOrGeneric resolvedType;
public final Set<GenericInsertPair> additionalGenerics;
//public final Set<GenericInsertPair> additionalGenerics;
public ResolvedType(RefTypeOrTPHOrWildcardOrGeneric resolvedType, Set<GenericInsertPair> additionalGenerics){
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.Set;
import java.util.stream.Collectors;
public class ResultSet {
public final Set<ResultPair> results;
public Set<ResultPair<TypePlaceholder, TypePlaceholder>> genIns;
public ResultSet(Set<ResultPair> 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) {

@@ -19,6 +19,10 @@ import java.util.function.BinaryOperator;
import java.util.stream.Collectors;
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.typeinference.constraints.Constraint;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
@@ -44,6 +48,7 @@ import de.dhbwstuttgart.typeinference.unify.model.Pair;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import com.google.common.collect.Ordering;
@@ -163,7 +168,9 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
thNo = totalnoOfThread;
writeLog("thNo2 " + thNo);
try {
this.logFile = new FileWriter(new File(System.getProperty("user.dir")+"/src/test/java/logFiles/"+"Thread_"+thNo));
this.logFile = //new OutputStreamWriter(new NullOutputStream());
new FileWriter(new File(System.getProperty("user.dir")+"/src/test/java/logFiles/"+"Thread_"+thNo));
//logFile.write("");
}
catch (IOException e) {
System.err.println("log-File nicht vorhanden");
@@ -228,7 +235,9 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
catch (IOException ioE) {
System.err.println("no log-File");
}
if (isUndefinedPairSetSet(res)) { return new HashSet<>(); }
if (isUndefinedPairSetSet(res)) {
throw new TypeinferenceException("Unresolved constraints: " + res.toString(), new NullToken()); //return new HashSet<>();
}
else return res;
}
/*
@@ -478,15 +487,16 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//PL 2018-05-18 beide Bedingungen muessen gelten, da eqPrime Veränderungen in allem ausser subst
//eqPrimePrime Veraenderungen in subst repraesentieren.
//try {
if (isSolvedForm(eqPrime)) {
writeLog("eqPrime:" + eqPrime.toString()+"\n");
}
//if (isSolvedForm(eqPrime)) {
// writeLog("eqPrime:" + eqPrime.toString()+"\n");
//}
//}
//catch (IOException e) {
// System.err.println("log-File nicht vorhanden");
//}
eqPrimePrimeSet.add(eqPrime);
if (finalresult) {
if (finalresult && isSolvedForm(eqPrime)) {
writeLog("eqPrime:" + eqPrime.toString()+"\n");
urm.notify(eqPrimePrimeSet);
}
}
@@ -542,7 +552,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
return result;
}
Set<Set<UnifyPair>> nextSet = remainingSets.remove(0);
writeLog("nextSet: " + nextSet.toString());
if (finalresult) writeLog("nextSet: " + nextSet.toString());
List<Set<UnifyPair>> nextSetasList =new ArrayList<>(nextSet);
try {
//List<Set<UnifyPair>>
@@ -611,9 +621,9 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
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());
if (finalresult) writeLog("nextSetasList: " + nextSetasList.toString());
Set<UnifyPair> nextSetElem = nextSetasList.get(0);
writeLog("BasePair1: " + nextSetElem + " " + nextSetElem.iterator().next().getBasePair());
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<>();
@@ -747,7 +757,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
//for(Set<UnifyPair> a : newSet) {
i++;
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
//im else-Zweig
//if (remainingSets.isEmpty()) {//muss immer gegeben sein, weil nur 1 Element der topLevelSets mehr als ein Elemet enthaelt
@@ -1341,7 +1351,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
// .collect(Collectors.toCollection(ArrayList::new));
writeLog("res (undef): " + res.toString());
writeLog("abhSubst: " + abhSubst.toString());
writeLog("a2: " + rekTiefe + " " + a.toString());
if (finalresult) writeLog("a2: " + rekTiefe + " " + a.toString());
writeLog("Durchschnitt: " + durchschnitt.toString());
writeLog("nextSet: " + nextSet.toString());
writeLog("nextSetasList: " + nextSetasList.toString());

@@ -11,28 +11,45 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.UnifyTypeVisitor;
* @author Florian Steurer
*
*/
public final class ReferenceType extends UnifyType {
public class ReferenceType extends UnifyType {
/**
* The buffered 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) {
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) {
super(name, new TypeParams(params));
hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();
genericTypeVar = false;
}
public ReferenceType(String name, TypeParams params) {
super(name, params);
hashCode = 31 + 17 * typeName.hashCode() + 17 * typeParams.hashCode();
genericTypeVar = false;
}
public boolean isGenTypeVar () {
return genericTypeVar;
}
@Override
Set<UnifyType> smArg(IFiniteClosure fc, Set<UnifyType> fBounded) {
return fc.smArg(this, fBounded);

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

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

@@ -0,0 +1,45 @@
package bytecode;
import static org.junit.Assert.*;
import java.io.File;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Vector;
import org.junit.BeforeClass;
import org.junit.Test;
import de.dhbwstuttgart.core.JavaTXCompiler;
public class VectorSuperTest {
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;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/VectorSuper.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("VectorSuper");
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
}
@Test
public void test1() throws Exception {
Method m = classToTest.getDeclaredMethod("m", Vector.class);
//Object result = m.invoke(instanceOfClass, 1);
//assertEquals(1,result);
}
}

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

@@ -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.Long;
import java.lang.Short;
public class Faculty {
public fact;
Faculty() {
fact = (x) -> {
if (x == 1) {
return 1;
}
else {
return x * (fact.apply(x-1));
}
};
}
public getFact(x) {
return fact.apply(x);
}
public fact;
Faculty() {
fact = (x) -> {
if (x == 1) {
return 1;
}
else {
return x * (fact.apply(x-1));
}
};
}
public getFact(x) {
return fact.apply(x);
}
}
// m (x) {
//
//// var fact = (x) -> {
@@ -45,4 +48,4 @@ public class Faculty {
// return x * m(x-1);
// }
// }
}

@@ -1,6 +1,7 @@
public class Id<FTU extends FTT,FTT> {
public class Id {
id(FTU b){
id(b){
return b;
}
}
}

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

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

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

@@ -0,0 +1,11 @@
import java.util.Vector;
import java.lang.Integer;
public class VectorSuper {
m(x){
Integer y = 1;
x.addElement(y);
//return x;
}
}