Merge branch 'bytecode2' of ssh://gohorb.ba-horb.de/bahome/projekt/git/JavaCompilerCore into plugin
This commit is contained in:
commit
fd8568532a
Binary file not shown.
24
doc/parser.md
Normal file
24
doc/parser.md
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# Dateien
|
||||||
|
* sämtliche Datein im Ordner de.dhbwstuttgart.parser gehören zum Parser
|
||||||
|
* Auch zu beachten: pom.xml
|
||||||
|
* Ein Teil der pom.xml instruiert maven zur Kompilierung der Java8.g4 Datei
|
||||||
|
* VORSICHT! Wird nicht zwangsläufig von der IDE ausgeführt
|
||||||
|
* siehe Kapitel "Grammatik -> Parser"
|
||||||
|
|
||||||
|
|
||||||
|
## Unterordner antlr
|
||||||
|
* Java8.g4
|
||||||
|
* die eigentliche Java Grammatik
|
||||||
|
* hier wurden Anpassungen vorgenommen, damit sie auch typloses Java annimmt
|
||||||
|
* alle anderen Dateien in diesem Ordner sind vom ANTLR-Parsergenerator autogeneriert
|
||||||
|
|
||||||
|
## Unterordner SyntaxTreeGenerator
|
||||||
|
* SyntaxTreeGenerator
|
||||||
|
* TODO
|
||||||
|
|
||||||
|
# Grammatik -> Parser
|
||||||
|
* Die Antlr-Grammatik (Java8.g4) wandelt
|
||||||
|
* Folgende Stellen sind relevant
|
||||||
|
* TODO
|
||||||
|
|
||||||
|
|
@ -69,8 +69,11 @@ public class ArgumentVisitor implements StatementVisitor {
|
|||||||
public void visit(BinaryExpr binary) {
|
public void visit(BinaryExpr binary) {
|
||||||
binary.accept(bytecodeGenMethod);
|
binary.accept(bytecodeGenMethod);
|
||||||
|
|
||||||
if(argListMethCall.get(0))
|
if(argListMethCall.get(0)) {
|
||||||
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(binary.getType()));
|
bytecodeGenMethod.doUnboxing(bytecodeGenMethod.getResolvedType(binary.getType()));
|
||||||
|
} else {
|
||||||
|
bytecodeGenMethod.doBoxing(bytecodeGenMethod.getResolvedType(binary.getType()));
|
||||||
|
}
|
||||||
argListMethCall.remove(0);
|
argListMethCall.remove(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,9 @@ package de.dhbwstuttgart.bytecode;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
import de.dhbwstuttgart.exceptions.NotImplementedException;
|
||||||
@ -13,6 +15,9 @@ import org.objectweb.asm.MethodVisitor;
|
|||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
|
import de.dhbwstuttgart.bytecode.descriptor.DescriptorToString;
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||||
import de.dhbwstuttgart.bytecode.signature.Signature;
|
import de.dhbwstuttgart.bytecode.signature.Signature;
|
||||||
@ -21,6 +26,7 @@ import de.dhbwstuttgart.bytecode.signature.TypeToString;
|
|||||||
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
|
import de.dhbwstuttgart.bytecode.utilities.NormalConstructor;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
|
import de.dhbwstuttgart.bytecode.utilities.NormalMethod;
|
||||||
|
import de.dhbwstuttgart.bytecode.utilities.Simplify;
|
||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.statement.Literal;
|
import de.dhbwstuttgart.syntaxtree.statement.Literal;
|
||||||
@ -56,8 +62,7 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
HashMap<String, Integer> paramsAndLocals = new HashMap<>();
|
HashMap<String, Integer> paramsAndLocals = new HashMap<>();
|
||||||
// stores generics and their bounds of class
|
// stores generics and their bounds of class
|
||||||
HashMap<String, String> genericsAndBounds = new HashMap<>();
|
HashMap<String, String> genericsAndBounds = new HashMap<>();
|
||||||
// stores generics and their bounds of method
|
|
||||||
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
|
|
||||||
|
|
||||||
private final TPHExtractor tphExtractor = new TPHExtractor();
|
private final TPHExtractor tphExtractor = new TPHExtractor();
|
||||||
private final ArrayList<GenericInsertPair> commonPairs = new ArrayList<>();
|
private final ArrayList<GenericInsertPair> commonPairs = new ArrayList<>();
|
||||||
@ -175,8 +180,32 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Constructor field) {
|
public void visit(Constructor field) {
|
||||||
|
System.out.println("ResultSet: ");
|
||||||
|
resultSet.results.forEach(a->{
|
||||||
|
System.out.println(a.getLeft().toString() + " = " + a.getRight().toString());
|
||||||
|
});
|
||||||
|
System.out.println("---------------");
|
||||||
|
|
||||||
|
// stores generics and their bounds of method
|
||||||
|
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
|
||||||
|
|
||||||
field.getParameterList().accept(this);
|
field.getParameterList().accept(this);
|
||||||
|
|
||||||
|
String methParamTypes = field.name+"%%";
|
||||||
|
|
||||||
|
Iterator<FormalParameter> itr = field.getParameterList().iterator();
|
||||||
|
while(itr.hasNext()) {
|
||||||
|
FormalParameter fp = itr.next();
|
||||||
|
methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";";
|
||||||
|
// methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";";
|
||||||
|
}
|
||||||
|
|
||||||
|
if(methodNameAndParamsT.contains(methParamTypes)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
methodNameAndParamsT.add(methParamTypes);
|
||||||
|
System.out.println("Method: "+field.name +" , paramsType: "+methParamTypes);
|
||||||
|
|
||||||
String desc = null;
|
String desc = null;
|
||||||
boolean hasGen = false;
|
boolean hasGen = false;
|
||||||
|
|
||||||
@ -190,8 +219,8 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
}
|
}
|
||||||
String sig = null;
|
String sig = null;
|
||||||
if(hasGen) {
|
if(hasGen) {
|
||||||
ArrayList<GenericInsertPair> pairs = simplifyPairs(field.name,tphExtractor.allPairs);
|
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(field.name, tphExtractor);
|
||||||
Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,pairs);
|
Signature signature = new Signature(field, genericsAndBounds,methodParamsAndTypes,resultSet,constraints);
|
||||||
sig = signature.toString();
|
sig = signature.toString();
|
||||||
}
|
}
|
||||||
NormalConstructor constructor = new NormalConstructor(field,genericsAndBounds,hasGen);
|
NormalConstructor constructor = new NormalConstructor(field,genericsAndBounds,hasGen);
|
||||||
@ -212,6 +241,7 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
// TODO: check if the method is static => if static then the first param will be stored in pos 0
|
// TODO: check if the method is static => if static then the first param will be stored in pos 0
|
||||||
// else it will be stored in pos 1 and this will be stored in pos 0
|
// else it will be stored in pos 1 and this will be stored in pos 0
|
||||||
String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
|
// String retType = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
||||||
String methParamTypes = retType+method.name+"%%";
|
String methParamTypes = retType+method.name+"%%";
|
||||||
method.getParameterList().accept(this);
|
method.getParameterList().accept(this);
|
||||||
|
|
||||||
@ -219,6 +249,7 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
while(itr.hasNext()) {
|
while(itr.hasNext()) {
|
||||||
FormalParameter fp = itr.next();
|
FormalParameter fp = itr.next();
|
||||||
methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";";
|
methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";";
|
||||||
|
// methParamTypes += resultSet.resolveType(fp.getType()).resolvedType.acceptTV(new TypeToSignature())+";";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(methodNameAndParamsT.contains(methParamTypes)) {
|
if(methodNameAndParamsT.contains(methParamTypes)) {
|
||||||
@ -226,6 +257,8 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
}
|
}
|
||||||
methodNameAndParamsT.add(methParamTypes);
|
methodNameAndParamsT.add(methParamTypes);
|
||||||
System.out.println("Method: "+method.name +" , paramsType: "+methParamTypes);
|
System.out.println("Method: "+method.name +" , paramsType: "+methParamTypes);
|
||||||
|
// stores generics and their bounds of method
|
||||||
|
HashMap<String, String> genericsAndBoundsMethod = new HashMap<>();
|
||||||
String methDesc = null;
|
String methDesc = null;
|
||||||
|
|
||||||
// Method getModifiers() ?
|
// Method getModifiers() ?
|
||||||
@ -257,10 +290,12 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
/* if method has generics or return type is TPH, create signature */
|
/* if method has generics or return type is TPH, create signature */
|
||||||
// zwite operand muss weggelassen werden
|
// zwite operand muss weggelassen werden
|
||||||
if(hasGen||resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString()).equals("TPH")) {
|
if(hasGen||resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString()).equals("TPH")) {
|
||||||
ArrayList<GenericInsertPair> pairs = simplifyPairs(method.name,tphExtractor.allPairs);
|
System.out.println("ALL CONST: " + tphExtractor.allCons.size());
|
||||||
System.out.println(method.name + " => Simplified Pairs: ");
|
tphExtractor.allCons.forEach(c->System.out.println(c.toString()));
|
||||||
pairs.forEach(p->System.out.println(p.TA1.getName() + " -> "+p.TA2.getName()));
|
System.out.println("----------------");
|
||||||
Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet, pairs);
|
HashMap<TPHConstraint, HashSet<String>> constraints = Simplify.simplifyConstraints(method.name, tphExtractor);
|
||||||
|
// ArrayList<GenericInsertPair> pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons);
|
||||||
|
Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds,methodParamsAndTypes,resultSet,constraints);
|
||||||
sig = signature.toString();
|
sig = signature.toString();
|
||||||
}
|
}
|
||||||
System.out.println(method.getName()+" ==> "+sig);
|
System.out.println(method.getName()+" ==> "+sig);
|
||||||
@ -278,145 +313,6 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
mv.visitEnd();
|
mv.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<GenericInsertPair> simplifyPairs(String methodName, ArrayList<GenericInsertPair> allPairs) {
|
|
||||||
allPairs.forEach(p->System.out.print(p.TA1 + " < "+ p.TA2+ " ; "));
|
|
||||||
|
|
||||||
if(allPairs.size() < 2)
|
|
||||||
return allPairs;
|
|
||||||
|
|
||||||
ArrayList<GenericInsertPair> simplifiedPairs = new ArrayList<>();
|
|
||||||
|
|
||||||
ArrayList<HashMap<Integer, TypePlaceholder>> beforeSimplify = new ArrayList<>();
|
|
||||||
|
|
||||||
MethodAndTPH method;
|
|
||||||
ArrayList<TypePlaceholder> methodTphs = new ArrayList<>();
|
|
||||||
ArrayList<GenericInsertPair> methodPairs = new ArrayList<>();
|
|
||||||
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
|
|
||||||
if(m.getName().equals(methodName)) {
|
|
||||||
methodTphs = m.getTphs();
|
|
||||||
methodPairs = m.getPairs();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
HashMap<TypePlaceholder, TypePlaceholder> subAndSuperTph = new HashMap<>();
|
|
||||||
for(GenericInsertPair p : allPairs) {
|
|
||||||
// Tph2.jav
|
|
||||||
if(subAndSuperTph.containsKey(p.TA1)) {
|
|
||||||
if(methodTphs.contains(subAndSuperTph.get(p.TA1)))
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
subAndSuperTph.put(p.TA1, p.TA2);
|
|
||||||
}
|
|
||||||
int numOfVisitedPairs = 0;
|
|
||||||
for(TypePlaceholder subTph: subAndSuperTph.keySet()) {
|
|
||||||
|
|
||||||
if(numOfVisitedPairs>=subAndSuperTph.size())
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(!methodTphs.contains(subTph))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
HashMap<Integer, TypePlaceholder> tphsInRel= new HashMap<>();
|
|
||||||
|
|
||||||
tphsInRel.put(tphsInRel.size(), subTph);
|
|
||||||
TypePlaceholder superTph = subAndSuperTph.get(subTph);
|
|
||||||
tphsInRel.put(tphsInRel.size(), superTph);
|
|
||||||
|
|
||||||
numOfVisitedPairs++;
|
|
||||||
boolean isCycle = false;
|
|
||||||
while(subAndSuperTph.containsKey(superTph)) {
|
|
||||||
superTph = subAndSuperTph.get(superTph);
|
|
||||||
if(tphsInRel.containsValue(superTph)) {
|
|
||||||
isCycle = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tphsInRel.put(tphsInRel.size(), superTph);
|
|
||||||
numOfVisitedPairs++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subtype
|
|
||||||
TypePlaceholder subTphRes = tphsInRel.get(0);
|
|
||||||
// Die größte Supertype
|
|
||||||
TypePlaceholder superTphRes = tphsInRel.get(tphsInRel.size()-1);
|
|
||||||
|
|
||||||
while(subAndSuperTph.containsValue(subTphRes)) {
|
|
||||||
for(TypePlaceholder tph : subAndSuperTph.keySet()) {
|
|
||||||
if(methodTphs.contains(tph) && subAndSuperTph.get(tph).equals(subTphRes)) {
|
|
||||||
subTphRes = tph;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(subTphRes.equals(tphsInRel.get(0))) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tphsInRel.put(0, subTphRes);
|
|
||||||
numOfVisitedPairs++;
|
|
||||||
}
|
|
||||||
|
|
||||||
subTphRes = tphsInRel.get(0);
|
|
||||||
|
|
||||||
int i = 2;
|
|
||||||
while(!methodTphs.contains(superTphRes) && (tphsInRel.size()-i) >0) {
|
|
||||||
superTphRes = tphsInRel.get(tphsInRel.size()-i);
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if((methodTphs.contains(superTphRes) || !tphExtractor.allTPHS.containsKey(superTphRes))
|
|
||||||
&& !subTphRes.equals(superTphRes)) {
|
|
||||||
|
|
||||||
beforeSimplify.add(tphsInRel);
|
|
||||||
}
|
|
||||||
|
|
||||||
// teste noch den Fall X < Y und Y nicht in TPHS der Methode
|
|
||||||
// Dann hat man nach der While-Schleife X < Y
|
|
||||||
// Y muss durch Object ersetzt.
|
|
||||||
|
|
||||||
// Zweite Operand für die Fälle wie in Lambda.jav (Paramtrisierte Typen)
|
|
||||||
if((methodTphs.contains(superTphRes) || !tphExtractor.allTPHS.containsKey(superTphRes))
|
|
||||||
&& !subTphRes.equals(superTphRes)) {
|
|
||||||
GenericInsertPair sPair = new GenericInsertPair(subTphRes, superTphRes);
|
|
||||||
simplifiedPairs.add(sPair);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
beforeSimplify.forEach(e->{
|
|
||||||
System.out.println("=> ");
|
|
||||||
e.forEach((v,k) -> {
|
|
||||||
System.out.print(v + "->" + k + ", ");
|
|
||||||
});
|
|
||||||
System.out.println();
|
|
||||||
System.out.println("----------------------");
|
|
||||||
});
|
|
||||||
|
|
||||||
if(beforeSimplify.size()>1) {
|
|
||||||
int i = 0;
|
|
||||||
while(i<beforeSimplify.size()) {
|
|
||||||
TypePlaceholder sub = beforeSimplify.get(i).get(0);
|
|
||||||
|
|
||||||
for(HashMap<Integer, TypePlaceholder> e: beforeSimplify) {
|
|
||||||
if(!e.equals(beforeSimplify.get(i)) && e.containsValue(sub)) {
|
|
||||||
GenericInsertPair sPair = new GenericInsertPair(e.get(0), sub);
|
|
||||||
System.out.println("To remove = " + e.get(0)+ " " +e.get(e.size()-1));
|
|
||||||
removePair(simplifiedPairs,e.get(0), e.get(e.size()-1));
|
|
||||||
simplifiedPairs.add(sPair);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return simplifiedPairs;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void removePair(ArrayList<GenericInsertPair> simplifiedPairs, TypePlaceholder typePlaceholder, TypePlaceholder typePlaceholder2) {
|
|
||||||
for(GenericInsertPair p : simplifiedPairs) {
|
|
||||||
if(p.TA1.equals(typePlaceholder) && p.TA2.equals(typePlaceholder2)) {
|
|
||||||
simplifiedPairs.remove(p);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(ParameterList formalParameters) {
|
public void visit(ParameterList formalParameters) {
|
||||||
paramsAndLocals = new HashMap<>();
|
paramsAndLocals = new HashMap<>();
|
||||||
@ -469,16 +365,19 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
// ??
|
// ??
|
||||||
@Override
|
@Override
|
||||||
public void visit(FieldVar fieldVar) {
|
public void visit(FieldVar fieldVar) {
|
||||||
|
System.out.println("In FieldVar ---");
|
||||||
// cw.newField(fieldVar.receiver.toString(), fieldVar.fieldVarName.toString(), fieldVar.getType().toString());
|
// cw.newField(fieldVar.receiver.toString(), fieldVar.fieldVarName.toString(), fieldVar.getType().toString());
|
||||||
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, fieldVar.fieldVarName, "L"+fieldVar.getType()+";", null, null);
|
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, fieldVar.fieldVarName, "L"+fieldVar.getType()+";", null, null);
|
||||||
fv.visitEnd();
|
fv.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
// access flages?? modifiers
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(Field field) {
|
public void visit(Field field) {
|
||||||
FieldVisitor fv = cw.visitField(Opcodes.ACC_PRIVATE, field.getName(), "L"+field.getType().toString().replace(".", "/")+";", null, null);
|
System.out.println("In Field ---");
|
||||||
fv.visitEnd();
|
cw.visitField(field.modifier, field.getName(),
|
||||||
|
"L"+resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToDescriptor())+";",
|
||||||
|
resultSet.resolveType(field.getType()).resolvedType.acceptTV(new TypeToSignature()),
|
||||||
|
null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -659,14 +558,15 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TPHExtractor extends AbstractASTWalker{
|
public class TPHExtractor extends AbstractASTWalker{
|
||||||
// Alle TPHs der Felder werden iKopf der Klasse definiert
|
// Alle TPHs der Felder werden iKopf der Klasse definiert
|
||||||
// alle TPHs der Klasse: (TPH, is in Method?)
|
// alle TPHs der Klasse: (TPH, is in Method?)
|
||||||
final HashMap<TypePlaceholder,Boolean> allTPHS = new HashMap<>();
|
final HashMap<TypePlaceholder,Boolean> allTPHS = new HashMap<>();
|
||||||
MethodAndTPH methodAndTph;
|
MethodAndTPH methodAndTph;
|
||||||
Boolean inMethod = false;
|
Boolean inMethod = false;
|
||||||
final ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>();
|
public final ArrayList<MethodAndTPH> ListOfMethodsAndTph = new ArrayList<>();
|
||||||
final ArrayList<GenericInsertPair> allPairs = new ArrayList<>();
|
final ArrayList<GenericInsertPair> allPairs = new ArrayList<>();
|
||||||
|
public final ArrayList<TPHConstraint> allCons = new ArrayList<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(TypePlaceholder tph) {
|
public void visit(TypePlaceholder tph) {
|
||||||
@ -681,6 +581,8 @@ public class BytecodeGen implements ASTVisitor {
|
|||||||
if(inMethod)
|
if(inMethod)
|
||||||
methodAndTph.getPairs().add(ag);
|
methodAndTph.getPairs().add(ag);
|
||||||
allPairs.add(ag);
|
allPairs.add(ag);
|
||||||
|
TPHConstraint con = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS);
|
||||||
|
allCons.add(con);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ import java.lang.invoke.MethodHandle;
|
|||||||
import java.lang.invoke.MethodHandles;
|
import java.lang.invoke.MethodHandles;
|
||||||
import java.lang.invoke.MethodType;
|
import java.lang.invoke.MethodType;
|
||||||
import java.lang.reflect.Parameter;
|
import java.lang.reflect.Parameter;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
@ -68,6 +70,8 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
private String path;
|
private String path;
|
||||||
private SourceFile sf;
|
private SourceFile sf;
|
||||||
private IStatement statement = null;
|
private IStatement statement = null;
|
||||||
|
private boolean isReturnStmt = false;
|
||||||
|
private boolean isParentBinary = false;
|
||||||
|
|
||||||
private boolean needDUP = false;
|
private boolean needDUP = false;
|
||||||
|
|
||||||
@ -106,14 +110,14 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public BytecodeGenMethod(LambdaExpression lambdaExpression, ResultSet resultSet, MethodVisitor mv,
|
public BytecodeGenMethod(LambdaExpression lambdaExpression, ResultSet resultSet, MethodVisitor mv,
|
||||||
int indexOfFirstParamLam, boolean isInterface, HashMap<String, byte[]> classFiles, String path) {
|
int indexOfFirstParamLam, boolean isInterface, HashMap<String, byte[]> classFiles, String path, int lamCounter) {
|
||||||
|
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
this.mv = mv;
|
this.mv = mv;
|
||||||
this.isInterface = isInterface;
|
this.isInterface = isInterface;
|
||||||
this.classFiles = classFiles;
|
this.classFiles = classFiles;
|
||||||
this.path = path;
|
this.path = path;
|
||||||
|
this.lamCounter = lamCounter;
|
||||||
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
||||||
int i = indexOfFirstParamLam;
|
int i = indexOfFirstParamLam;
|
||||||
while (itr.hasNext()) {
|
while (itr.hasNext()) {
|
||||||
@ -208,7 +212,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(BinaryExpr binary) {
|
public void visit(BinaryExpr binary) {
|
||||||
|
isParentBinary = true;
|
||||||
String lexpType = getResolvedType(binary.lexpr.getType());
|
String lexpType = getResolvedType(binary.lexpr.getType());
|
||||||
String rexpType = getResolvedType(binary.rexpr.getType());
|
String rexpType = getResolvedType(binary.rexpr.getType());
|
||||||
|
|
||||||
@ -223,7 +227,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Label endLabel = new Label();
|
Label endLabel = new Label();
|
||||||
// this case for while loops
|
// this case for while loops and If statements
|
||||||
if (statement instanceof LoopStmt)
|
if (statement instanceof LoopStmt)
|
||||||
mv.visitLabel(endLabel);
|
mv.visitLabel(endLabel);
|
||||||
|
|
||||||
@ -240,6 +244,8 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
binary.rexpr.accept(this);
|
binary.rexpr.accept(this);
|
||||||
|
|
||||||
|
isParentBinary = false;
|
||||||
|
|
||||||
if (!lexpType.equals(rexpType) && !rexpType.equals(largerType))
|
if (!lexpType.equals(rexpType) && !rexpType.equals(largerType))
|
||||||
doCast(rexpType, largerType);
|
doCast(rexpType, largerType);
|
||||||
|
|
||||||
@ -270,6 +276,8 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
case LESSEQUAL:
|
case LESSEQUAL:
|
||||||
case BIGGERTHAN:
|
case BIGGERTHAN:
|
||||||
case BIGGEREQUAL:
|
case BIGGEREQUAL:
|
||||||
|
case EQUAL:
|
||||||
|
case NOTEQUAL:
|
||||||
Label branchLabel = new Label();
|
Label branchLabel = new Label();
|
||||||
doVisitRelOpInsn(op, largerType, branchLabel, endLabel);
|
doVisitRelOpInsn(op, largerType, branchLabel, endLabel);
|
||||||
break;
|
break;
|
||||||
@ -277,7 +285,6 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getLargerType(String lexpType, String rexpType) {
|
private String getLargerType(String lexpType, String rexpType) {
|
||||||
@ -501,6 +508,18 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
public void visit(LambdaExpression lambdaExpression) {
|
public void visit(LambdaExpression lambdaExpression) {
|
||||||
this.lamCounter++;
|
this.lamCounter++;
|
||||||
|
|
||||||
|
String typeErasure = "(";
|
||||||
|
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
||||||
|
while (itr.hasNext()) {
|
||||||
|
itr.next();
|
||||||
|
typeErasure += "L" + Type.getInternalName(Object.class) + ";";
|
||||||
|
}
|
||||||
|
|
||||||
|
typeErasure += ")L" + Type.getInternalName(Object.class) + ";";
|
||||||
|
|
||||||
|
generateBCForFunN(lambdaExpression, typeErasure);
|
||||||
|
|
||||||
|
|
||||||
Lambda lam = new Lambda(lambdaExpression);
|
Lambda lam = new Lambda(lambdaExpression);
|
||||||
String lamDesc = lam.accept(new DescriptorToString(resultSet));
|
String lamDesc = lam.accept(new DescriptorToString(resultSet));
|
||||||
// Call site, which, when invoked, returns an instance of the functional
|
// Call site, which, when invoked, returns an instance of the functional
|
||||||
@ -516,14 +535,6 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
// Für die Parameter-Typen und Return-Typ braucht man die Bounds (für die
|
// Für die Parameter-Typen und Return-Typ braucht man die Bounds (für die
|
||||||
// Typlöschung)
|
// Typlöschung)
|
||||||
|
|
||||||
String typeErasure = "(";
|
|
||||||
Iterator<FormalParameter> itr = lambdaExpression.params.iterator();
|
|
||||||
while (itr.hasNext()) {
|
|
||||||
itr.next();
|
|
||||||
typeErasure += "L" + Type.getInternalName(Object.class) + ";";
|
|
||||||
}
|
|
||||||
|
|
||||||
typeErasure += ")L" + Type.getInternalName(Object.class) + ";";
|
|
||||||
// Type erasure
|
// Type erasure
|
||||||
Type arg1 = Type.getMethodType(typeErasure);
|
Type arg1 = Type.getMethodType(typeErasure);
|
||||||
// Type arg1 = Type.getMethodType(lamDesc);
|
// Type arg1 = Type.getMethodType(lamDesc);
|
||||||
@ -556,14 +567,14 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
methodName, arg3.toString(), null, null);
|
methodName, arg3.toString(), null, null);
|
||||||
|
|
||||||
new BytecodeGenMethod(lambdaExpression, this.resultSet, mvLambdaBody, indexOfFirstParamLam, isInterface,
|
new BytecodeGenMethod(lambdaExpression, this.resultSet, mvLambdaBody, indexOfFirstParamLam, isInterface,
|
||||||
classFiles,this.path);
|
classFiles,this.path, lamCounter);
|
||||||
|
|
||||||
mvLambdaBody.visitMaxs(0, 0);
|
mvLambdaBody.visitMaxs(0, 0);
|
||||||
mvLambdaBody.visitEnd();
|
mvLambdaBody.visitEnd();
|
||||||
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup",
|
cw.visitInnerClass("java/lang/invoke/MethodHandles$Lookup", "java/lang/invoke/MethodHandles", "Lookup",
|
||||||
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL);
|
Opcodes.ACC_PUBLIC + Opcodes.ACC_STATIC + Opcodes.ACC_FINAL);
|
||||||
|
|
||||||
generateBCForFunN(lambdaExpression, typeErasure);
|
// generateBCForFunN(lambdaExpression, typeErasure);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) {
|
private void generateBCForFunN(LambdaExpression lambdaExpression, String methDesc) {
|
||||||
@ -644,7 +655,10 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(IfStmt ifStmt) {
|
public void visit(IfStmt ifStmt) {
|
||||||
System.out.println("If");
|
statement = new IfStatement(ifStmt.expr, ifStmt.then_block, ifStmt.else_block);
|
||||||
|
isBinaryExp = statement.isExprBinary();
|
||||||
|
ifStmt.expr.accept(this);
|
||||||
|
statement = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -654,25 +668,36 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(MethodCall methodCall) {
|
public void visit(MethodCall methodCall) {
|
||||||
|
boolean parentBinary = isParentBinary;
|
||||||
System.out.println("In MethodCall = " + methodCall.name);
|
System.out.println("In MethodCall = " + methodCall.name);
|
||||||
String receiverName = getResolvedType(methodCall.receiver.getType());
|
String receiverName = getResolvedType(methodCall.receiver.getType());
|
||||||
System.out.println("Methods of " + receiverName + " ");
|
System.out.println("Methods of " + receiverName + " ");
|
||||||
ClassLoader cLoader = ClassLoader.getSystemClassLoader();
|
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;
|
java.lang.reflect.Method methodRefl = null;
|
||||||
String clazz = receiverName.replace("/", ".");
|
String clazz = receiverName.replace("/", ".");
|
||||||
|
String methCallType = resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor());
|
||||||
|
String[] typesOfParams = getTypes(methodCall.arglist.getArguments());
|
||||||
try {
|
try {
|
||||||
if(receiverName.contains("<")) {
|
if(receiverName.contains("<")) {
|
||||||
clazz = clazz.substring(0, receiverName.indexOf("<"));
|
clazz = clazz.substring(0, receiverName.indexOf("<"));
|
||||||
}
|
}
|
||||||
|
|
||||||
java.lang.reflect.Method[] methods = cLoader.loadClass(clazz).getMethods();
|
java.lang.reflect.Method[] methods = cLoader.loadClass(clazz).getMethods();
|
||||||
System.out.println("Methods of " + receiverName + " ");
|
System.out.println("Methods of " + receiverName + " ");
|
||||||
for(java.lang.reflect.Method m : methods) {
|
methodRefl = getMethod(methodCall.name,methodCall.arglist.getArguments().size(),methods);
|
||||||
if(methodCall.name.equals(m.getName())) {
|
|
||||||
methodRefl = m;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
// try {
|
||||||
|
// cLoader2 = new URLClassLoader(new URL[] {new URL("file://"+path)});
|
||||||
|
// java.lang.reflect.Method[] methods = cLoader2.loadClass(clazz).getMethods();
|
||||||
|
// System.out.println("Methods of " + receiverName + " ");
|
||||||
|
// for(int i = 0; i<methods.length; i++) {
|
||||||
|
// System.out.println(methods[i]);
|
||||||
|
// }
|
||||||
|
// methodRefl = getMethod(methodCall.name,methodCall.arglist.getArguments().size(),methCallType, typesOfParams,methods);
|
||||||
|
// }catch (Exception e2) {
|
||||||
String superClass = "";
|
String superClass = "";
|
||||||
// TODO: Test SubMatrix.jav
|
// TODO: Test SubMatrix.jav
|
||||||
while(true) {
|
while(true) {
|
||||||
@ -703,28 +728,46 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
} catch (Exception e2) {
|
} catch (Exception e3) {
|
||||||
receiverName = superClass;
|
receiverName = superClass;
|
||||||
continue;
|
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]);
|
||||||
|
}
|
||||||
|
methodRefl = getMethod(methodCall.name,methodCall.arglist.getArguments().size(),methCallType, typesOfParams,methods);
|
||||||
|
}catch (Exception e2) {
|
||||||
|
//do nothing
|
||||||
|
}
|
||||||
|
}
|
||||||
methodCall.receiver.accept(this);
|
methodCall.receiver.accept(this);
|
||||||
|
|
||||||
System.out.println("Methodcall type : " + resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor()));
|
System.out.println("Methodcall type : " + resultSet.resolveType(methodCall.getType()).resolvedType.acceptTV(new TypeToDescriptor()));
|
||||||
String mDesc = "";
|
String mDesc = "";
|
||||||
List<Boolean> argListMethCall = new LinkedList<>();
|
List<Boolean> argListMethCall = new LinkedList<>();
|
||||||
|
String receiverRefl="";
|
||||||
if(methodRefl == null) {
|
if(methodRefl == null) {
|
||||||
MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(),
|
MethodFromMethodCall method = new MethodFromMethodCall(methodCall.arglist, methodCall.getType(),
|
||||||
receiverName, genericsAndBoundsMethod, genericsAndBounds);
|
receiverName, genericsAndBoundsMethod, genericsAndBounds);
|
||||||
mDesc = method.accept(new DescriptorToString(resultSet));
|
mDesc = method.accept(new DescriptorToString(resultSet));
|
||||||
methodCall.arglist.accept(this);
|
methodCall.arglist.accept(this);
|
||||||
} else {
|
} else {
|
||||||
|
receiverRefl = methodRefl.getAnnotatedReceiverType().getType().toString();
|
||||||
for(Parameter p:methodRefl.getParameters()) {
|
for(Parameter p:methodRefl.getParameters()) {
|
||||||
System.out.println(p.getName() + " und is Primitive = " + p.getType().isPrimitive());
|
System.out.println(p.getName() + " und is Primitive = " + p.getType().isPrimitive());
|
||||||
argListMethCall.add(p.getType().isPrimitive());
|
argListMethCall.add(p.getType().isPrimitive());
|
||||||
}
|
}
|
||||||
|
System.out.println("Receiver = " + methodRefl.getAnnotatedReceiverType().getType().toString());
|
||||||
mDesc = getMethodDesc(methodRefl);
|
mDesc = getMethodDesc(methodRefl);
|
||||||
for (Expression al : methodCall.arglist.getArguments()) {
|
for (Expression al : methodCall.arglist.getArguments()) {
|
||||||
statement = new ArgumentExpr(al);
|
statement = new ArgumentExpr(al);
|
||||||
@ -740,7 +783,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
// methodCall.arglist.accept(this);
|
// methodCall.arglist.accept(this);
|
||||||
|
|
||||||
// is methodCall.receiver functional Interface)?
|
// is methodCall.receiver functional Interface)?
|
||||||
if (varsFunInterface.contains(methodCall.receiver.getType())) {
|
if (varsFunInterface.contains(methodCall.receiver.getType()) || (methodRefl!= null && receiverRefl.contains("interface"))) {
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, clazz.replace(".", "/"), methodCall.name,
|
mv.visitMethodInsn(Opcodes.INVOKEINTERFACE, clazz.replace(".", "/"), methodCall.name,
|
||||||
mDesc, true);
|
mDesc, true);
|
||||||
} else {
|
} else {
|
||||||
@ -759,9 +802,71 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
if(isBinaryExp)
|
if(isBinaryExp)
|
||||||
doUnboxing(getResolvedType(methodCall.getType()));
|
doUnboxing(getResolvedType(methodCall.getType()));
|
||||||
}
|
}
|
||||||
|
System.out.println("ISParent Binary = "+isParentBinary +" -> " + parentBinary);
|
||||||
|
if(methodRefl == null && (parentBinary || !isReturnStmt)) {
|
||||||
|
if(isBinaryExp)
|
||||||
|
doUnboxing(getResolvedType(methodCall.getType()));
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String[] getTypes(List<Expression> arguments) {
|
||||||
|
String[] types = new String[arguments.size()];
|
||||||
|
for(int i = 0; i<arguments.size(); ++i) {
|
||||||
|
String t = getResolvedType(arguments.get(i).getType());
|
||||||
|
types[i] = t;
|
||||||
|
}
|
||||||
|
return types;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For API methods
|
||||||
|
* @param name name of a method
|
||||||
|
* @param i number of parameters
|
||||||
|
* @param methods all methods of a class
|
||||||
|
* @return the method in the class file which its name equals the given methode name
|
||||||
|
*/
|
||||||
|
private java.lang.reflect.Method getMethod(String name, int i, java.lang.reflect.Method[] methods) {
|
||||||
|
for(java.lang.reflect.Method m : methods) {
|
||||||
|
if(name.equals(m.getName()) && i == m.getParameterCount()) {
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param name name of a method
|
||||||
|
* @param i number of parameters
|
||||||
|
* @param methCallType return type of method
|
||||||
|
* @param typesOfParams
|
||||||
|
* @param methods all methods of a class
|
||||||
|
* @return the method in the class file which its name equals the given methode name
|
||||||
|
*/
|
||||||
|
private java.lang.reflect.Method getMethod(String name, int i, String methCallType, String[] typesOfParams, java.lang.reflect.Method[] methods) {
|
||||||
|
// if(methCallType.equals("void")) {
|
||||||
|
// methCallType = "V";
|
||||||
|
// } else {
|
||||||
|
// methCallType = "L"+methCallType+";";
|
||||||
|
// }
|
||||||
|
for(java.lang.reflect.Method m : methods) {
|
||||||
|
if(name.equals(m.getName()) && i == m.getParameterCount() && methCallType.equals(m.getReturnType().getName().replace(".", "/"))) {
|
||||||
|
boolean typesEqual = true;
|
||||||
|
Class<?>[] pTypes = m.getParameterTypes();
|
||||||
|
for(int j = 0; j<typesOfParams.length; ++j) {
|
||||||
|
if(!typesOfParams[j].equals(pTypes[j])) {
|
||||||
|
typesEqual = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(typesEqual)
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
private String getMethodDesc(java.lang.reflect.Method methodRefl) {
|
private String getMethodDesc(java.lang.reflect.Method methodRefl) {
|
||||||
StringBuilder sb = new StringBuilder("(");
|
StringBuilder sb = new StringBuilder("(");
|
||||||
|
|
||||||
@ -918,20 +1023,22 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
@Override
|
@Override
|
||||||
public void visit(Return aReturn) {
|
public void visit(Return aReturn) {
|
||||||
statement = new ReturnStmt(aReturn.retexpr);
|
statement = new ReturnStmt(aReturn.retexpr);
|
||||||
|
isReturnStmt = true;
|
||||||
isBinaryExp = statement.isExprBinary();
|
isBinaryExp = statement.isExprBinary();
|
||||||
|
boolean isBinary = isBinaryExp;
|
||||||
if(aReturn.retexpr instanceof UnaryExpr)
|
if(aReturn.retexpr instanceof UnaryExpr)
|
||||||
needDUP = true;
|
needDUP = true;
|
||||||
|
|
||||||
aReturn.retexpr.accept(this);
|
aReturn.retexpr.accept(this);
|
||||||
|
|
||||||
if (isBinaryExp) {
|
if (isBinary) {
|
||||||
BinaryExpr binary = (BinaryExpr) aReturn.retexpr;
|
BinaryExpr binary = (BinaryExpr) aReturn.retexpr;
|
||||||
doBoxing(getResolvedType(binary.getType()));
|
doBoxing(getResolvedType(binary.getType()));
|
||||||
isBinaryExp = false;
|
// isBinaryExp = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
mv.visitInsn(Opcodes.ARETURN);
|
mv.visitInsn(Opcodes.ARETURN);
|
||||||
|
isReturnStmt = false;
|
||||||
statement = null;
|
statement = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1038,16 +1145,23 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
break;
|
break;
|
||||||
case "java/lang/Integer":
|
case "java/lang/Integer":
|
||||||
// zweite Argument isLong
|
// zweite Argument isLong
|
||||||
|
// visitIntegerLiteral(((Double) value).intValue(), false);
|
||||||
|
if(value instanceof Double)
|
||||||
visitIntegerLiteral(((Double) value).intValue(), false);
|
visitIntegerLiteral(((Double) value).intValue(), false);
|
||||||
|
if(value instanceof Integer)
|
||||||
|
visitIntegerLiteral(((Integer) value).intValue(), false);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Long":
|
case "java/lang/Long":
|
||||||
visitLongLiteral(((Double) value).longValue(), true);
|
visitLongLiteral(((Integer) value).longValue(), true);
|
||||||
break;
|
break;
|
||||||
case "java/lang/Float":
|
case "java/lang/Float":
|
||||||
visitFloatLiteral(((Double) value).floatValue());
|
visitFloatLiteral(((Double) value).floatValue());
|
||||||
break;
|
break;
|
||||||
case "java/lang/Double":
|
case "java/lang/Double":
|
||||||
|
if(value instanceof Double)
|
||||||
visitDoubleLiteral((Double) value);
|
visitDoubleLiteral((Double) value);
|
||||||
|
if(value instanceof Integer)
|
||||||
|
visitDoubleLiteral(((Integer) value).doubleValue());
|
||||||
break;
|
break;
|
||||||
case "java/lang/Character":
|
case "java/lang/Character":
|
||||||
visitCharLiteral((Character) value);
|
visitCharLiteral((Character) value);
|
||||||
@ -1067,7 +1181,7 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Boxing: prim -> RefType
|
// Boxing: prim -> RefType
|
||||||
private void doBoxing(String type) {
|
public void doBoxing(String type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case "java/lang/String":
|
case "java/lang/String":
|
||||||
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;",
|
mv.visitMethodInsn(Opcodes.INVOKEVIRTUAL, "java/lang/StringBuilder", "toString", "()Ljava/lang/String;",
|
||||||
@ -1191,7 +1305,6 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
BinaryExpr binary = (BinaryExpr) al;
|
BinaryExpr binary = (BinaryExpr) al;
|
||||||
String binaryType = getResolvedType(binary.getType());
|
String binaryType = getResolvedType(binary.getType());
|
||||||
doBoxing(binaryType);
|
doBoxing(binaryType);
|
||||||
isBinaryExp = false;
|
|
||||||
}
|
}
|
||||||
statement = null;
|
statement = null;
|
||||||
}
|
}
|
||||||
@ -1207,8 +1320,9 @@ public class BytecodeGenMethod implements StatementVisitor {
|
|||||||
// array slot onto the top of the operand stack.
|
// array slot onto the top of the operand stack.
|
||||||
assignLeftSide.field.receiver.accept(this);
|
assignLeftSide.field.receiver.accept(this);
|
||||||
this.rightSideTemp.accept(this);
|
this.rightSideTemp.accept(this);
|
||||||
|
System.out.println("Receiver = " + getResolvedType(assignLeftSide.field.receiver.getType()));
|
||||||
mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()),
|
mv.visitFieldInsn(Opcodes.PUTFIELD, getResolvedType(assignLeftSide.field.receiver.getType()),
|
||||||
assignLeftSide.field.fieldVarName, getResolvedType(assignLeftSide.field.getType()));
|
assignLeftSide.field.fieldVarName, "L"+getResolvedType(assignLeftSide.field.getType())+";");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
29
src/de/dhbwstuttgart/bytecode/IfStatement.java
Normal file
29
src/de/dhbwstuttgart/bytecode/IfStatement.java
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode;
|
||||||
|
|
||||||
|
import org.objectweb.asm.Label;
|
||||||
|
import org.objectweb.asm.MethodVisitor;
|
||||||
|
import org.objectweb.asm.Opcodes;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.Expression;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.statement.Statement;
|
||||||
|
|
||||||
|
public class IfStatement extends AStatement{
|
||||||
|
|
||||||
|
private Statement then_block;
|
||||||
|
private Statement else_block;
|
||||||
|
|
||||||
|
public IfStatement(Expression expr, Statement then_block, Statement else_block) {
|
||||||
|
super(expr);
|
||||||
|
this.then_block = then_block;
|
||||||
|
this.else_block = else_block;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void genBCForRelOp(MethodVisitor mv,Label branchLabel, Label endLabel, BytecodeGenMethod bytecodeGenMethod) {
|
||||||
|
bytecodeGenMethod.isBinary(false);
|
||||||
|
this.then_block.accept(bytecodeGenMethod);
|
||||||
|
|
||||||
|
mv.visitLabel(branchLabel);
|
||||||
|
this.else_block.accept(bytecodeGenMethod);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode.constraint;
|
||||||
|
|
||||||
|
public class EqualConstraint extends TPHConstraint {
|
||||||
|
|
||||||
|
public EqualConstraint(String left, String right, Relation rel) {
|
||||||
|
super(left, right, rel);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode.constraint;
|
||||||
|
|
||||||
|
public class ExtendsConstraint extends TPHConstraint {
|
||||||
|
|
||||||
|
public ExtendsConstraint(String left, String right, Relation rel) {
|
||||||
|
super(left, right, rel);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
55
src/de/dhbwstuttgart/bytecode/constraint/TPHConstraint.java
Normal file
55
src/de/dhbwstuttgart/bytecode/constraint/TPHConstraint.java
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode.constraint;
|
||||||
|
|
||||||
|
public class TPHConstraint {
|
||||||
|
protected String left;
|
||||||
|
protected String right;
|
||||||
|
protected Relation rel;
|
||||||
|
public enum Relation{
|
||||||
|
EXTENDS, EQUAL
|
||||||
|
}
|
||||||
|
|
||||||
|
public TPHConstraint(String left, String right, Relation rel) {
|
||||||
|
this.left = left;
|
||||||
|
this.right = right;
|
||||||
|
this.rel = rel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getLeft() {
|
||||||
|
return left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getRight() {
|
||||||
|
return right;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public Relation getRel() {
|
||||||
|
return rel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setLeft(String left) {
|
||||||
|
this.left = left;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRight(String right) {
|
||||||
|
this.right = right;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setRel(Relation rel) {
|
||||||
|
this.rel = rel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containTPH(String tph) {
|
||||||
|
return left.equals(tph)||right.equals(tph);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
if(rel == Relation.EXTENDS) {
|
||||||
|
return left + " < " + right;
|
||||||
|
}else {
|
||||||
|
return left + " = " + right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,15 +2,18 @@ package de.dhbwstuttgart.bytecode.signature;
|
|||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.signature.SignatureVisitor;
|
import org.objectweb.asm.signature.SignatureVisitor;
|
||||||
import org.objectweb.asm.signature.SignatureWriter;
|
import org.objectweb.asm.signature.SignatureWriter;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||||
import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH;
|
import de.dhbwstuttgart.bytecode.utilities.Simplify;
|
||||||
import de.dhbwstuttgart.syntaxtree.AbstractASTWalker;
|
|
||||||
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
|
||||||
import de.dhbwstuttgart.syntaxtree.Constructor;
|
import de.dhbwstuttgart.syntaxtree.Constructor;
|
||||||
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
|
||||||
@ -36,7 +39,7 @@ public class Signature {
|
|||||||
private HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes;
|
private HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes;
|
||||||
private ResultSet resultSet;
|
private ResultSet resultSet;
|
||||||
private ArrayList<GenericInsertPair> commonPairs;
|
private ArrayList<GenericInsertPair> commonPairs;
|
||||||
private ArrayList<GenericInsertPair> methodPairs;
|
private HashMap<TPHConstraint,HashSet<String>> methodConstraints;
|
||||||
|
|
||||||
public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds,ArrayList<GenericInsertPair> commonPairs) {
|
public Signature(ClassOrInterface classOrInterface, HashMap<String, String> genericsAndBounds,ArrayList<GenericInsertPair> commonPairs) {
|
||||||
this.classOrInterface = classOrInterface;
|
this.classOrInterface = classOrInterface;
|
||||||
@ -47,24 +50,26 @@ public class Signature {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Signature(Constructor constructor, HashMap<String, String> genericsAndBounds,
|
public Signature(Constructor constructor, HashMap<String, String> genericsAndBounds,
|
||||||
HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes,ResultSet resultSet,ArrayList<GenericInsertPair> methodPairs) {
|
HashMap<String,RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes,ResultSet resultSet,
|
||||||
|
HashMap<TPHConstraint,HashSet<String>> methodConstraints) {
|
||||||
this.constructor = constructor;
|
this.constructor = constructor;
|
||||||
this.genericsAndBounds = genericsAndBounds;
|
this.genericsAndBounds = genericsAndBounds;
|
||||||
this.methodParamsAndTypes = methodParamsAndTypes;
|
this.methodParamsAndTypes = methodParamsAndTypes;
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
this.methodPairs = methodPairs;
|
this.methodConstraints = methodConstraints;
|
||||||
sw = new SignatureWriter();
|
sw = new SignatureWriter();
|
||||||
createSignatureForConsOrMethod(this.constructor,true);
|
createSignatureForConsOrMethod(this.constructor,true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Signature(Method method, HashMap<String, String> genericsAndBoundsMethod,HashMap<String, String> genericsAndBounds,
|
public Signature(Method method, HashMap<String, String> genericsAndBoundsMethod,HashMap<String, String> genericsAndBounds,
|
||||||
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes, ResultSet resultSet, ArrayList<GenericInsertPair> methodPairs) {
|
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> methodParamsAndTypes, ResultSet resultSet,
|
||||||
|
HashMap<TPHConstraint,HashSet<String>> methodConstraints) {
|
||||||
this.method = method;
|
this.method = method;
|
||||||
this.genericsAndBoundsMethod = genericsAndBoundsMethod;
|
this.genericsAndBoundsMethod = genericsAndBoundsMethod;
|
||||||
this.genericsAndBounds = genericsAndBounds;
|
this.genericsAndBounds = genericsAndBounds;
|
||||||
this.methodParamsAndTypes = methodParamsAndTypes;
|
this.methodParamsAndTypes = methodParamsAndTypes;
|
||||||
this.resultSet = resultSet;
|
this.resultSet = resultSet;
|
||||||
this.methodPairs = methodPairs;
|
this.methodConstraints = methodConstraints;
|
||||||
sw = new SignatureWriter();
|
sw = new SignatureWriter();
|
||||||
createSignatureForConsOrMethod(this.method,false);
|
createSignatureForConsOrMethod(this.method,false);
|
||||||
}
|
}
|
||||||
@ -111,104 +116,39 @@ public class Signature {
|
|||||||
getBoundsOfTypeVar(g,genericsAndBoundsMethod);
|
getBoundsOfTypeVar(g,genericsAndBoundsMethod);
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: paramtrisierte Typen mit Generics, Type Variablen müssen definiert werden.
|
|
||||||
|
|
||||||
// Wenn die RückgabeType eine TPH ist, wird als generic behandelt
|
// Wenn die RückgabeType eine TPH ist, wird als generic behandelt
|
||||||
// z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object
|
// z.B: Type = TPH K => wird eine Formal Type Parameter K$ erzeugt und Bound = Object
|
||||||
if(!isConstructor) {
|
if(!isConstructor) {
|
||||||
String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature());
|
||||||
if(!ret.equals("V")) {
|
ArrayList<TPHConstraint> allConsBeforeSimplify = new ArrayList<>();
|
||||||
// TODO TypeToSignature nochmal kontrollieren und schauen ob man dort wirklich
|
|
||||||
// T... braucht und L ...
|
HashMap<TPHConstraint,HashSet<String>> allConstraints = new HashMap<>();
|
||||||
if(ret.contains("$") && !ret.contains("$$") && !ret.contains("<")) {
|
|
||||||
if(genericsAndBounds.containsKey(ret)) {
|
|
||||||
genericsAndBoundsMethod.put(ret.substring(1), genericsAndBounds.get(ret.substring(1)));
|
|
||||||
}else {
|
|
||||||
sw.visitFormalTypeParameter(ret.substring(1));
|
|
||||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
|
||||||
genericsAndBoundsMethod.put(ret.substring(1), Type.getInternalName(Object.class));
|
|
||||||
sw.visitClassBound().visitEnd();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(ret.contains("<")) {
|
if(ret.contains("<")) {
|
||||||
RefType ref = (RefType) resultSet.resolveType(method.getReturnType()).resolvedType;
|
allConsBeforeSimplify = getAllConstraints((RefType) resultSet.resolveType(method.getReturnType()).resolvedType);
|
||||||
if(hasTPHs(ref)) {
|
|
||||||
createSignatureForParameterizedType(ref);
|
|
||||||
}
|
|
||||||
System.out.println("HAS WC = " + hasWC(ref));
|
|
||||||
if(hasWC(ref))
|
|
||||||
createSigForParamTypeWithWC(ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parameters
|
|
||||||
for(String paramName : methodParamsAndTypes.keySet()) {
|
for(String paramName : methodParamsAndTypes.keySet()) {
|
||||||
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
|
RefTypeOrTPHOrWildcardOrGeneric t = methodParamsAndTypes.get(paramName);
|
||||||
String pT = t.acceptTV(new TypeToSignature());
|
String pT = t.acceptTV(new TypeToSignature());
|
||||||
// S.o
|
|
||||||
if(t instanceof TypePlaceholder) {
|
if(pT.contains("<"))
|
||||||
String gP = t.acceptTV(new TypeToSignature());
|
allConsBeforeSimplify = getAllConstraints((RefType) t);
|
||||||
if(!genericsAndBounds.containsKey(gP.substring(1)) && !genericsAndBoundsMethod.containsKey(gP.substring(1))) {
|
}
|
||||||
sw.visitFormalTypeParameter(gP.substring(1));
|
boolean doSimplify = false;
|
||||||
String bound = Type.getInternalName(Object.class);
|
if(!allConsBeforeSimplify.isEmpty()) {
|
||||||
boolean isTypeVar = false;
|
addConstraintsToMap(allConstraints,allConsBeforeSimplify);
|
||||||
for(GenericInsertPair pair : methodPairs) {
|
doSimplify = true;
|
||||||
if(pT.substring(1,pT.length()-1).equals(pair.TA1.getName())) {
|
}
|
||||||
bound = pair.TA2.getName()+"$";
|
createTypeVars(allConstraints, doSimplify);
|
||||||
isTypeVar = true;
|
|
||||||
break;
|
if(!ret.equals("V")) {
|
||||||
|
if(ret.contains("$") && !ret.contains("$$") && !ret.contains("<")) {
|
||||||
|
if(genericsAndBounds.containsKey(ret)) {
|
||||||
|
genericsAndBoundsMethod.put(ret.substring(1), genericsAndBounds.get(ret.substring(1)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isTypeVar) {
|
|
||||||
sw.visitClassBound().visitTypeVariable(bound);
|
|
||||||
}else {
|
|
||||||
sw.visitClassBound().visitClassType(bound);
|
|
||||||
sw.visitClassBound().visitEnd();
|
|
||||||
}
|
|
||||||
|
|
||||||
genericsAndBoundsMethod.put(gP.substring(1), bound);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(pT.contains("<")) {
|
|
||||||
RefType ref = (RefType) methodParamsAndTypes.get(paramName);
|
|
||||||
if(hasTPHs(ref))
|
|
||||||
createSignatureForParameterizedType(ref);
|
|
||||||
|
|
||||||
System.out.println("HAS WC = " + hasWC(ref));
|
|
||||||
if(hasWC(ref))
|
|
||||||
createSigForParamTypeWithWC(ref);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(GenericInsertPair p:methodPairs) {
|
|
||||||
String name = p.TA1.getName()+"$";
|
|
||||||
if(!genericsAndBoundsMethod.containsKey(name)) {
|
|
||||||
sw.visitFormalTypeParameter(name);
|
|
||||||
sw.visitClassBound().visitTypeVariable(p.TA2.getName()+"$");
|
|
||||||
genericsAndBoundsMethod.put(name, p.TA2.getName()+"$");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ArrayList<TypePlaceholder> types = new ArrayList<>();
|
|
||||||
ArrayList<TypePlaceholder> superTypes = new ArrayList<>();
|
|
||||||
|
|
||||||
for(GenericInsertPair p : methodPairs) {
|
|
||||||
types.add(p.TA1);
|
|
||||||
superTypes.add(p.TA2);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(GenericInsertPair p : methodPairs) {
|
|
||||||
String name = p.TA2.getName()+"$";
|
|
||||||
if(!types.contains(p.TA2) && !genericsAndBoundsMethod.containsKey(name)) {
|
|
||||||
String bound = Type.getInternalName(Object.class);
|
|
||||||
sw.visitFormalTypeParameter(name);
|
|
||||||
sw.visitClassBound().visitClassType(bound);
|
|
||||||
genericsAndBoundsMethod.put(name, bound);
|
|
||||||
sw.visitClassBound().visitEnd();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,169 +169,94 @@ public class Signature {
|
|||||||
// sw.visitEnd();
|
// sw.visitEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createSigForParamTypeWithWC(RefType ref) {
|
private void addConstraintsToMap(HashMap<TPHConstraint, HashSet<String>> allConstraints,
|
||||||
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
|
ArrayList<TPHConstraint> allConsBeforeSimplify) {
|
||||||
if(p instanceof WildcardType) {
|
for(TPHConstraint tphCons : allConsBeforeSimplify) {
|
||||||
if(((WildcardType) p).getInnerType() instanceof GenericRefType) {
|
allConstraints.put(tphCons, null);
|
||||||
String name = new TypeToSignature().visit((GenericRefType)((WildcardType) p).getInnerType());
|
|
||||||
System.out.println("NAME WC = " + name);
|
|
||||||
if(!genericsAndBoundsMethod.containsKey(name) && !genericsAndBounds.containsKey(name)) {
|
|
||||||
sw.visitFormalTypeParameter(name);
|
|
||||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
|
||||||
sw.visitClassBound().visitEnd();
|
|
||||||
genericsAndBoundsMethod.put(name, Type.getInternalName(Object.class));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
private String getEqualTPH(HashMap<TPHConstraint, HashSet<String>> methodConstraints, String tph) {
|
||||||
|
for(TPHConstraint cons : methodConstraints.keySet()) {
|
||||||
private boolean hasWC(RefType ref) {
|
if(methodConstraints.get(cons) != null) {
|
||||||
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
|
if(methodConstraints.get(cons).contains(tph)) {
|
||||||
System.out.println("HAS WCs: " + p.acceptTV(new TypeToString()));
|
return cons.getLeft();
|
||||||
System.out.println("HAS WCs: " + p.getClass());
|
|
||||||
if(p.acceptTV(new TypeToString()).contains("WC"))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void createSignatureForParameterizedType(RefType ref) {
|
|
||||||
ArrayList<GenericInsertPair> allPairs = getAllPairs(ref);
|
|
||||||
allPairs.addAll(methodPairs);
|
|
||||||
ArrayList<GenericInsertPair> simplifiedPairs = simplifyPairs(allPairs);
|
|
||||||
|
|
||||||
HashMap<String, String> names = new HashMap<>();
|
|
||||||
|
|
||||||
for(GenericInsertPair pair : simplifiedPairs) {
|
|
||||||
if(ref.getParaList().contains(pair.TA1)) {
|
|
||||||
String sub = pair.TA1.getName()+"$";
|
|
||||||
String superT = pair.TA2.getName()+"$";
|
|
||||||
names.put(sub, superT);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
return tph;
|
||||||
|
}
|
||||||
|
|
||||||
for(String sub : names.keySet()) {
|
private void createTypeVars(HashMap<TPHConstraint, HashSet<String>> allConstraints, boolean doSimplify) {
|
||||||
|
allConstraints.putAll(methodConstraints);
|
||||||
|
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> simplifiedConstraints;
|
||||||
|
if(doSimplify) {
|
||||||
|
simplifiedConstraints = Simplify.simplifyContraints(allConstraints);
|
||||||
|
}else {
|
||||||
|
simplifiedConstraints = allConstraints;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(TPHConstraint cons : simplifiedConstraints.keySet()) {
|
||||||
|
// need subst.
|
||||||
|
String sub = cons.getLeft()+"$";
|
||||||
if(!genericsAndBoundsMethod.containsKey(sub) && !genericsAndBounds.containsKey(sub)) {
|
if(!genericsAndBoundsMethod.containsKey(sub) && !genericsAndBounds.containsKey(sub)) {
|
||||||
sw.visitFormalTypeParameter(sub);
|
sw.visitFormalTypeParameter(sub);
|
||||||
String bound = names.get(sub);
|
String bound = cons.getRight();
|
||||||
sw.visitClassBound().visitTypeVariable(bound);
|
if(bound.equals(Type.getInternalName(Object.class))) {
|
||||||
|
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
||||||
|
sw.visitClassBound().visitEnd();
|
||||||
genericsAndBoundsMethod.put(sub, bound);
|
genericsAndBoundsMethod.put(sub, bound);
|
||||||
|
} else {
|
||||||
|
String boundName = bound+"$";
|
||||||
|
sw.visitClassBound().visitTypeVariable(boundName);
|
||||||
|
genericsAndBoundsMethod.put(sub, boundName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(String superT : names.values()) {
|
|
||||||
if(!names.containsKey(superT)) {
|
|
||||||
if(!genericsAndBoundsMethod.containsKey(superT) && !genericsAndBounds.containsKey(superT)) {
|
|
||||||
sw.visitFormalTypeParameter(superT);
|
|
||||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
|
||||||
sw.visitClassBound().visitEnd();
|
|
||||||
genericsAndBoundsMethod.put(superT, Type.getInternalName(Object.class));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private ArrayList<TPHConstraint> getAllConstraints(RefType ref) {
|
||||||
|
final ArrayList<TPHConstraint> res = new ArrayList<>();
|
||||||
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
|
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
|
||||||
if(p instanceof TypePlaceholder) {
|
ResolvedType resType;
|
||||||
String name = ((TypePlaceholder) p).getName() + "$";
|
if(p instanceof WildcardType) {
|
||||||
if(!genericsAndBoundsMethod.containsKey(name) && !genericsAndBounds.containsKey(name)) {
|
resType = resultSet.resolveType(((WildcardType) p).getInnerType());
|
||||||
sw.visitFormalTypeParameter(name);
|
}else {
|
||||||
sw.visitClassBound().visitClassType(Type.getInternalName(Object.class));
|
resType = resultSet.resolveType(p);
|
||||||
sw.visitClassBound().visitEnd();
|
|
||||||
genericsAndBoundsMethod.put(name, Type.getInternalName(Object.class));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ArrayList<GenericInsertPair> getAllPairs(RefType ref) {
|
RefTypeOrTPHOrWildcardOrGeneric resolved = resType.resolvedType;
|
||||||
final ArrayList<GenericInsertPair> res = new ArrayList<>();
|
|
||||||
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
|
|
||||||
RefTypeOrTPHOrWildcardOrGeneric resolved = resultSet.resolveType(p).resolvedType;
|
|
||||||
if(resolved instanceof TypePlaceholder) {
|
if(resolved instanceof TypePlaceholder) {
|
||||||
resultSet.resolveType(p).additionalGenerics.forEach(ag ->{
|
resType.additionalGenerics.forEach(ag ->{
|
||||||
if(!contains(res,ag)) {
|
TPHConstraint constr = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS);
|
||||||
res.add(ag);
|
if(!contains(res,constr)) {
|
||||||
|
res.add(constr);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
if(resolved instanceof WildcardType) {
|
||||||
|
WildcardType resWC = (WildcardType) resolved;
|
||||||
|
ResolvedType resType2 = resultSet.resolveType(resWC.getInnerType());
|
||||||
|
if(resType2.resolvedType instanceof TypePlaceholder) {
|
||||||
|
resType2.additionalGenerics.forEach(ag ->{
|
||||||
|
TPHConstraint constr = new ExtendsConstraint(ag.TA1.getName(), ag.TA2.getName(), Relation.EXTENDS);
|
||||||
|
if(!contains(res,constr)) {
|
||||||
|
res.add(constr);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
System.out.println("RES GIP === " + res.size());
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
private boolean contains(ArrayList<TPHConstraint> constraints, TPHConstraint constr) {
|
||||||
private boolean contains(ArrayList<GenericInsertPair> pairs, GenericInsertPair genPair) {
|
for(int i=0; i<constraints.size();++i) {
|
||||||
for(int i=0; i<pairs.size();++i) {
|
TPHConstraint p = constraints.get(i);
|
||||||
GenericInsertPair p = pairs.get(i);
|
if(constr.getLeft().equals(p.getLeft()) && constr.getRight().equals(p.getRight()))
|
||||||
if(p.TA1.equals(genPair.TA1) && p.TA2.equals(genPair.TA2))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
private ArrayList<GenericInsertPair> simplifyPairs(ArrayList<GenericInsertPair> allPairs) {
|
|
||||||
ArrayList<GenericInsertPair> simplifiedPairs = new ArrayList<>();
|
|
||||||
|
|
||||||
HashMap<TypePlaceholder, TypePlaceholder> subAndSuperTph = new HashMap<>();
|
|
||||||
for(GenericInsertPair p : allPairs) {
|
|
||||||
subAndSuperTph.put(p.TA1, p.TA2);
|
|
||||||
}
|
|
||||||
|
|
||||||
subAndSuperTph.forEach((k,v)->System.out.println(k.getName() + " || " + v.getName()));
|
|
||||||
|
|
||||||
int numOfVisitedPairs = 0;
|
|
||||||
for(TypePlaceholder subTph: subAndSuperTph.keySet()) {
|
|
||||||
|
|
||||||
if(numOfVisitedPairs>=subAndSuperTph.size())
|
|
||||||
break;
|
|
||||||
|
|
||||||
HashMap<Integer, TypePlaceholder> tphsInRel= new HashMap<>();
|
|
||||||
|
|
||||||
tphsInRel.put(tphsInRel.size(), subTph);
|
|
||||||
TypePlaceholder superTph = subAndSuperTph.get(subTph);
|
|
||||||
tphsInRel.put(tphsInRel.size(), superTph);
|
|
||||||
|
|
||||||
numOfVisitedPairs++;
|
|
||||||
|
|
||||||
while(subAndSuperTph.containsKey(superTph)) {
|
|
||||||
superTph = subAndSuperTph.get(superTph);
|
|
||||||
tphsInRel.put(tphsInRel.size(), superTph);
|
|
||||||
numOfVisitedPairs++;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subtype
|
|
||||||
TypePlaceholder subTphRes = tphsInRel.get(0);
|
|
||||||
// Die größte Supertype
|
|
||||||
TypePlaceholder superTphRes = tphsInRel.get(tphsInRel.size()-1);
|
|
||||||
|
|
||||||
|
|
||||||
while(subAndSuperTph.containsValue(subTphRes)) {
|
|
||||||
for(TypePlaceholder tph : subAndSuperTph.keySet()) {
|
|
||||||
if(subAndSuperTph.get(tph).equals(subTphRes)) {
|
|
||||||
subTphRes = tph;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tphsInRel.put(0, subTphRes);
|
|
||||||
numOfVisitedPairs++;
|
|
||||||
}
|
|
||||||
|
|
||||||
subTphRes = tphsInRel.get(0);
|
|
||||||
GenericInsertPair sPair = new GenericInsertPair(subTphRes, superTphRes);
|
|
||||||
simplifiedPairs.add(sPair);
|
|
||||||
}
|
|
||||||
return simplifiedPairs;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean hasTPHs(RefType ref) {
|
|
||||||
for(RefTypeOrTPHOrWildcardOrGeneric p : ref.getParaList()) {
|
|
||||||
System.out.println("HAS TPHs: " + p.acceptTV(new TypeToString()));
|
|
||||||
if(p.acceptTV(new TypeToString()).contains("WC")){
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if(resultSet.resolveType(p).resolvedType instanceof TypePlaceholder)
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -430,6 +295,7 @@ public class Signature {
|
|||||||
// das braucht man nicht es reicht: sv.visitTypeVariable(r.acceptTV(new TypeToSignature())
|
// das braucht man nicht es reicht: sv.visitTypeVariable(r.acceptTV(new TypeToSignature())
|
||||||
//
|
//
|
||||||
String sig2 = r.acceptTV(new TypeToSignature());
|
String sig2 = r.acceptTV(new TypeToSignature());
|
||||||
|
String eqTPH = getEqualTPH(methodConstraints, sig2.substring(1, sig2.length()-1))+"$";
|
||||||
if(!(r instanceof TypePlaceholder)) {
|
if(!(r instanceof TypePlaceholder)) {
|
||||||
if(sig2.contains("$$")) {
|
if(sig2.contains("$$")) {
|
||||||
System.out.println(" Signature FUN$$: "+r);
|
System.out.println(" Signature FUN$$: "+r);
|
||||||
@ -440,7 +306,7 @@ public class Signature {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature()));
|
System.out.println(r.getClass()+" Signature TPH: "+r.acceptTV(new TypeToSignature()));
|
||||||
sv.visitTypeVariable(sig2.substring(1, sig2.length()));
|
sv.visitTypeVariable(eqTPH);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
@ -34,9 +34,9 @@ public class TypeToSignature implements TypeVisitor<String> {
|
|||||||
// params += "L"+param.toString().replace(".", "/");
|
// params += "L"+param.toString().replace(".", "/");
|
||||||
// }
|
// }
|
||||||
params += param.acceptTV(new TypeToSignature());
|
params += param.acceptTV(new TypeToSignature());
|
||||||
if(!(param instanceof RefType))
|
|
||||||
|
if(param instanceof TypePlaceholder)
|
||||||
params += ";";
|
params += ";";
|
||||||
// if(it.hasNext())params += ";";
|
|
||||||
}
|
}
|
||||||
params += ">";
|
params += ">";
|
||||||
}
|
}
|
||||||
@ -48,7 +48,10 @@ public class TypeToSignature implements TypeVisitor<String> {
|
|||||||
@Override
|
@Override
|
||||||
public String visit(SuperWildcardType superWildcardType) {
|
public String visit(SuperWildcardType superWildcardType) {
|
||||||
// throw new NotImplementedException();
|
// throw new NotImplementedException();
|
||||||
return "-" + superWildcardType.getInnerType().acceptTV(new TypeToSignature());
|
String sig = "-" + superWildcardType.getInnerType().acceptTV(new TypeToSignature());
|
||||||
|
if(superWildcardType.getInnerType() instanceof TypePlaceholder)
|
||||||
|
sig += ";";
|
||||||
|
return sig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -60,7 +63,10 @@ public class TypeToSignature implements TypeVisitor<String> {
|
|||||||
@Override
|
@Override
|
||||||
public String visit(ExtendsWildcardType extendsWildcardType) {
|
public String visit(ExtendsWildcardType extendsWildcardType) {
|
||||||
// throw new NotImplementedException();
|
// throw new NotImplementedException();
|
||||||
return "+" + extendsWildcardType.getInnerType().acceptTV(new TypeToSignature());
|
String sig = "+" + extendsWildcardType.getInnerType().acceptTV(new TypeToSignature());
|
||||||
|
if(extendsWildcardType.getInnerType() instanceof TypePlaceholder)
|
||||||
|
sig += ";";
|
||||||
|
return sig;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -46,8 +46,8 @@ public class KindOfLambda implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(BinaryExpr binary) {
|
public void visit(BinaryExpr binary) {
|
||||||
// TODO Auto-generated method stub
|
binary.lexpr.accept(this);
|
||||||
|
binary.rexpr.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -82,8 +82,9 @@ public class KindOfLambda implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(IfStmt ifStmt) {
|
public void visit(IfStmt ifStmt) {
|
||||||
// TODO Auto-generated method stub
|
ifStmt.expr.accept(this);
|
||||||
|
ifStmt.then_block.accept(this);
|
||||||
|
ifStmt.else_block.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -156,9 +157,11 @@ public class KindOfLambda implements StatementVisitor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(This aThis) {
|
public void visit(This aThis) {
|
||||||
|
if(!isInstanceCapturingLambda) {
|
||||||
this.isInstanceCapturingLambda = true;
|
this.isInstanceCapturingLambda = true;
|
||||||
this.argumentList.add(aThis.getType());
|
this.argumentList.add(aThis.getType());
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visit(WhileStmt whileStmt) {
|
public void visit(WhileStmt whileStmt) {
|
||||||
|
432
src/de/dhbwstuttgart/bytecode/utilities/Simplify.java
Normal file
432
src/de/dhbwstuttgart/bytecode/utilities/Simplify.java
Normal file
@ -0,0 +1,432 @@
|
|||||||
|
package de.dhbwstuttgart.bytecode.utilities;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.bytecode.BytecodeGen.TPHExtractor;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.ExtendsConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||||
|
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint.Relation;
|
||||||
|
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||||
|
|
||||||
|
public class Simplify {
|
||||||
|
|
||||||
|
public static HashMap<TPHConstraint, HashSet<String>> simplifyConstraints(String name, TPHExtractor tphExtractor) {
|
||||||
|
// 1. check if there are any cycles like L<R and R<L:
|
||||||
|
// a) yes => set L=R and:
|
||||||
|
// * remove both constraints
|
||||||
|
// * substitute L with R in all constraint
|
||||||
|
// b)no => go to next step
|
||||||
|
// 2. check the result of step 1 if there are any equal-constraints like L=R, M=R ..
|
||||||
|
// a) yes => put all such TPhs in a map and define "key-Cons"
|
||||||
|
// -- key-Cons = TPH < Object --
|
||||||
|
// put this Constraint and the
|
||||||
|
// b) no
|
||||||
|
// 3. is
|
||||||
|
|
||||||
|
ArrayList<TPHConstraint> allCons = tphExtractor.allCons;
|
||||||
|
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
|
||||||
|
// step 1:
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
|
||||||
|
String left = c.getLeft();
|
||||||
|
String right = c.getRight();
|
||||||
|
if(c.getRel() == Relation.EXTENDS) {
|
||||||
|
TPHConstraint revCon = getReverseConstraint(allCons,left,right);
|
||||||
|
if(revCon != null) {
|
||||||
|
revCon.setRel(Relation.EQUAL);
|
||||||
|
consToRemove.add(revCon);
|
||||||
|
c.setRel(Relation.EQUAL);
|
||||||
|
substituteTPH(allCons,left, right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("NEW ALL CONST: " + allCons.size());
|
||||||
|
allCons.forEach(c->System.out.println(c.toString()));
|
||||||
|
System.out.println("----------------");
|
||||||
|
allCons.removeAll(consToRemove);
|
||||||
|
consToRemove = new ArrayList<>();
|
||||||
|
|
||||||
|
int size = allCons.size();
|
||||||
|
|
||||||
|
System.out.println("AFTER DELETE ALL CONST: " + allCons.size());
|
||||||
|
allCons.forEach(c->System.out.println(c.toString()));
|
||||||
|
System.out.println("----------------");
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
||||||
|
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
if(c.getRel()==Relation.EQUAL) {
|
||||||
|
HashSet<String> equalTPHs = getEqualsTPHs(result, c);
|
||||||
|
TPHConstraint constraint = getKeyConstraint(result,c);
|
||||||
|
equalTPHs.add(c.getLeft());
|
||||||
|
equalTPHs.add(c.getRight());
|
||||||
|
result.put(constraint, equalTPHs);
|
||||||
|
consToRemove.add(c);
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("Step 2 Result: ");
|
||||||
|
result.forEach((c,hs)->{
|
||||||
|
System.out.print(c.toString() + " -> ");
|
||||||
|
hs.forEach(s->{
|
||||||
|
System.out.print(s + ", ");
|
||||||
|
});
|
||||||
|
System.out.println();
|
||||||
|
});
|
||||||
|
System.out.println("----------------");
|
||||||
|
allCons.removeAll(consToRemove);
|
||||||
|
allCons.addAll(result.keySet());
|
||||||
|
|
||||||
|
if(!allCons.isEmpty() && allCons.size()<2) {
|
||||||
|
|
||||||
|
if(!result.containsKey(allCons.get(0)))
|
||||||
|
result.put(allCons.get(0), null);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
size += result.keySet().size();
|
||||||
|
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
if(c.getRight().equals(Type.getInternalName(Object.class)))
|
||||||
|
size--;
|
||||||
|
}
|
||||||
|
ArrayList<TypePlaceholder> methodTphs = new ArrayList<>();
|
||||||
|
for(MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) {
|
||||||
|
if(m.getName().equals(name)) {
|
||||||
|
methodTphs = m.getTphs();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
HashMap<String, String> subAndSuper = new HashMap<>();
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
if(subAndSuper.containsKey(c.getLeft())) {
|
||||||
|
LinkedList<String> all = new LinkedList<>();
|
||||||
|
all.add(c.getLeft());
|
||||||
|
String sup =c.getRight();
|
||||||
|
all.add(sup);
|
||||||
|
HashMap<String, String> ss = new HashMap<>();
|
||||||
|
for(TPHConstraint constr : allCons) {
|
||||||
|
ss.put(constr.getLeft(), constr.getRight());
|
||||||
|
}
|
||||||
|
while(ss.containsKey(sup)) {
|
||||||
|
sup = ss.get(sup);
|
||||||
|
all.add(sup);
|
||||||
|
}
|
||||||
|
if(!containTPH(methodTphs, all.getLast()))
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
subAndSuper.put(c.getLeft(), c.getRight());
|
||||||
|
}
|
||||||
|
|
||||||
|
int numOfVisitedPairs = 0;
|
||||||
|
for(String sub : subAndSuper.keySet()) {
|
||||||
|
if(isTPHInConstraint(result,sub))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(!containTPH(methodTphs,sub))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if(numOfVisitedPairs>=size)
|
||||||
|
break;
|
||||||
|
LinkedList<String> tphInRel = new LinkedList<>();
|
||||||
|
tphInRel.add(sub);
|
||||||
|
String superT = subAndSuper.get(sub);
|
||||||
|
tphInRel.add(superT);
|
||||||
|
|
||||||
|
numOfVisitedPairs++;
|
||||||
|
while(subAndSuper.containsKey(superT)) {
|
||||||
|
superT = subAndSuper.get(superT);
|
||||||
|
if(tphInRel.contains(superT)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tphInRel.add(superT);
|
||||||
|
numOfVisitedPairs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subtype
|
||||||
|
String subTphRes = tphInRel.getFirst();
|
||||||
|
// Die größte Supertype
|
||||||
|
String superTphRes = tphInRel.getLast();
|
||||||
|
|
||||||
|
while(subAndSuper.containsValue(subTphRes)) {
|
||||||
|
for(String tph : subAndSuper.keySet()) {
|
||||||
|
if(containTPH(methodTphs,tph) && subAndSuper.get(tph).equals(subTphRes)) {
|
||||||
|
subTphRes = tph;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(subTphRes.equals(tphInRel.getFirst())) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tphInRel.addFirst(subTphRes);
|
||||||
|
numOfVisitedPairs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
subTphRes = tphInRel.getFirst();
|
||||||
|
|
||||||
|
int i = 2;
|
||||||
|
while(!containTPH(methodTphs,superTphRes) && (tphInRel.size()-i) >0) {
|
||||||
|
superTphRes = tphInRel.get(tphInRel.size()-i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!containTPH(methodTphs, superTphRes)) {
|
||||||
|
result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
||||||
|
} else {
|
||||||
|
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), null);
|
||||||
|
result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(TypePlaceholder tph : methodTphs) {
|
||||||
|
if(!isTPHInConstraint(result, tph.getName())) {
|
||||||
|
result.put(new ExtendsConstraint(tph.getName(), Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("EndResult: ");
|
||||||
|
result.forEach((c,hs)->{
|
||||||
|
if(c!=null) {
|
||||||
|
System.out.print(c.toString() + " -> ");
|
||||||
|
if(hs == null) {
|
||||||
|
System.out.print(" [] ");
|
||||||
|
}else {
|
||||||
|
hs.forEach(s->{
|
||||||
|
System.out.print(s + ", ");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
});
|
||||||
|
System.out.println("----------------");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HashMap<TPHConstraint, HashSet<String>> simplifyContraints(HashMap<TPHConstraint, HashSet<String>> allConstraints) {
|
||||||
|
// 1. check if there are any cycles like L<R and R<L:
|
||||||
|
// a) yes => set L=R and:
|
||||||
|
// * remove both constraints
|
||||||
|
// * substitute L with R in all constraint
|
||||||
|
// b)no => go to next step
|
||||||
|
// 2. check the result of step 1 if there are any equal-constraints like L=R, M=R ..
|
||||||
|
// a) yes => put all such TPhs in a map and define "key-Cons"
|
||||||
|
// -- key-Cons = TPH < Object --
|
||||||
|
// put this Constraint and the
|
||||||
|
// b) no
|
||||||
|
// 3. is
|
||||||
|
ArrayList<TPHConstraint> allCons = new ArrayList<>();
|
||||||
|
for(TPHConstraint tphCons : allConstraints.keySet()) {
|
||||||
|
allCons.add(tphCons);
|
||||||
|
}
|
||||||
|
ArrayList<TPHConstraint> consToRemove = new ArrayList<>();
|
||||||
|
// step 1:
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
|
||||||
|
String left = c.getLeft();
|
||||||
|
String right = c.getRight();
|
||||||
|
if(c.getRel() == Relation.EXTENDS) {
|
||||||
|
TPHConstraint revCon = getReverseConstraint(allCons,left,right);
|
||||||
|
if(revCon != null) {
|
||||||
|
revCon.setRel(Relation.EQUAL);
|
||||||
|
consToRemove.add(revCon);
|
||||||
|
c.setRel(Relation.EQUAL);
|
||||||
|
substituteTPH(allCons,left, right);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("NEW ALL CONST: " + allCons.size());
|
||||||
|
allCons.forEach(c->System.out.println(c.toString()));
|
||||||
|
System.out.println("----------------");
|
||||||
|
allCons.removeAll(consToRemove);
|
||||||
|
consToRemove = new ArrayList<>();
|
||||||
|
|
||||||
|
// int size = allCons.size();
|
||||||
|
|
||||||
|
System.out.println("AFTER DELETE ALL CONST: " + allCons.size());
|
||||||
|
allCons.forEach(c->System.out.println(c.toString()));
|
||||||
|
System.out.println("----------------");
|
||||||
|
HashMap<TPHConstraint, HashSet<String>> result = new HashMap<>();
|
||||||
|
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
if(c.getRel()==Relation.EQUAL) {
|
||||||
|
HashSet<String> equalTPHs = getEqualsTPHs(result, c);
|
||||||
|
TPHConstraint constraint = getKeyConstraint(result,c);
|
||||||
|
equalTPHs.add(c.getLeft());
|
||||||
|
equalTPHs.add(c.getRight());
|
||||||
|
result.put(constraint, equalTPHs);
|
||||||
|
consToRemove.add(c);
|
||||||
|
// size--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println("Step 2 Result: ");
|
||||||
|
result.forEach((c,hs)->{
|
||||||
|
System.out.print(c.toString() + " -> ");
|
||||||
|
hs.forEach(s->{
|
||||||
|
System.out.print(s + ", ");
|
||||||
|
});
|
||||||
|
System.out.println();
|
||||||
|
});
|
||||||
|
System.out.println("----------------");
|
||||||
|
allCons.removeAll(consToRemove);
|
||||||
|
allCons.addAll(result.keySet());
|
||||||
|
|
||||||
|
if(!allCons.isEmpty() && allCons.size()<2) {
|
||||||
|
|
||||||
|
if(!result.containsKey(allCons.get(0)))
|
||||||
|
result.put(allCons.get(0), null);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// size += result.keySet().size();
|
||||||
|
|
||||||
|
// for(TPHConstraint c : allCons) {
|
||||||
|
// if(c.getRight().equals(Type.getInternalName(Object.class)))
|
||||||
|
// size--;
|
||||||
|
// }
|
||||||
|
|
||||||
|
HashMap<String, String> subAndSuper = new HashMap<>();
|
||||||
|
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
subAndSuper.put(c.getLeft(), c.getRight());
|
||||||
|
}
|
||||||
|
|
||||||
|
// int numOfVisitedPairs = 0;
|
||||||
|
for(String sub : subAndSuper.keySet()) {
|
||||||
|
if(isTPHInConstraint(result,sub))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// if(numOfVisitedPairs>=size)
|
||||||
|
// break;
|
||||||
|
|
||||||
|
LinkedList<String> tphInRel = new LinkedList<>();
|
||||||
|
tphInRel.add(sub);
|
||||||
|
String superT = subAndSuper.get(sub);
|
||||||
|
tphInRel.add(superT);
|
||||||
|
|
||||||
|
// numOfVisitedPairs++;
|
||||||
|
while(subAndSuper.containsKey(superT)) {
|
||||||
|
superT = subAndSuper.get(superT);
|
||||||
|
if(tphInRel.contains(superT)) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tphInRel.add(superT);
|
||||||
|
// numOfVisitedPairs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subtype
|
||||||
|
String subTphRes = tphInRel.getFirst();
|
||||||
|
// Die größte Supertype
|
||||||
|
String superTphRes = tphInRel.getLast();
|
||||||
|
|
||||||
|
while(subAndSuper.containsValue(subTphRes)) {
|
||||||
|
for(String tph : subAndSuper.keySet()) {
|
||||||
|
if(subAndSuper.get(tph).equals(subTphRes)) {
|
||||||
|
subTphRes = tph;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(subTphRes.equals(tphInRel.getFirst())) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tphInRel.addFirst(subTphRes);
|
||||||
|
// numOfVisitedPairs++;
|
||||||
|
}
|
||||||
|
|
||||||
|
subTphRes = tphInRel.getFirst();
|
||||||
|
|
||||||
|
int i = 2;
|
||||||
|
while(superTphRes.equals(Type.getInternalName(Object.class)) && (tphInRel.size()-i) >0) {
|
||||||
|
superTphRes = tphInRel.get(tphInRel.size()-i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
if(superTphRes.equals(Type.getInternalName(Object.class))) {
|
||||||
|
result.put(new ExtendsConstraint(subTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
||||||
|
} else {
|
||||||
|
result.put(new ExtendsConstraint(subTphRes, superTphRes, Relation.EXTENDS), null);
|
||||||
|
result.put(new ExtendsConstraint(superTphRes, Type.getInternalName(Object.class), Relation.EXTENDS), null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
System.out.println("EndResult: ");
|
||||||
|
result.forEach((c,hs)->{
|
||||||
|
if(c!=null) {
|
||||||
|
System.out.print(c.toString() + " -> ");
|
||||||
|
if(hs == null) {
|
||||||
|
System.out.print(" [] ");
|
||||||
|
}else {
|
||||||
|
hs.forEach(s->{
|
||||||
|
System.out.print(s + ", ");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
System.out.println();
|
||||||
|
});
|
||||||
|
System.out.println("----------------");
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void substituteTPH(ArrayList<TPHConstraint> allCons,String left ,String right) {
|
||||||
|
allCons.forEach(c->{
|
||||||
|
if(c.getRel() == Relation.EXTENDS) {
|
||||||
|
if(c.getLeft().equals(left))
|
||||||
|
c.setLeft(right);
|
||||||
|
if(c.getRight().equals(left))
|
||||||
|
c.setRight(right);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TPHConstraint getReverseConstraint(ArrayList<TPHConstraint> allCons, String left, String right) {
|
||||||
|
for(TPHConstraint c : allCons) {
|
||||||
|
if(c.getLeft().equals(right) && c.getRight().equals(left)){
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean isTPHInConstraint(HashMap<TPHConstraint, HashSet<String>> result, String sub) {
|
||||||
|
for(TPHConstraint c : result.keySet()) {
|
||||||
|
if(c.getLeft().equals(sub))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean containTPH(ArrayList<TypePlaceholder> methodTphs, String sub) {
|
||||||
|
for(TypePlaceholder tph : methodTphs) {
|
||||||
|
if(tph.getName().equals(sub))
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TPHConstraint getKeyConstraint(HashMap<TPHConstraint, HashSet<String>> result, TPHConstraint toFind) {
|
||||||
|
for(TPHConstraint c : result.keySet()) {
|
||||||
|
if(c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight()))
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
return new ExtendsConstraint(toFind.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static HashSet<String> getEqualsTPHs(HashMap<TPHConstraint,HashSet<String>> result, TPHConstraint toFind) {
|
||||||
|
for(TPHConstraint c : result.keySet()) {
|
||||||
|
if(c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight()))
|
||||||
|
return result.get(c);
|
||||||
|
}
|
||||||
|
return new HashSet<>();
|
||||||
|
}
|
||||||
|
}
|
@ -26,14 +26,17 @@ import de.dhbwstuttgart.typeinference.unify.RuleSet;
|
|||||||
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
|
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
|
||||||
import de.dhbwstuttgart.typeinference.unify.distributeVariance;
|
import de.dhbwstuttgart.typeinference.unify.distributeVariance;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
|
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.TypeUnifyTask;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileOutputStream;
|
import java.io.FileOutputStream;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
@ -79,10 +82,16 @@ public class JavaTXCompiler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
|
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
|
||||||
List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
|
//PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal hinzugefuegt werden
|
||||||
|
//List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
|
||||||
|
Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||||
|
|
||||||
|
/* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt
|
||||||
for (SourceFile sf : sourceFiles.values()) {
|
for (SourceFile sf : sourceFiles.values()) {
|
||||||
allClasses.addAll(sf.getClasses());
|
allClasses.addAll(sf.getClasses());
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
List<ClassOrInterface> importedClasses = new ArrayList<>();
|
List<ClassOrInterface> importedClasses = new ArrayList<>();
|
||||||
for (JavaClassName name : forSourceFile.getImports()) {
|
for (JavaClassName name : forSourceFile.getImports()) {
|
||||||
//TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
|
//TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
|
||||||
@ -91,7 +100,7 @@ public class JavaTXCompiler {
|
|||||||
importedClasses.add(importedClass);
|
importedClasses.add(importedClass);
|
||||||
allClasses.addAll(importedClasses);
|
allClasses.addAll(importedClasses);
|
||||||
}
|
}
|
||||||
return allClasses;
|
return new ArrayList<>(allClasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<ResultSet> typeInference() throws ClassNotFoundException {
|
public List<ResultSet> typeInference() throws ClassNotFoundException {
|
||||||
@ -127,6 +136,10 @@ public class JavaTXCompiler {
|
|||||||
Set<String> returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder)
|
Set<String> returnTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder)
|
||||||
.map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get();
|
.map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get();
|
||||||
|
|
||||||
|
Set<String> fieldTypeVarNames = allClasses.stream().map(x -> x.getFieldDecl().stream().filter(y -> y.getReturnType() instanceof TypePlaceholder)
|
||||||
|
.map(z -> ((TypePlaceholder)z.getReturnType()).getName()).collect(Collectors.toCollection(HashSet::new))).reduce((a,b) -> { a.addAll(b); return a;} ).get();
|
||||||
|
|
||||||
|
returnTypeVarNames.addAll(fieldTypeVarNames);
|
||||||
|
|
||||||
xConsSet = xConsSet.stream().map(x -> {
|
xConsSet = xConsSet.stream().map(x -> {
|
||||||
//Hier muss ueberlegt werden, ob
|
//Hier muss ueberlegt werden, ob
|
||||||
@ -156,7 +169,9 @@ public class JavaTXCompiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return x;//HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE JEWEILS ANDERE SEITE
|
return x;//HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE JEWEILS ANDERE SEITE
|
||||||
}).map( y -> {
|
})
|
||||||
|
/* PL 2018-11-07 wird in varianceInheritance erledigt
|
||||||
|
.map( y -> {
|
||||||
if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) {
|
if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) {
|
||||||
if (((PlaceholderType)y.getLhsType()).getVariance() != 0 && ((PlaceholderType)y.getRhsType()).getVariance() == 0) {
|
if (((PlaceholderType)y.getLhsType()).getVariance() != 0 && ((PlaceholderType)y.getRhsType()).getVariance() == 0) {
|
||||||
((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType()).getVariance());
|
((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType()).getVariance());
|
||||||
@ -166,6 +181,7 @@ public class JavaTXCompiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return y; } )
|
return y; } )
|
||||||
|
*/
|
||||||
.collect(Collectors.toCollection(HashSet::new));
|
.collect(Collectors.toCollection(HashSet::new));
|
||||||
varianceInheritance(xConsSet);
|
varianceInheritance(xConsSet);
|
||||||
Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure);
|
Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure);
|
||||||
@ -173,8 +189,17 @@ public class JavaTXCompiler {
|
|||||||
System.out.println("RESULT: " + result);
|
System.out.println("RESULT: " + result);
|
||||||
results.addAll(result);
|
results.addAll(result);
|
||||||
}
|
}
|
||||||
|
results = results.stream().map(x -> {
|
||||||
|
Optional<Set<UnifyPair>> res = new RuleSet().subst(x.stream().map(y -> {
|
||||||
|
if (y.getPairOp() == PairOperator.SMALLERDOTWC) y.setPairOp(PairOperator.EQUALSDOT);
|
||||||
|
return y; //alle Paare a <.? b erden durch a =. b ersetzt
|
||||||
|
}).collect(Collectors.toCollection(HashSet::new)));
|
||||||
|
if (res.isPresent()) {//wenn subst ein Erg liefert wurde was veraendert
|
||||||
|
return new TypeUnifyTask().applyTypeUnificationRules(res.get(), finiteClosure);
|
||||||
|
}
|
||||||
|
else return x; //wenn nichts veraendert wurde wird x zurueckgegeben
|
||||||
|
}).collect(Collectors.toCollection(HashSet::new));
|
||||||
|
System.out.println("RESULT Final: " + results);
|
||||||
return results.stream().map((unifyPairs ->
|
return results.stream().map((unifyPairs ->
|
||||||
new ResultSet(UnifyTypeFactory.convert(unifyPairs, generateTPHMap(cons))))).collect(Collectors.toList());
|
new ResultSet(UnifyTypeFactory.convert(unifyPairs, generateTPHMap(cons))))).collect(Collectors.toList());
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,8 @@ import de.dhbwstuttgart.typeinference.unify.model.*;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.antlr.v4.runtime.Token;
|
||||||
|
|
||||||
public class FCGenerator {
|
public class FCGenerator {
|
||||||
/**
|
/**
|
||||||
* Baut die FiniteClosure aus availableClasses.
|
* Baut die FiniteClosure aus availableClasses.
|
||||||
@ -26,12 +28,19 @@ public class FCGenerator {
|
|||||||
|
|
||||||
public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
|
public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
|
||||||
HashSet<Pair> pairs = new HashSet<>();
|
HashSet<Pair> pairs = new HashSet<>();
|
||||||
|
//PL 2018-09-18: gtvs vor die for-Schleife gezogen, damit immer die gleichen Typeplaceholder eingesetzt werden.
|
||||||
|
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs = new HashMap<>();
|
||||||
for(ClassOrInterface cly : availableClasses){
|
for(ClassOrInterface cly : availableClasses){
|
||||||
pairs.addAll(getSuperTypes(cly, availableClasses));
|
pairs.addAll(getSuperTypes(cly, availableClasses, gtvs));
|
||||||
}
|
}
|
||||||
return pairs;
|
return pairs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Bildet eine Kette vom übergebenen Typ bis hin zum höchsten bekannten Typ
|
* Bildet eine Kette vom übergebenen Typ bis hin zum höchsten bekannten Typ
|
||||||
* Als Generics werden TPHs benutzt, welche der Unifikationsalgorithmus korrekt interpretieren muss.
|
* Als Generics werden TPHs benutzt, welche der Unifikationsalgorithmus korrekt interpretieren muss.
|
||||||
|
@ -21,12 +21,14 @@ import java.util.*;
|
|||||||
public class StatementGenerator {
|
public class StatementGenerator {
|
||||||
|
|
||||||
private JavaClassRegistry reg;
|
private JavaClassRegistry reg;
|
||||||
|
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields; //PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH bekommen
|
||||||
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars;
|
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars;
|
||||||
private GenericsRegistry generics;
|
private GenericsRegistry generics;
|
||||||
|
|
||||||
public StatementGenerator(JavaClassRegistry reg, GenericsRegistry generics, Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars){
|
public StatementGenerator(JavaClassRegistry reg, GenericsRegistry generics, Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields, Map<String, RefTypeOrTPHOrWildcardOrGeneric> localVars){
|
||||||
this.reg = reg;
|
this.reg = reg;
|
||||||
this.generics = generics;
|
this.generics = generics;
|
||||||
|
this.fields = fields;
|
||||||
this.localVars = localVars;
|
this.localVars = localVars;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,9 +240,14 @@ public class StatementGenerator {
|
|||||||
if(localVars.get(expression) != null){
|
if(localVars.get(expression) != null){
|
||||||
return new LocalVar(expression, localVars.get(expression), offset);
|
return new LocalVar(expression, localVars.get(expression), offset);
|
||||||
}else{
|
}else{
|
||||||
|
if(fields.get(expression) != null){//PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH bekommen
|
||||||
|
return new FieldVar(new This(offset), expression, fields.get(expression), offset);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
//kann eigentlich nicht vorkommen
|
||||||
//Dann Muss es ein Feld sein!
|
//Dann Muss es ein Feld sein!
|
||||||
return new FieldVar(new This(offset), expression, TypePlaceholder.fresh(offset), offset);
|
return new FieldVar(new This(offset), expression, TypePlaceholder.fresh(offset), offset);
|
||||||
}
|
}}
|
||||||
}
|
}
|
||||||
return generateFieldVarOrClassname(expression, offset);
|
return generateFieldVarOrClassname(expression, offset);
|
||||||
}
|
}
|
||||||
@ -818,8 +825,12 @@ public class StatementGenerator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Expression convert(Java8Parser.LiteralContext literal) {
|
private Expression convert(Java8Parser.LiteralContext literal) {
|
||||||
if(literal.IntegerLiteral() != null || literal.FloatingPointLiteral()!= null){
|
if(literal.IntegerLiteral() != null){
|
||||||
Number value = Double.parseDouble(literal.IntegerLiteral().getText());
|
Number value = Integer.parseInt(literal.IntegerLiteral().getText());
|
||||||
|
return new Literal(TypePlaceholder.fresh(literal.getStart()),
|
||||||
|
value, literal.getStart());
|
||||||
|
} else if(literal.FloatingPointLiteral()!= null){
|
||||||
|
Number value = Double.parseDouble(literal.FloatingPointLiteral().getText());
|
||||||
return new Literal(TypePlaceholder.fresh(literal.getStart()),
|
return new Literal(TypePlaceholder.fresh(literal.getStart()),
|
||||||
value, literal.getStart());
|
value, literal.getStart());
|
||||||
}else if(literal.BooleanLiteral() != null){
|
}else if(literal.BooleanLiteral() != null){
|
||||||
@ -892,7 +903,7 @@ public class StatementGenerator {
|
|||||||
for(FormalParameter param : params.getFormalparalist()){
|
for(FormalParameter param : params.getFormalparalist()){
|
||||||
lambdaLocals.put(param.getName(), param.getType());
|
lambdaLocals.put(param.getName(), param.getType());
|
||||||
}
|
}
|
||||||
StatementGenerator lambdaGenerator = new StatementGenerator(reg, generics, lambdaLocals);
|
StatementGenerator lambdaGenerator = new StatementGenerator(reg, generics, fields, lambdaLocals);
|
||||||
|
|
||||||
Block block;
|
Block block;
|
||||||
if(expression.lambdaBody().expression() != null){
|
if(expression.lambdaBody().expression() != null){
|
||||||
|
@ -33,6 +33,7 @@ public class SyntaxTreeGenerator{
|
|||||||
private final GenericsRegistry globalGenerics;
|
private final GenericsRegistry globalGenerics;
|
||||||
private String pkgName = "";
|
private String pkgName = "";
|
||||||
Set<JavaClassName> imports = new HashSet();
|
Set<JavaClassName> imports = new HashSet();
|
||||||
|
private Map<String, RefTypeOrTPHOrWildcardOrGeneric> fields = new HashMap<>(); //PL 2018-11-01 fields eingefuegt, damit die fields immer die gleiche TPH bekommen
|
||||||
|
|
||||||
List<Statement> fieldInitializations = new ArrayList<>();
|
List<Statement> fieldInitializations = new ArrayList<>();
|
||||||
|
|
||||||
@ -122,7 +123,7 @@ public class SyntaxTreeGenerator{
|
|||||||
private Method convert(int modifiers, Java8Parser.MethodHeaderContext header, Java8Parser.MethodBodyContext body,
|
private Method convert(int modifiers, Java8Parser.MethodHeaderContext header, Java8Parser.MethodBodyContext body,
|
||||||
JavaClassName parentClass, RefType superClass, GenericsRegistry localGenerics) {
|
JavaClassName parentClass, RefType superClass, GenericsRegistry localGenerics) {
|
||||||
|
|
||||||
StatementGenerator stmtGen = new StatementGenerator(reg, localGenerics, new HashMap<>());
|
StatementGenerator stmtGen = new StatementGenerator(reg, localGenerics, fields, new HashMap<>());
|
||||||
|
|
||||||
String name = header.methodDeclarator().Identifier().getText();
|
String name = header.methodDeclarator().Identifier().getText();
|
||||||
GenericDeclarationList gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), header.getStart());
|
GenericDeclarationList gtvDeclarations = new GenericDeclarationList(new ArrayList<>(), header.getStart());
|
||||||
@ -346,6 +347,7 @@ public class SyntaxTreeGenerator{
|
|||||||
}
|
}
|
||||||
for(Java8Parser.VariableDeclaratorContext varCtx : fieldDeclarationContext.variableDeclaratorList().variableDeclarator()){
|
for(Java8Parser.VariableDeclaratorContext varCtx : fieldDeclarationContext.variableDeclaratorList().variableDeclarator()){
|
||||||
String fieldName = convert(varCtx.variableDeclaratorId());
|
String fieldName = convert(varCtx.variableDeclaratorId());
|
||||||
|
fields.put(fieldName, fieldType);
|
||||||
if(varCtx.variableInitializer() != null){
|
if(varCtx.variableInitializer() != null){
|
||||||
initializeField(varCtx, fieldType, generics);
|
initializeField(varCtx, fieldType, generics);
|
||||||
}
|
}
|
||||||
@ -360,7 +362,7 @@ public class SyntaxTreeGenerator{
|
|||||||
|
|
||||||
// Initialize a field by creating implicit constructor.
|
// Initialize a field by creating implicit constructor.
|
||||||
private void initializeField(Java8Parser.VariableDeclaratorContext ctx, RefTypeOrTPHOrWildcardOrGeneric typeOfField, GenericsRegistry generics){
|
private void initializeField(Java8Parser.VariableDeclaratorContext ctx, RefTypeOrTPHOrWildcardOrGeneric typeOfField, GenericsRegistry generics){
|
||||||
StatementGenerator statementGenerator = new StatementGenerator(reg, generics, new HashMap<>());
|
StatementGenerator statementGenerator = new StatementGenerator(reg, generics, fields, new HashMap<>());
|
||||||
fieldInitializations.add(statementGenerator.generateFieldAssignment(ctx, typeOfField));
|
fieldInitializations.add(statementGenerator.generateFieldAssignment(ctx, typeOfField));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,4 +15,5 @@ public abstract class RefTypeOrTPHOrWildcardOrGeneric extends SyntaxTreeNode{
|
|||||||
|
|
||||||
public abstract <A> A acceptTV(TypeVisitor<A> visitor);
|
public abstract <A> A acceptTV(TypeVisitor<A> visitor);
|
||||||
public abstract void accept(ResultSetVisitor visitor);
|
public abstract void accept(ResultSetVisitor visitor);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -59,6 +59,7 @@ public class TypePlaceholder extends RefTypeOrTPHOrWildcardOrGeneric
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
return "TPH " + this.name;
|
return "TPH " + this.name;
|
||||||
|
@ -23,4 +23,8 @@ public abstract class ResultPair<A extends RefTypeOrTPHOrWildcardOrGeneric,B ext
|
|||||||
public B getRight() {
|
public B getRight() {
|
||||||
return right;
|
return right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "(" + left.toString() + ", " + right.toString() + ")";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,10 @@ public class ResultSet {
|
|||||||
|
|
||||||
//TODO Beim Einsetzen eines Generics, müssen die new und Methodenaufrufe verändert werden
|
//TODO Beim Einsetzen eines Generics, müssen die new und Methodenaufrufe verändert werden
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return results.toString();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class Resolver implements ResultSetVisitor {
|
class Resolver implements ResultSetVisitor {
|
||||||
@ -44,6 +48,7 @@ class Resolver implements ResultSetVisitor {
|
|||||||
public ResolvedType resolve(TypePlaceholder tph){
|
public ResolvedType resolve(TypePlaceholder tph){
|
||||||
toResolve = tph;
|
toResolve = tph;
|
||||||
resolved = null;
|
resolved = null;
|
||||||
|
System.out.println(tph.toString());
|
||||||
for(ResultPair resultPair : result.results){
|
for(ResultPair resultPair : result.results){
|
||||||
if(resultPair instanceof PairTPHEqualTPH && ((PairTPHEqualTPH) resultPair).getLeft().equals(toResolve)){
|
if(resultPair instanceof PairTPHEqualTPH && ((PairTPHEqualTPH) resultPair).getLeft().equals(toResolve)){
|
||||||
return resolve(((PairTPHEqualTPH) resultPair).getRight());
|
return resolve(((PairTPHEqualTPH) resultPair).getRight());
|
||||||
@ -109,6 +114,8 @@ class Resolver implements ResultSetVisitor {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -4,6 +4,7 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
|
|||||||
import de.dhbwstuttgart.exceptions.TypeinferenceException;
|
import de.dhbwstuttgart.exceptions.TypeinferenceException;
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
import de.dhbwstuttgart.parser.NullToken;
|
||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
|
||||||
|
import de.dhbwstuttgart.parser.scope.JavaClassName;
|
||||||
import de.dhbwstuttgart.syntaxtree.*;
|
import de.dhbwstuttgart.syntaxtree.*;
|
||||||
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
|
||||||
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
import de.dhbwstuttgart.syntaxtree.factory.NameGenerator;
|
||||||
@ -18,6 +19,7 @@ import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
|||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
public class TYPEStmt implements StatementVisitor{
|
public class TYPEStmt implements StatementVisitor{
|
||||||
|
|
||||||
@ -370,12 +372,86 @@ public class TYPEStmt implements StatementVisitor{
|
|||||||
//PL 2018-06-23 Sie haben einen Typ. Der muesste hier eingefuegt werden
|
//PL 2018-06-23 Sie haben einen Typ. Der muesste hier eingefuegt werden
|
||||||
//wie hier fuer double gezeigt. Im Momment auskommentiert, weil zu wenige Literaltypen
|
//wie hier fuer double gezeigt. Im Momment auskommentiert, weil zu wenige Literaltypen
|
||||||
//funktionieren
|
//funktionieren
|
||||||
//if (literal.value instanceof Double) {
|
if (literal.value instanceof Short) {
|
||||||
// constraintsSet.addUndConstraint(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT));
|
constraintsSet.addUndConstraint(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT));
|
||||||
//}
|
return;
|
||||||
//else {
|
}
|
||||||
// throw new NotImplementedException();
|
if (literal.value instanceof Byte) {
|
||||||
//}
|
constraintsSet.addUndConstraint(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (literal.value instanceof Float) {
|
||||||
|
constraintsSet.addUndConstraint(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (literal.value instanceof Double) {
|
||||||
|
constraintsSet.addUndConstraint(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (literal.value instanceof Long) {
|
||||||
|
constraintsSet.addUndConstraint(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (literal.value instanceof Integer) {
|
||||||
|
//constraintsSet.addUndConstraint(new Pair(literal.getType(),integer, PairOperator.EQUALSDOT));
|
||||||
|
// /*
|
||||||
|
HashSet<JavaClassName> clNames = info.getAvailableClasses().stream().map(x -> x.getClassName()).collect(Collectors.toCollection(HashSet::new));
|
||||||
|
Set<Constraint> oderConstraints = new HashSet<>();
|
||||||
|
Constraint constraint = new Constraint();
|
||||||
|
constraint.add(new Pair(literal.getType(), integer, PairOperator.EQUALSDOT));
|
||||||
|
oderConstraints.add(constraint);
|
||||||
|
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Double")).findAny().isPresent()) {
|
||||||
|
constraint = new Constraint();
|
||||||
|
constraint.add(new Pair(literal.getType(), doublee, PairOperator.EQUALSDOT));
|
||||||
|
oderConstraints.add(constraint);
|
||||||
|
}
|
||||||
|
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Long")).findAny().isPresent()) {
|
||||||
|
constraint = new Constraint();
|
||||||
|
constraint.add(new Pair(literal.getType(), longg, PairOperator.EQUALSDOT));
|
||||||
|
oderConstraints.add(constraint);
|
||||||
|
}
|
||||||
|
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Float")).findAny().isPresent()) {
|
||||||
|
constraint = new Constraint();
|
||||||
|
constraint.add(new Pair(literal.getType(), floatt, PairOperator.EQUALSDOT));
|
||||||
|
oderConstraints.add(constraint);
|
||||||
|
}
|
||||||
|
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Short")).findAny().isPresent()) {
|
||||||
|
constraint = new Constraint();
|
||||||
|
constraint.add(new Pair(literal.getType(), shortt, PairOperator.EQUALSDOT));
|
||||||
|
oderConstraints.add(constraint);
|
||||||
|
}
|
||||||
|
if (clNames.stream().filter(x -> x.toString().equals("java.lang.Byte")).findAny().isPresent()) {
|
||||||
|
constraint = new Constraint();
|
||||||
|
constraint.add(new Pair(literal.getType(), bytee, PairOperator.EQUALSDOT));
|
||||||
|
oderConstraints.add(constraint);
|
||||||
|
}
|
||||||
|
constraintsSet.addOderConstraint(oderConstraints);
|
||||||
|
// */
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (literal.value instanceof Short) {
|
||||||
|
constraintsSet.addUndConstraint(new Pair(literal.getType(),shortt, PairOperator.EQUALSDOT));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (literal.value instanceof Byte) {
|
||||||
|
constraintsSet.addUndConstraint(new Pair(literal.getType(),bytee, PairOperator.EQUALSDOT));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (literal.value instanceof Float) {
|
||||||
|
constraintsSet.addUndConstraint(new Pair(literal.getType(),floatt, PairOperator.EQUALSDOT));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (literal.value instanceof String) {
|
||||||
|
constraintsSet.addUndConstraint(new Pair(literal.getType(),string, PairOperator.EQUALSDOT));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (literal.value instanceof Boolean) {
|
||||||
|
constraintsSet.addUndConstraint(new Pair(literal.getType(),bool, PairOperator.EQUALSDOT));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -445,6 +521,8 @@ public class TYPEStmt implements StatementVisitor{
|
|||||||
@Override
|
@Override
|
||||||
public void visit(AssignToField assignLeftSide) {
|
public void visit(AssignToField assignLeftSide) {
|
||||||
//Hier ist kein Code nötig. Es werden keine extra Constraints generiert
|
//Hier ist kein Code nötig. Es werden keine extra Constraints generiert
|
||||||
|
//HIER muss Code rein PL 2018-10-24
|
||||||
|
assignLeftSide.field.accept(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -474,7 +552,9 @@ public class TYPEStmt implements StatementVisitor{
|
|||||||
|
|
||||||
RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset());
|
RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset());
|
||||||
*/
|
*/
|
||||||
methodConstraint.add(new Pair(forMethod.receiver.getType(), assumption.getReceiverType(resolver),
|
|
||||||
|
RefTypeOrTPHOrWildcardOrGeneric retType = assumption.getReceiverType(resolver);
|
||||||
|
methodConstraint.add(new Pair(forMethod.receiver.getType(), retType,
|
||||||
PairOperator.SMALLERDOT));
|
PairOperator.SMALLERDOT));
|
||||||
methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(),
|
methodConstraint.add(new Pair(assumption.getReturnType(resolver), forMethod.getType(),
|
||||||
PairOperator.EQUALSDOT));
|
PairOperator.EQUALSDOT));
|
||||||
|
@ -36,7 +36,7 @@ import java.io.IOException;
|
|||||||
*/
|
*/
|
||||||
public class RuleSet implements IRuleSet{
|
public class RuleSet implements IRuleSet{
|
||||||
|
|
||||||
RuleSet() {
|
public RuleSet() {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -776,11 +776,18 @@ public class RuleSet implements IRuleSet{
|
|||||||
return Optional.empty();
|
return Optional.empty();
|
||||||
|
|
||||||
Set<UnifyPair> result = new HashSet<UnifyPair>();
|
Set<UnifyPair> result = new HashSet<UnifyPair>();
|
||||||
|
if (pair.getPairOp() == PairOperator.SMALLERDOT) {
|
||||||
result.add(new UnifyPair(funNLhsType.getTypeParams().get(funNLhsType.getTypeParams().size()-1), funNRhsType.getTypeParams().get(funNRhsType.getTypeParams().size()-1), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
result.add(new UnifyPair(funNLhsType.getTypeParams().get(funNLhsType.getTypeParams().size()-1), funNRhsType.getTypeParams().get(funNRhsType.getTypeParams().size()-1), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||||
for(int i = 0; i < funNLhsType.getTypeParams().size()-1; i++) {
|
for(int i = 0; i < funNLhsType.getTypeParams().size()-1; i++) {
|
||||||
result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), funNLhsType.getTypeParams().get(i), PairOperator.SMALLERDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
else {// pair.getPairOp() == PairOperator.EQUALDOT
|
||||||
|
result.add(new UnifyPair(funNLhsType.getTypeParams().get(funNLhsType.getTypeParams().size()-1), funNRhsType.getTypeParams().get(funNRhsType.getTypeParams().size()-1), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||||
|
for(int i = 0; i < funNLhsType.getTypeParams().size()-1; i++) {
|
||||||
|
result.add(new UnifyPair(funNRhsType.getTypeParams().get(i), funNLhsType.getTypeParams().get(i), PairOperator.EQUALSDOT, pair.getSubstitution(), pair.getBasePair()));
|
||||||
|
}
|
||||||
|
}
|
||||||
result.stream().forEach(x -> { UnifyType l = x.getLhsType();
|
result.stream().forEach(x -> { UnifyType l = x.getLhsType();
|
||||||
if (l instanceof PlaceholderType) { ((PlaceholderType)l).disableWildcardtable(); }
|
if (l instanceof PlaceholderType) { ((PlaceholderType)l).disableWildcardtable(); }
|
||||||
UnifyType r = x.getRhsType();
|
UnifyType r = x.getRhsType();
|
||||||
|
@ -23,14 +23,17 @@ import de.dhbwstuttgart.typeinference.unify.interfaces.IRuleSet;
|
|||||||
import de.dhbwstuttgart.typeinference.unify.interfaces.ISetOperations;
|
import de.dhbwstuttgart.typeinference.unify.interfaces.ISetOperations;
|
||||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
|
import de.dhbwstuttgart.typeinference.unify.interfaces.IUnify;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
|
import de.dhbwstuttgart.typeinference.unify.model.ExtendsType;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.model.FunNType;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
import de.dhbwstuttgart.typeinference.unify.model.PairOperator;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
|
import de.dhbwstuttgart.typeinference.unify.model.PlaceholderType;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.model.ReferenceType;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.SuperType;
|
import de.dhbwstuttgart.typeinference.unify.model.SuperType;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
|
import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.Unifier;
|
import de.dhbwstuttgart.typeinference.unify.model.Unifier;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
import de.dhbwstuttgart.typeinference.unify.model.UnifyPair;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.OrderingUnifyPair;
|
import de.dhbwstuttgart.typeinference.unify.model.OrderingUnifyPair;
|
||||||
|
import de.dhbwstuttgart.typeinference.unify.model.Pair;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.FileWriter;
|
import java.io.FileWriter;
|
||||||
@ -79,7 +82,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
|||||||
|
|
||||||
Integer noAllErasedElements = 0;
|
Integer noAllErasedElements = 0;
|
||||||
|
|
||||||
Integer noBacktracking = 0;
|
static int noBacktracking;
|
||||||
|
|
||||||
public TypeUnifyTask() {
|
public TypeUnifyTask() {
|
||||||
rules = new RuleSet();
|
rules = new RuleSet();
|
||||||
@ -500,7 +503,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
|||||||
|
|
||||||
/* auskommentiert um alle Max und min Betrachtung auszuschalten ANFANG */
|
/* auskommentiert um alle Max und min Betrachtung auszuschalten ANFANG */
|
||||||
if (!result.isEmpty() && !isUndefinedPairSetSet(res)) {
|
if (!result.isEmpty() && !isUndefinedPairSetSet(res)) {
|
||||||
if (nextSetasList.iterator().hasNext() && nextSetasList.iterator().next().stream().filter(x -> x.getLhsType().getName().equals("D")).findFirst().isPresent() && nextSetasList.size()>1)
|
if (nextSetasList.iterator().hasNext() && nextSetasList.iterator().next().stream().filter(x -> x.getLhsType().getName().equals("B")).findFirst().isPresent() && nextSetasList.size()>1)
|
||||||
System.out.print("");
|
System.out.print("");
|
||||||
Iterator<Set<UnifyPair>> nextSetasListIt = new ArrayList<Set<UnifyPair>>(nextSetasList).iterator();
|
Iterator<Set<UnifyPair>> nextSetasListIt = new ArrayList<Set<UnifyPair>>(nextSetasList).iterator();
|
||||||
if (variance == 1) {
|
if (variance == 1) {
|
||||||
@ -511,6 +514,9 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
|||||||
(oup.compare(a, a_next) == 1)) {
|
(oup.compare(a, a_next) == 1)) {
|
||||||
nextSetasList.remove(a_next);
|
nextSetasList.remove(a_next);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
System.out.println("");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else { if (variance == -1) {
|
else { if (variance == -1) {
|
||||||
@ -521,6 +527,9 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
|||||||
(oup.compare(a, a_next) == -1)) {
|
(oup.compare(a, a_next) == -1)) {
|
||||||
nextSetasList.remove(0);
|
nextSetasList.remove(0);
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
System.out.println("");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (variance == 0) {
|
else if (variance == 0) {
|
||||||
@ -531,6 +540,7 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
|||||||
/* auskommentiert um alle Max und min Betrachtung auszuschalten ENDE */
|
/* auskommentiert um alle Max und min Betrachtung auszuschalten ENDE */
|
||||||
|
|
||||||
if (isUndefinedPairSetSet(res)) {
|
if (isUndefinedPairSetSet(res)) {
|
||||||
|
int nofstred= 0;
|
||||||
Set<UnifyPair> abhSubst = res.stream()
|
Set<UnifyPair> abhSubst = res.stream()
|
||||||
.map(b ->
|
.map(b ->
|
||||||
b.stream()
|
b.stream()
|
||||||
@ -542,8 +552,18 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
|||||||
.filter(x -> b.contains(x))
|
.filter(x -> b.contains(x))
|
||||||
//.filter(y -> abhSubst.contains(y))
|
//.filter(y -> abhSubst.contains(y))
|
||||||
.collect(Collectors.toCollection(HashSet::new));
|
.collect(Collectors.toCollection(HashSet::new));
|
||||||
Set<PlaceholderType> vars = durchschnitt.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new));
|
//Set<PlaceholderType> vars = durchschnitt.stream().map(x -> (PlaceholderType)x.getLhsType()).collect(Collectors.toCollection(HashSet::new));
|
||||||
int len = nextSetasList.size();
|
int len = nextSetasList.size();
|
||||||
|
Set<UnifyPair> undefRes = res.stream().reduce((y,z) -> { y.addAll(z); return y;}).get(); //flatten aller undef results
|
||||||
|
Set<Pair<Set<UnifyPair>, UnifyPair>> reducedUndefResSubstGroundedBasePair = undefRes.stream()
|
||||||
|
.map(x -> { Set<UnifyPair> su = x.getAllSubstitutions(); //alle benutzten Substitutionen
|
||||||
|
su.add(x.getGroundBasePair()); // urspruengliches Paar
|
||||||
|
su.removeAll(durchschnitt); //alle aktuell genänderten Paare entfernen
|
||||||
|
return new Pair<>(su, x.getGroundBasePair());})
|
||||||
|
.collect(Collectors.toCollection(HashSet::new));
|
||||||
|
if (res.size() > 1) {
|
||||||
|
System.out.println();
|
||||||
|
}
|
||||||
nextSetasList = nextSetasList.stream().filter(x -> {
|
nextSetasList = nextSetasList.stream().filter(x -> {
|
||||||
//Boolean ret = false;
|
//Boolean ret = false;
|
||||||
//for (PlaceholderType var : vars) {
|
//for (PlaceholderType var : vars) {
|
||||||
@ -553,7 +573,6 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
|||||||
}).collect(Collectors.toCollection(ArrayList::new));
|
}).collect(Collectors.toCollection(ArrayList::new));
|
||||||
|
|
||||||
noAllErasedElements = noAllErasedElements + (len - nextSetasList.size());
|
noAllErasedElements = noAllErasedElements + (len - nextSetasList.size());
|
||||||
|
|
||||||
noBacktracking++;
|
noBacktracking++;
|
||||||
|
|
||||||
System.out.println("");
|
System.out.println("");
|
||||||
@ -569,6 +588,93 @@ public class TypeUnifyTask extends RecursiveTask<Set<Set<UnifyPair>>> {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected boolean couldBecorrect(Set<Pair<Set<UnifyPair>, UnifyPair>> reducedUndefResSubstGroundedBasePair, Set<UnifyPair> nextElem) {
|
||||||
|
return reducedUndefResSubstGroundedBasePair.stream()
|
||||||
|
.map(pair -> {
|
||||||
|
Set<UnifyPair> reducedAbhSubst = pair.getKey();
|
||||||
|
reducedAbhSubst.addAll(nextElem);
|
||||||
|
Optional<Set<UnifyPair>> substRes = rules.subst(reducedAbhSubst);
|
||||||
|
if (!substRes.isPresent()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
//PL 2018-10-12
|
||||||
|
//Evtl. zurest applyTypeUnification aufrufen
|
||||||
|
//evtl auch unify aufrufen
|
||||||
|
else {
|
||||||
|
UnifyPair checkPair = substRes.get().stream()
|
||||||
|
.filter(x -> x.getGroundBasePair().equals(pair.getValue().get())).findFirst().get();
|
||||||
|
if (((checkPair.getLhsType() instanceof PlaceholderType) || (checkPair.getRhsType() instanceof PlaceholderType))
|
||||||
|
&& (checkPair.getPairOp() == PairOperator.SMALLERDOT || checkPair.getPairOp() == PairOperator.SMALLERDOTWC))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
Set<UnifyPair> setCheckPair = new HashSet<>();
|
||||||
|
setCheckPair.add(checkPair);
|
||||||
|
Set<UnifyPair> setReturnCheckPair = applyTypeUnificationRules(setCheckPair, fc);
|
||||||
|
UnifyPair checkPair1 = setReturnCheckPair.iterator().next();
|
||||||
|
Set<UnifyPair> up = new HashSet<>();
|
||||||
|
up.add(checkPair1);
|
||||||
|
Set<UnifyPair> undef = new HashSet<>();
|
||||||
|
*/
|
||||||
|
PairOperator pairOp = checkPair.getPairOp();
|
||||||
|
UnifyType lhsType = checkPair.getLhsType();
|
||||||
|
UnifyType rhsType = checkPair.getRhsType();
|
||||||
|
///* Case 1: (a <. Theta')
|
||||||
|
if ((((pairOp == PairOperator.SMALLERDOT) || (pairOp == PairOperator.SMALLERNEQDOT)) && lhsType instanceof PlaceholderType)
|
||||||
|
// Case 2: (a <.? ? ext Theta')
|
||||||
|
|| (pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType && rhsType instanceof ExtendsType)
|
||||||
|
// Case 3: (a <.? ? sup Theta')
|
||||||
|
|| (pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType && rhsType instanceof SuperType)
|
||||||
|
|
||||||
|
// Case 4 was replaced by an inference rule
|
||||||
|
// Case 4: (a <.? Theta')
|
||||||
|
|| (pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof PlaceholderType)
|
||||||
|
// Case 5: (Theta <. a)
|
||||||
|
|| ((pairOp == PairOperator.SMALLERDOT) && rhsType instanceof PlaceholderType)
|
||||||
|
// Case 6 was replaced by an inference rule.
|
||||||
|
// Case 6: (? ext Theta <.? a)
|
||||||
|
|| (pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof ExtendsType && rhsType instanceof PlaceholderType)
|
||||||
|
// Case 7 was replaced by an inference rule
|
||||||
|
// Case 7: (? sup Theta <.? a)
|
||||||
|
|| (pairOp == PairOperator.SMALLERDOTWC && lhsType instanceof SuperType && rhsType instanceof PlaceholderType)
|
||||||
|
// Case 8: (Theta <.? a)
|
||||||
|
|| (pairOp == PairOperator.SMALLERDOTWC && rhsType instanceof PlaceholderType)
|
||||||
|
//reduceWildcardLow
|
||||||
|
|| (pairOp == PairOperator.SMALLERDOTWC && (lhsType instanceof ExtendsType) && (rhsType instanceof ExtendsType))
|
||||||
|
//reduceWildcardLowRight
|
||||||
|
|| ((pairOp == PairOperator.SMALLERDOTWC) && (lhsType instanceof ReferenceType) && (rhsType instanceof ExtendsType))
|
||||||
|
//reduceWildcardUp
|
||||||
|
|| ((pairOp == PairOperator.SMALLERDOTWC) && (lhsType instanceof SuperType) && (rhsType instanceof SuperType))
|
||||||
|
//reduceWildcardUpRight
|
||||||
|
|| ((pairOp == PairOperator.SMALLERDOTWC) && (lhsType instanceof ReferenceType) && (rhsType instanceof SuperType))
|
||||||
|
//reduceFunN
|
||||||
|
|| (((pairOp == PairOperator.SMALLERDOT) || (pairOp == PairOperator.EQUALSDOT))
|
||||||
|
//PL 2017-10-03 hinzugefuegt
|
||||||
|
//da Regel auch fuer EQUALSDOT anwendbar
|
||||||
|
&& (lhsType instanceof FunNType) && (rhsType instanceof FunNType))
|
||||||
|
//greaterFunN
|
||||||
|
|| ((pairOp== PairOperator.SMALLERDOT) && (lhsType instanceof FunNType) && (rhsType instanceof PlaceholderType))
|
||||||
|
//smallerFunN
|
||||||
|
|| ((pairOp == PairOperator.SMALLERDOT) && (lhsType instanceof PlaceholderType && rhsType instanceof FunNType))
|
||||||
|
//reduceTph
|
||||||
|
|| ((pairOp == PairOperator.SMALLERDOTWC) && (lhsType instanceof PlaceholderType && rhsType instanceof ReferenceType))
|
||||||
|
//reduceTphExt
|
||||||
|
|| ((pairOp == PairOperator.SMALLERDOTWC) && (lhsType instanceof ExtendsType) && rhsType instanceof PlaceholderType)
|
||||||
|
//reduceTphSup
|
||||||
|
|| ((pairOp == PairOperator.SMALLERDOTWC) && (lhsType instanceof SuperType) && rhsType instanceof PlaceholderType)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// 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 {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
//*/
|
||||||
|
} else {
|
||||||
|
//Pair type <. ? extends ? extends type betrachten TODO PL 2018-10-09
|
||||||
|
}}
|
||||||
|
return true;}).reduce((xx, yy) -> xx || yy).get();
|
||||||
|
}
|
||||||
|
|
||||||
protected boolean isUndefinedPairSet(Set<UnifyPair> s) {
|
protected boolean isUndefinedPairSet(Set<UnifyPair> s) {
|
||||||
if (s.size() >= 1 ) {
|
if (s.size() >= 1 ) {
|
||||||
|
@ -18,4 +18,8 @@ public class Pair<T, T1> {
|
|||||||
public T getKey() {
|
public T getKey() {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return "(" + key.toString() + "," + "," + value.toString() + ")\n";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import java.util.ArrayList;
|
|||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Optional;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
|
|
||||||
@ -116,6 +117,10 @@ public class UnifyPair {
|
|||||||
return pairOp;
|
return pairOp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setPairOp(PairOperator po) {
|
||||||
|
pairOp = po;
|
||||||
|
}
|
||||||
|
|
||||||
public byte getVariance() {
|
public byte getVariance() {
|
||||||
return variance;
|
return variance;
|
||||||
}
|
}
|
||||||
@ -147,6 +152,18 @@ public class UnifyPair {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UnifyPair getGroundBasePair () {
|
||||||
|
if (basePair == null) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
if (basePair.getBasePair() == null) {
|
||||||
|
return basePair;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return basePair.getGroundBasePair();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public Boolean wrongWildcard() {
|
public Boolean wrongWildcard() {
|
||||||
return lhs.wrongWildcard() || rhs.wrongWildcard();
|
return lhs.wrongWildcard() || rhs.wrongWildcard();
|
||||||
}
|
}
|
||||||
|
54
test/bytecode/FacultyTest.java
Normal file
54
test/bytecode/FacultyTest.java
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
|
||||||
|
public class FacultyTest {
|
||||||
|
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")+"/test/bytecode/javFiles/Faculty.jav";
|
||||||
|
fileToTest = new File(path);
|
||||||
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
|
compiler.generateBytecode(System.getProperty("user.dir")+"/testBytecode/generatedBC/");
|
||||||
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
|
classToTest = loader.loadClass("Faculty");
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
// Method m = classToTest.getDeclaredMethod("m", Integer.class);
|
||||||
|
Field fact = classToTest.getDeclaredField("fact");
|
||||||
|
// Class<?> lambda = m.invoke(instanceOfClass).getClass();
|
||||||
|
Class<?> lambda = fact.getType();
|
||||||
|
Method apply = lambda.getMethod("apply", Object.class);
|
||||||
|
//
|
||||||
|
// // Damit man auf die Methode zugreifen kann
|
||||||
|
apply.setAccessible(true);
|
||||||
|
|
||||||
|
Integer i = 3;
|
||||||
|
|
||||||
|
Integer result = (Integer) apply.invoke(instanceOfClass, i);
|
||||||
|
// Integer result = (Integer) m.invoke(instanceOfClass,i);
|
||||||
|
|
||||||
|
assertEquals(6, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
43
test/bytecode/FieldTest.java
Normal file
43
test/bytecode/FieldTest.java
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
|
||||||
|
import org.junit.BeforeClass;
|
||||||
|
import org.junit.Test;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
|
||||||
|
public class FieldTest {
|
||||||
|
|
||||||
|
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")+"/test/bytecode/javFiles/Field.jav";
|
||||||
|
fileToTest = new File(path);
|
||||||
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
|
compiler.generateBytecode(System.getProperty("user.dir")+"/testBytecode/generatedBC/");
|
||||||
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
|
classToTest = loader.loadClass("Field");
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() {
|
||||||
|
Field[] fields = classToTest.getFields();
|
||||||
|
assertEquals(1, fields.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
52
test/bytecode/FunOLTest.java
Normal file
52
test/bytecode/FunOLTest.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
|
||||||
|
public class FunOLTest {
|
||||||
|
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")+"/test/bytecode/javFiles/FunOL.jav";
|
||||||
|
fileToTest = new File(path);
|
||||||
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
|
compiler.generateBytecode(System.getProperty("user.dir")+"/testBytecode/generatedBC/");
|
||||||
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
|
classToTest = loader.loadClass("FunOL");
|
||||||
|
/*
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
Method m = classToTest.getDeclaredMethod("m");
|
||||||
|
Class<?> lambda = m.invoke(instanceOfClass).getClass();
|
||||||
|
Method apply = lambda.getMethod("apply", Object.class);
|
||||||
|
|
||||||
|
// Damit man auf die Methode zugreifen kann
|
||||||
|
apply.setAccessible(true);
|
||||||
|
|
||||||
|
Integer i = 77;
|
||||||
|
|
||||||
|
Integer result = (Integer) apply.invoke(m.invoke(instanceOfClass), i);
|
||||||
|
|
||||||
|
assertEquals(77, result);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
91
test/bytecode/MatrixOpTest.java
Normal file
91
test/bytecode/MatrixOpTest.java
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
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 MatrixOpTest {
|
||||||
|
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_m1;
|
||||||
|
private static Object instanceOfClass_m2;
|
||||||
|
private static Object instanceOfClass_m3;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException, ClassNotFoundException, IOException, InstantiationException {
|
||||||
|
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/MatrixOP.jav";
|
||||||
|
fileToTest = new File(path);
|
||||||
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
|
// compiler.generateBytecode(pathToClassFile);
|
||||||
|
// loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
|
// classToTest = loader.loadClass("MatrixOP");
|
||||||
|
/*
|
||||||
|
Vector<Vector<Integer>> vv = new Vector<Vector<Integer>>();
|
||||||
|
Vector<Integer> v1 = new Vector<Integer> ();
|
||||||
|
v1.addElement(2);
|
||||||
|
v1.addElement(2);
|
||||||
|
Vector<Integer> v2 = new Vector<Integer> ();
|
||||||
|
v2.addElement(3);
|
||||||
|
v2.addElement(3);
|
||||||
|
//Matrix m1 = new Matrix();
|
||||||
|
//m1.addElement(v1);
|
||||||
|
//m1.addElement(v2);
|
||||||
|
vv.addElement(v1);
|
||||||
|
vv.addElement(v2);
|
||||||
|
instanceOfClass_m1 = classToTest.getDeclaredConstructor(Vector.class).newInstance(vv); //Matrix m1 = new Matrix(vv);
|
||||||
|
|
||||||
|
Vector<Vector<Integer>> vv1 = new Vector<Vector<Integer>>();
|
||||||
|
Vector<Integer> v3 = new Vector<Integer> ();
|
||||||
|
v3.addElement(2);
|
||||||
|
v3.addElement(2);
|
||||||
|
Vector<Integer> v4 = new Vector<Integer> ();
|
||||||
|
v4.addElement(3);
|
||||||
|
v4.addElement(3);
|
||||||
|
//Matrix m2 = new Matrix();
|
||||||
|
//m2.addElement(v3);
|
||||||
|
//m2.addElement(v4);
|
||||||
|
vv1.addElement(v3);
|
||||||
|
vv1.addElement(v4);
|
||||||
|
instanceOfClass_m2 = classToTest.getDeclaredConstructor(Vector.class).newInstance(vv1);//Matrix m2 = new Matrix(vv1);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//Matrix m3 = m1.mul(vv1);
|
||||||
|
Method mul = classToTest.getDeclaredMethod("mul", Vector.class);
|
||||||
|
Object result = mul.invoke(instanceOfClass_m1, instanceOfClass_m2);
|
||||||
|
System.out.println(instanceOfClass_m1.toString() + " * " + instanceOfClass_m2.toString() + " = " + result.toString());
|
||||||
|
|
||||||
|
Vector<Vector<Integer>> res = new Vector<Vector<Integer>>();
|
||||||
|
Vector<Integer> v5 = new Vector<Integer> ();
|
||||||
|
v5.addElement(10);
|
||||||
|
v5.addElement(10);
|
||||||
|
Vector<Integer> v6 = new Vector<Integer> ();
|
||||||
|
v6.addElement(15);
|
||||||
|
v6.addElement(15);
|
||||||
|
//Matrix m2 = new Matrix();
|
||||||
|
//m2.addElement(v3);
|
||||||
|
//m2.addElement(v4);
|
||||||
|
res.addElement(v5);
|
||||||
|
res.addElement(v6);
|
||||||
|
instanceOfClass_m3 = classToTest.getDeclaredConstructor(Vector.class).newInstance(res);
|
||||||
|
assertEquals(result, instanceOfClass_m3);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -24,28 +24,28 @@ public class OverloadingSortingTest {
|
|||||||
private static Class<?> classOL2;
|
private static Class<?> classOL2;
|
||||||
private static Object instanceOfClassOL2;
|
private static Object instanceOfClassOL2;
|
||||||
|
|
||||||
@BeforeClass
|
@Test
|
||||||
public static void setUpBeforeClass() throws Exception {
|
public void generateBC() throws Exception {
|
||||||
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Sorting.jav";
|
path = System.getProperty("user.dir")+"/test/bytecode/javFiles/Sorting.jav";
|
||||||
fileToTest = new File(path);
|
fileToTest = new File(path);
|
||||||
compiler = new JavaTXCompiler(fileToTest);
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
compiler.generateBytecode(pathToClassFile);
|
compiler.generateBytecode(pathToClassFile);
|
||||||
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
// loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
classToTest = loader.loadClass("Sorting");
|
// classToTest = loader.loadClass("Sorting");
|
||||||
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
// instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
// @Test
|
||||||
public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
// public void test() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
Method meth = classToTest.getDeclaredMethod("merge", classToTest);
|
// Method meth = classToTest.getDeclaredMethod("merge", classToTest);
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
@Test
|
// @Test
|
||||||
public void test2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
// public void test2() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
|
||||||
Method meth = classToTest.getDeclaredMethod("test", classOL2);
|
// Method meth = classToTest.getDeclaredMethod("test", classOL2);
|
||||||
String res = (String) meth.invoke(instanceOfClass, instanceOfClassOL2);
|
// String res = (String) meth.invoke(instanceOfClass, instanceOfClassOL2);
|
||||||
assertEquals("Overloading2", res);
|
// assertEquals("Overloading2", res);
|
||||||
}
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
52
test/bytecode/SortingTest.java
Normal file
52
test/bytecode/SortingTest.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
|
||||||
|
public class SortingTest {
|
||||||
|
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")+"/test/bytecode/javFiles/Sorting.jav";
|
||||||
|
fileToTest = new File(path);
|
||||||
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
|
compiler.generateBytecode(System.getProperty("user.dir")+"/testBytecode/generatedBC/");
|
||||||
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
|
classToTest = loader.loadClass("Sorting");
|
||||||
|
/*
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
Method m = classToTest.getDeclaredMethod("m");
|
||||||
|
Class<?> lambda = m.invoke(instanceOfClass).getClass();
|
||||||
|
Method apply = lambda.getMethod("apply", Object.class);
|
||||||
|
|
||||||
|
// Damit man auf die Methode zugreifen kann
|
||||||
|
apply.setAccessible(true);
|
||||||
|
|
||||||
|
Integer i = 77;
|
||||||
|
|
||||||
|
Integer result = (Integer) apply.invoke(m.invoke(instanceOfClass), i);
|
||||||
|
|
||||||
|
assertEquals(77, result);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -36,8 +36,9 @@ public class Tph5Test {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void test() throws Exception {
|
public void test() throws Exception {
|
||||||
Method m = classToTest.getDeclaredMethod("m", Object.class, Object.class, Object.class);
|
// Method m = classToTest.getDeclaredMethod("m", Object.class, Object.class, Object.class);
|
||||||
Object result = m.invoke(instanceOfClass, "xx",2,3);
|
Method m = classToTest.getDeclaredMethod("m", Object.class, Object.class);
|
||||||
|
// Object result = m.invoke(instanceOfClass, "xx",2,3);
|
||||||
|
|
||||||
//assertEquals(2,result);
|
//assertEquals(2,result);
|
||||||
}
|
}
|
||||||
|
52
test/bytecode/YTest.java
Normal file
52
test/bytecode/YTest.java
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
package bytecode;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
|
import java.net.URL;
|
||||||
|
import java.net.URLClassLoader;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||||
|
|
||||||
|
public class YTest {
|
||||||
|
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")+"/test/bytecode/javFiles/Y.jav";
|
||||||
|
fileToTest = new File(path);
|
||||||
|
compiler = new JavaTXCompiler(fileToTest);
|
||||||
|
compiler.generateBytecode(System.getProperty("user.dir")+"/testBytecode/generatedBC/");
|
||||||
|
pathToClassFile = System.getProperty("user.dir")+"/testBytecode/generatedBC/";
|
||||||
|
loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)});
|
||||||
|
classToTest = loader.loadClass("Y");
|
||||||
|
/*
|
||||||
|
instanceOfClass = classToTest.getDeclaredConstructor().newInstance();
|
||||||
|
|
||||||
|
Method m = classToTest.getDeclaredMethod("m");
|
||||||
|
Class<?> lambda = m.invoke(instanceOfClass).getClass();
|
||||||
|
Method apply = lambda.getMethod("apply", Object.class);
|
||||||
|
|
||||||
|
// Damit man auf die Methode zugreifen kann
|
||||||
|
apply.setAccessible(true);
|
||||||
|
|
||||||
|
Integer i = 77;
|
||||||
|
|
||||||
|
Integer result = (Integer) apply.invoke(m.invoke(instanceOfClass), i);
|
||||||
|
|
||||||
|
assertEquals(77, result);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -1,17 +1,46 @@
|
|||||||
import java.lang.Integer;
|
import java.lang.Integer;
|
||||||
|
|
||||||
class Faculty {
|
public class Faculty {
|
||||||
|
public fact;
|
||||||
m () {
|
Faculty() {
|
||||||
|
fact = (x) -> {
|
||||||
var fact = (x) -> {
|
if(x<0) {
|
||||||
if (x == 1) {
|
return 0;
|
||||||
|
}else if (x < 1) {
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return x * (fact.apply(x-1));
|
return x * (fact.apply(x-1));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
return fact;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// m (x) {
|
||||||
|
//
|
||||||
|
//// var fact = (x) -> {
|
||||||
|
//// if (x == 1) {
|
||||||
|
//// return x;
|
||||||
|
//// }
|
||||||
|
//// else {
|
||||||
|
//// return x * (fact.apply(x-1));
|
||||||
|
//// }
|
||||||
|
//// };
|
||||||
|
//// return fact;
|
||||||
|
//// var x = 13;
|
||||||
|
//// if(x>22) {
|
||||||
|
//// return 0;
|
||||||
|
//// }else if(x <1){
|
||||||
|
//// return x;
|
||||||
|
//// }else {
|
||||||
|
//// return 1;
|
||||||
|
//// }
|
||||||
|
//
|
||||||
|
// if (x < 0) {
|
||||||
|
// return 0;
|
||||||
|
// }else if(x<2) {
|
||||||
|
// return x;
|
||||||
|
// } else {
|
||||||
|
// return x * m(x-1);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
9
test/bytecode/javFiles/Field.jav
Normal file
9
test/bytecode/javFiles/Field.jav
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
public class Field {
|
||||||
|
public Integer x = 5;
|
||||||
|
|
||||||
|
m(){
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
}
|
12
test/bytecode/javFiles/FunOL.jav
Normal file
12
test/bytecode/javFiles/FunOL.jav
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import java.util.Vector;
|
||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.String;
|
||||||
|
//import java.lang.Byte;
|
||||||
|
//import java.lang.Boolean;
|
||||||
|
|
||||||
|
public class FunOL {
|
||||||
|
|
||||||
|
add(f, y) {
|
||||||
|
return f.apply() + y;
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,6 @@
|
|||||||
import java.util.Vector;
|
import java.util.Vector;
|
||||||
import java.lang.Integer;
|
import java.lang.Integer;
|
||||||
|
//import java.lang.Float;
|
||||||
//import java.lang.Byte;
|
//import java.lang.Byte;
|
||||||
import java.lang.Boolean;
|
import java.lang.Boolean;
|
||||||
|
|
||||||
|
43
test/bytecode/javFiles/MatrixOP.jav
Normal file
43
test/bytecode/javFiles/MatrixOP.jav
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import java.util.Vector;
|
||||||
|
import java.lang.Integer;
|
||||||
|
//import java.lang.Byte;
|
||||||
|
import java.lang.Boolean;
|
||||||
|
|
||||||
|
public class MatrixOP extends Vector<Vector<Integer>> {
|
||||||
|
|
||||||
|
MatrixOP () {
|
||||||
|
}
|
||||||
|
|
||||||
|
MatrixOP(vv) {
|
||||||
|
Integer i;
|
||||||
|
i = 0;
|
||||||
|
while(i < vv.size()) {
|
||||||
|
// Boolean a = this.add(vv.elementAt(i));
|
||||||
|
this.add(vv.elementAt(i));
|
||||||
|
i=i+1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mul = (m1, m2) -> {
|
||||||
|
var ret = new MatrixOP();
|
||||||
|
var i = 0;
|
||||||
|
while(i < size()) {
|
||||||
|
var v1 = m1.elementAt(i);
|
||||||
|
var v2 = new Vector<Integer>();
|
||||||
|
var j = 0;
|
||||||
|
while(j < v1.size()) {
|
||||||
|
var erg = 0;
|
||||||
|
var k = 0;
|
||||||
|
while(k < v1.size()) {
|
||||||
|
erg = erg + v1.elementAt(k)
|
||||||
|
* m2.elementAt(k).elementAt(j);
|
||||||
|
k++; }
|
||||||
|
// v2.addElement(new Integer(erg));
|
||||||
|
v2.addElement(erg);
|
||||||
|
j++; }
|
||||||
|
ret.addElement(v2);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
}
|
@ -1,9 +1,23 @@
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Collection;
|
import java.util.ArrayList;
|
||||||
|
import java.lang.String;
|
||||||
|
|
||||||
class Sorting{
|
public class Sorting{
|
||||||
merge(a, b){
|
merge(a, b){
|
||||||
a.addAll(b);
|
a.addAll(b);
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
sort(in){
|
||||||
|
var firstHalf = in;
|
||||||
|
var secondHalf = in;
|
||||||
|
return merge(sort(firstHalf), sort(secondHalf));
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
|
||||||
|
void sort(ArrayList<String> a){
|
||||||
|
a = merge(a,a);
|
||||||
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
@ -2,7 +2,7 @@ public class Tph {
|
|||||||
|
|
||||||
m(a,b){
|
m(a,b){
|
||||||
var c = m2(b);
|
var c = m2(b);
|
||||||
return c;
|
return a;
|
||||||
// return m2(b);
|
// return m2(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,13 @@
|
|||||||
public class Tph5 {
|
public class Tph5 {
|
||||||
m(a,b,c){
|
// m(a,b,c){
|
||||||
a = c;
|
// a = c;
|
||||||
b = c;
|
// b = c;
|
||||||
return a;
|
// return a;
|
||||||
|
// }
|
||||||
|
|
||||||
|
m(x,y){
|
||||||
|
x = m2(y);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m2(y) { return y; }
|
||||||
}
|
}
|
||||||
|
19
test/bytecode/javFiles/VectorAdd.jav
Normal file
19
test/bytecode/javFiles/VectorAdd.jav
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
import java.util.Vector;
|
||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.String;
|
||||||
|
//import java.lang.Byte;
|
||||||
|
//import java.lang.Boolean;
|
||||||
|
|
||||||
|
public class VectorAdd {
|
||||||
|
|
||||||
|
add(v1, v2) {
|
||||||
|
var ret = new Vector();
|
||||||
|
var i = 0;
|
||||||
|
var erg;
|
||||||
|
while(i < v1.size()) {
|
||||||
|
erg = v1.elementAt(i) + v2.elementAt(i);
|
||||||
|
ret.addElement(erg);
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
}
|
28
test/bytecode/javFiles/Y.jav
Normal file
28
test/bytecode/javFiles/Y.jav
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
|
||||||
|
class Y {
|
||||||
|
y;
|
||||||
|
//factorial;
|
||||||
|
|
||||||
|
Y() {
|
||||||
|
y = f -> t -> f.apply(y.apply(f)).apply(t);
|
||||||
|
//factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
ergibt Parse-Error
|
||||||
|
class fac1 {
|
||||||
|
factorial;
|
||||||
|
|
||||||
|
fac1() {
|
||||||
|
var y;
|
||||||
|
y = new Y<>().y;
|
||||||
|
factorial = y.apply(f -> n -> { if (n == 0) return 1; else return n * f.apply(n - 1); });
|
||||||
|
}
|
||||||
|
public static void main(String args[]) {
|
||||||
|
System.out.println(new fac1().factorial.apply(3));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
20
test/javFiles/ListenerOverload.jav
Normal file
20
test/javFiles/ListenerOverload.jav
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import java.lang.Integer;
|
||||||
|
import java.lang.String;
|
||||||
|
|
||||||
|
class ListenerOverload{
|
||||||
|
|
||||||
|
call(p){
|
||||||
|
call(p.left);
|
||||||
|
call(p.right);
|
||||||
|
}
|
||||||
|
|
||||||
|
call(Integer i){}
|
||||||
|
|
||||||
|
call(String s){}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Pair<A,B>{
|
||||||
|
A left;
|
||||||
|
B right;
|
||||||
|
}
|
@ -104,6 +104,10 @@ public class JavaTXCompilerTest {
|
|||||||
public void multipleSolutions() throws IOException, ClassNotFoundException {
|
public void multipleSolutions() throws IOException, ClassNotFoundException {
|
||||||
execute(new File(rootDirectory+"Sorting.jav"));
|
execute(new File(rootDirectory+"Sorting.jav"));
|
||||||
}
|
}
|
||||||
|
@Test
|
||||||
|
public void listenerTest() throws IOException, ClassNotFoundException {
|
||||||
|
execute(new File(rootDirectory+"ListenerOverload.jav"));
|
||||||
|
}
|
||||||
|
|
||||||
private static class TestResultSet{
|
private static class TestResultSet{
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user