From 669e7f111f4c9be0bf14cdcc72e4749e338baf4c Mon Sep 17 00:00:00 2001 From: Fayez Abu Alia Date: Fri, 5 Jul 2019 13:29:34 +0200 Subject: [PATCH] Separated the generation of bytecode and the calculation of simplify results from each other --- .../dhbwstuttgart/bytecode/BytecodeGen.java | 151 +--- .../dhbwstuttgart/bytecode/TPHExtractor.java | 2 +- .../bytecode/signature/Signature.java | 37 +- .../bytecode/simplifyRes/SimplifyResult.java | 64 ++ .../simplifyRes/SimplifyResultClass.java | 48 + .../simplifyRes/SimplifyResultFinder.java | 820 ++++++++++++++++++ .../simplifyRes/SimplifyResultMethod.java | 42 + .../simplifyRes/SimplifyResultSourceFile.java | 45 + .../simplifyRes/TypeVariableFinder.java | 88 ++ .../bytecode/utilities/Simplify.java | 44 +- .../bytecode/utilities/SimplifyResult.java | 42 - .../de/dhbwstuttgart/core/JavaTXCompiler.java | 33 +- .../java/bytecode/FieldTphConsMethTest.java | 3 +- 13 files changed, 1207 insertions(+), 212 deletions(-) create mode 100644 src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResult.java create mode 100644 src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResultClass.java create mode 100644 src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResultFinder.java create mode 100644 src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResultMethod.java create mode 100644 src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResultSourceFile.java create mode 100644 src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/TypeVariableFinder.java delete mode 100644 src/main/java/de/dhbwstuttgart/bytecode/utilities/SimplifyResult.java diff --git a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java index 767bfcc5..1c289835 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/BytecodeGen.java @@ -6,8 +6,10 @@ import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.NoSuchElementException; import java.util.Optional; +import java.util.Set; import org.objectweb.asm.ClassWriter; import org.objectweb.asm.FieldVisitor; @@ -22,11 +24,12 @@ import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor; import de.dhbwstuttgart.bytecode.signature.Signature; import de.dhbwstuttgart.bytecode.signature.TypeToSignature; import de.dhbwstuttgart.bytecode.signature.TypeToString; +import de.dhbwstuttgart.bytecode.simplifyRes.SimplifyResult; +import de.dhbwstuttgart.bytecode.simplifyRes.SimplifyResultSourceFile; import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH; import de.dhbwstuttgart.bytecode.utilities.NormalConstructor; import de.dhbwstuttgart.bytecode.utilities.NormalMethod; import de.dhbwstuttgart.bytecode.utilities.Simplify; -import de.dhbwstuttgart.bytecode.utilities.SimplifyResult; import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.syntaxtree.ASTVisitor; @@ -83,7 +86,8 @@ public class BytecodeGen implements ASTVisitor { String type; public static RefTypeOrTPHOrWildcardOrGeneric THISTYPE = null; - String className; + private String className; + private String pkgName; private boolean isInterface; private Collection listOfResultSets; private ResultSet resultSet; @@ -96,7 +100,7 @@ public class BytecodeGen implements ASTVisitor { private String superClass; - private ArrayList tphsClass; + private List tphsClass; // stores parameter, local vars and the next index on the local variable table, // which use for aload_i, astore_i,... @@ -106,9 +110,6 @@ public class BytecodeGen implements ASTVisitor { private int constructorPos = 0; - private final TPHExtractor tphExtractor = new TPHExtractor(); - private final ArrayList commonPairs = new ArrayList<>(); - HashMap methodParamsAndTypes = new HashMap<>(); byte[] bytecode; HashMap classFiles; @@ -116,34 +117,27 @@ public class BytecodeGen implements ASTVisitor { private final ArrayList methodNameAndParamsT = new ArrayList<>(); private final ArrayList fieldNameAndParamsT = new ArrayList<>(); - private HashMap simplifyResults = new HashMap<>(); - private List> simplifyResultsList = new ArrayList<>(); - private final ArrayList fieldNameSignature = new ArrayList<>(); - public List> getSimplifyResultsList() { - return simplifyResultsList; - } + private List simplifyResultsForAllSourceFiles; + private SimplifyResult simplifyResult; - public void setSimplifyResultsList(List> simplifyResultsList) { - this.simplifyResultsList = simplifyResultsList; - } - - public BytecodeGen(HashMap classFiles, Collection listOfResultSets, SourceFile sf, + public BytecodeGen(HashMap classFiles, Collection listOfResultSets, List simplifyResultsForAllSourceFiles, SourceFile sf, String path) { this.classFiles = classFiles; this.listOfResultSets = listOfResultSets; + this.simplifyResultsForAllSourceFiles = simplifyResultsForAllSourceFiles; this.sf = sf; this.path = path; + this.pkgName = sf.getPkgName(); } @Override public void visit(SourceFile sourceFile) { for (ClassOrInterface cl : sourceFile.getClasses()) { System.out.println("in Class: " + cl.getClassName().toString()); - BytecodeGen classGen = new BytecodeGen(classFiles, listOfResultSets, sf, path); + BytecodeGen classGen = new BytecodeGen(classFiles, listOfResultSets, simplifyResultsForAllSourceFiles, sf, path); cl.accept(classGen); - simplifyResultsList.add(classGen.getSimplifyResults()); classGen.writeClass(cl.getClassName().toString()); } } @@ -152,7 +146,7 @@ public class BytecodeGen implements ASTVisitor { * Associates the bytecode of the class that was build with the classWriter * {@link #cw} with the class name in the map {@link #classFiles} * - * @param name name of the class with which the the bytecode is to be associated + * @param name name of the class with which the bytecode is to be associated */ private void writeClass(String name) { bytecode = cw.toByteArray(); @@ -182,69 +176,29 @@ public class BytecodeGen implements ASTVisitor { boolean isConsWithNoParamsVisited = false; boolean isVisited = false; List listOfResultSetsList = new ArrayList<>(listOfResultSets); + simplifyResult = simplifyResultsForAllSourceFiles.stream().map(sr->sr.getSimplifyResultsByName(pkgName, className)).findFirst().get(); for (int i = 0; i < listOfResultSetsList.size(); i++) { //for (ResultSet rs : listOfResultSets) { superClass = classOrInterface.getSuperClass().acceptTV(new TypeToDescriptor()); resultSet = listOfResultSetsList.get(i); - tphExtractor.setResultSet(resultSet); +// tphExtractor.setResultSet(resultSet); + // Nur einmal ausführen!! if (!isVisited) { - classOrInterface.accept(tphExtractor); - - getCommonTPHS(tphExtractor); - - tphsClass = new ArrayList<>(); - for (String t : tphExtractor.allTPHS.keySet()) { - if (!tphExtractor.allTPHS.get(t)) - tphsClass.add(t); - } + tphsClass = simplifyResult.getTphsClass(); String sig = null; /* * if class has generics then creates signature Signature looks like: * Superclass */ - if (classOrInterface.getGenerics().iterator().hasNext() || !commonPairs.isEmpty() - || classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<") + if (classOrInterface.getGenerics().iterator().hasNext() || classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<") || !tphsClass.isEmpty()) { - HashMap> constraints = Simplify - .simplifyConstraintsClass(tphExtractor, tphsClass); - ArrayList consClass = new ArrayList<>(); - for (TPHConstraint cons : constraints.keySet()) { - String right = null; - boolean isToAdd = false; - for (String tph : tphsClass) { - if (cons.getLeft().equals(tph)) { - - consClass.add(cons); - try { - right = getTPH(cons.getRight()); - isToAdd = true; - } catch (NoSuchElementException e) { - continue; - } - - } - } - if (isToAdd) { - tphsClass.add(right); - removeFromMethod(right); - right = null; - isToAdd = false; - } -// if(right != null) { -// tphsClass.add(right); -// removeFromMethod(right); -// right = null; -// } - } - - SimplifyResult sRes = new SimplifyResult(consClass, tphsClass, new HashMap<>()); - simplifyResults.put(className, sRes); - - Signature signature = new Signature(classOrInterface, genericsAndBounds, commonPairs, tphsClass, - consClass); + + List consClass = simplifyResult.getClassConstraints(); + + Signature signature = new Signature(classOrInterface, genericsAndBounds, consClass); sig = signature.toString(); System.out.println("Signature: => " + sig); } @@ -276,41 +230,6 @@ public class BytecodeGen implements ASTVisitor { } - private void removeFromMethod(String name) { - for (MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) { - ArrayList toRemove = new ArrayList<>(); - for (String tph : m.getTphs()) { - if (tph.equals(name)) { - toRemove.add(tph); - } - } - - if (!toRemove.isEmpty()) { - m.getTphs().removeAll(toRemove); - return; - } - } - - } - - private String getTPH(String name) { - for (String tph : tphExtractor.allTPHS.keySet()) { - if (tph.equals(name)) - return tph; - } - throw new NoSuchElementException("TPH " + name + " does not exist"); - } - - private void getCommonTPHS(TPHExtractor tphExtractor) { - // Gemeinsame TPHs - ArrayList cTPHs = new ArrayList<>(); - // Alle TPHs der Felder speichern - for (String tph : tphExtractor.allTPHS.keySet()) { - if (!tphExtractor.allTPHS.get(tph)) - cTPHs.add(tph); - } - } - @Override public void visit(Constructor field) { System.out.println("ResultSet: "); @@ -330,7 +249,6 @@ public class BytecodeGen implements ASTVisitor { 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)) { @@ -353,8 +271,7 @@ public class BytecodeGen implements ASTVisitor { } String sig = null; if (hasGen) { - HashMap> constraints = Simplify.simplifyConstraints(field, tphExtractor, - tphsClass); + Map> constraints = simplifyResult.getMethodConstraintsByID(methParamTypes); Signature signature = new Signature(field, genericsAndBounds, methodParamsAndTypes, resultSet, constraints); sig = signature.toString(); } @@ -395,7 +312,6 @@ public class BytecodeGen implements ASTVisitor { 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)) { @@ -443,23 +359,12 @@ public class BytecodeGen implements ASTVisitor { // zwite operand muss weggelassen werden if (hasGen || resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString()) .equals("TPH")) { - System.out.println("ALL CONST: " + tphExtractor.allCons.size()); - tphExtractor.allCons.forEach(c -> System.out.println(c.toString())); - System.out.println("----------------"); - HashMap> constraints = Simplify.simplifyConstraints(method, - tphExtractor, tphsClass); + + Map> constraints = simplifyResult.getMethodConstraintsByID(methParamTypes); // ArrayList pairs = simplifyPairs(method.name,tphExtractor.allPairs,tphExtractor.allCons); Signature signature = new Signature(method, genericsAndBoundsMethod, genericsAndBounds, methodParamsAndTypes, resultSet, constraints); sig = signature.toString(); - if (simplifyResults.containsKey(className)) { - simplifyResults.get(className).getMethodsConstraints().put(methParamTypes, constraints); - } else { - SimplifyResult sRes = new SimplifyResult(new ArrayList<>(), new ArrayList<>(), new HashMap<>()); - sRes.getMethodsConstraints().put(methParamTypes, constraints); - simplifyResults.put(className, sRes); - } - } System.out.println(method.getName() + " ==> " + sig); NormalMethod meth = new NormalMethod(method, genericsAndBounds, genericsAndBoundsMethod, hasGen); @@ -476,10 +381,6 @@ public class BytecodeGen implements ASTVisitor { mv.visitEnd(); } - public HashMap getSimplifyResults() { - return simplifyResults; - } - @Override public void visit(ParameterList formalParameters) { paramsAndLocals = new HashMap<>(); diff --git a/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java b/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java index 2ef7d957..72776302 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/TPHExtractor.java @@ -40,7 +40,7 @@ import de.dhbwstuttgart.typeinference.result.ResultSet; public class TPHExtractor extends AbstractASTWalker { // Alle TPHs der Felder werden iKopf der Klasse definiert // alle TPHs der Klasse: (TPH, is in Method?) - final HashMap allTPHS = new HashMap<>(); + public final HashMap allTPHS = new HashMap<>(); MethodAndTPH methodAndTph; Boolean inMethod = false; diff --git a/src/main/java/de/dhbwstuttgart/bytecode/signature/Signature.java b/src/main/java/de/dhbwstuttgart/bytecode/signature/Signature.java index fbbacdfa..e7f870c5 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/signature/Signature.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/signature/Signature.java @@ -4,6 +4,9 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.Set; import org.objectweb.asm.Type; import org.objectweb.asm.signature.SignatureVisitor; @@ -18,7 +21,6 @@ import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.Constructor; import de.dhbwstuttgart.syntaxtree.GenericTypeVar; import de.dhbwstuttgart.syntaxtree.Method; -import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; import de.dhbwstuttgart.syntaxtree.type.GenericRefType; import de.dhbwstuttgart.syntaxtree.type.RefType; @@ -26,7 +28,6 @@ import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType; import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; import de.dhbwstuttgart.syntaxtree.type.WildcardType; -import de.dhbwstuttgart.typeinference.result.GenericInsertPair; import de.dhbwstuttgart.typeinference.result.ResolvedType; import de.dhbwstuttgart.typeinference.result.ResultSet; @@ -39,17 +40,13 @@ public class Signature { private Method method; private HashMap methodParamsAndTypes; private ResultSet resultSet; - private ArrayList commonPairs; - private HashMap> methodConstraints; - private ArrayList tphsClass; - private ArrayList consClass; + private Map> methodConstraints; + private List consClass; public Signature(ClassOrInterface classOrInterface, HashMap genericsAndBounds, - ArrayList commonPairs, ArrayList tphsClass, ArrayList consClass) { + List consClass) { this.classOrInterface = classOrInterface; this.genericsAndBounds = genericsAndBounds; - this.commonPairs = commonPairs; - this.tphsClass = tphsClass; this.consClass = consClass; sw = new SignatureWriter(); createSignatureForClassOrInterface(); @@ -57,7 +54,7 @@ public class Signature { public Signature(Constructor constructor, HashMap genericsAndBounds, HashMap methodParamsAndTypes,ResultSet resultSet, - HashMap> methodConstraints) { + Map> methodConstraints) { this.constructor = constructor; this.genericsAndBounds = genericsAndBounds; this.methodParamsAndTypes = methodParamsAndTypes; @@ -69,13 +66,13 @@ public class Signature { public Signature(Method method, HashMap genericsAndBoundsMethod,HashMap genericsAndBounds, HashMap methodParamsAndTypes, ResultSet resultSet, - HashMap> methodConstraints) { + Map> constraints) { this.method = method; this.genericsAndBoundsMethod = genericsAndBoundsMethod; this.genericsAndBounds = genericsAndBounds; this.methodParamsAndTypes = methodParamsAndTypes; this.resultSet = resultSet; - this.methodConstraints = methodConstraints; + this.methodConstraints = constraints; sw = new SignatureWriter(); createSignatureForConsOrMethod(this.method,false); } @@ -152,7 +149,7 @@ public class Signature { String ret = resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature()); ArrayList allConsBeforeSimplify = new ArrayList<>(); - HashMap> allConstraints = new HashMap<>(); + Map> allConstraints = new HashMap<>(); if(ret.contains("<")) { allConsBeforeSimplify = getAllConstraints((RefType) resultSet.resolveType(method.getReturnType()).resolvedType); @@ -199,17 +196,17 @@ public class Signature { // sw.visitEnd(); } - private void addConstraintsToMap(HashMap> allConstraints, + private void addConstraintsToMap(Map> allConstraints, ArrayList allConsBeforeSimplify) { for(TPHConstraint tphCons : allConsBeforeSimplify) { allConstraints.put(tphCons, null); } } - private String getEqualTPH(HashMap> methodConstraints, String tph) { - for(TPHConstraint cons : methodConstraints.keySet()) { - if(methodConstraints.get(cons) != null) { - if(methodConstraints.get(cons).contains(tph)) { + private String getEqualTPH(Map> methodConstraints2, String tph) { + for(TPHConstraint cons : methodConstraints2.keySet()) { + if(methodConstraints2.get(cons) != null) { + if(methodConstraints2.get(cons).contains(tph)) { return cons.getLeft(); } } @@ -217,10 +214,10 @@ public class Signature { return tph; } - private void createTypeVars(HashMap> allConstraints, boolean doSimplify) { + private void createTypeVars(Map> allConstraints, boolean doSimplify) { allConstraints.putAll(methodConstraints); - HashMap> simplifiedConstraints; + Map> simplifiedConstraints; if(doSimplify) { simplifiedConstraints = Simplify.simplifyContraints(allConstraints); }else { diff --git a/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResult.java b/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResult.java new file mode 100644 index 00000000..04544d0b --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResult.java @@ -0,0 +1,64 @@ +/** + * + */ +package de.dhbwstuttgart.bytecode.simplifyRes; + +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; + +/** + * The class SimplifyResult represents the results of the simplify algorithm. + * This class contains all constraints and all type placeholders of a class. The type placeholders + * are represented by their names. + * The simplify results of each method of a class are also contained in this class. + * + * @author fayez + * + */ +public class SimplifyResult { + private List classConstraints; + private List tphsClass; + private final List simplifyResultForMethod = new ArrayList<>(); + + public SimplifyResult(List classConstraints, List tphsClass) { + this.classConstraints = classConstraints; + this.tphsClass = tphsClass; + } + + public SimplifyResult() { + } + + public List getClassConstraints() { + return classConstraints; + } + + public List getSimplifyResultForMethod() { + return simplifyResultForMethod; + } + + public List getTphsClass() { + return tphsClass==null?new ArrayList<>():tphsClass; + } + + /** + * @param classConstraints the classConstraints to set + */ + public void setClassConstraints(List classConstraints) { + this.classConstraints = classConstraints; + } + + /** + * @param tphsClass the tphsClass to set + */ + public void setTphsClass(List tphsClass) { + this.tphsClass = tphsClass; + } + + public Map> getMethodConstraintsByID(String id){ + return simplifyResultForMethod.stream().filter(sr->sr.getMethodID().equals(id)).findAny().get().getConastraintsAndEqualTPHs(); + } +} diff --git a/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResultClass.java b/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResultClass.java new file mode 100644 index 00000000..ef0aa85f --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResultClass.java @@ -0,0 +1,48 @@ +/** + * + */ +package de.dhbwstuttgart.bytecode.simplifyRes; + + +/** + * The simplify results of a class + * + * @author fayez + * + */ +public class SimplifyResultClass { + private final String className; + private SimplifyResult simplifyResults; + + /** + * @param className + */ + public SimplifyResultClass(String className) { + this.className = className; + } + + /** + * @param className + * @param simplifyResults + */ + public SimplifyResultClass(String className, SimplifyResult simplifyResults) { + this.className = className; + this.simplifyResults = simplifyResults; + } + + public String getClassName() { + return className; + } + + public SimplifyResult getSimplifyResults() { + return simplifyResults; + } + + /** + * @param simplifyResults the simplifyResults to set + */ + public void setSimplifyResults(SimplifyResult simplifyResults) { + this.simplifyResults = simplifyResults; + } + +} diff --git a/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResultFinder.java b/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResultFinder.java new file mode 100644 index 00000000..bcc023d9 --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResultFinder.java @@ -0,0 +1,820 @@ +/** + * + */ +package de.dhbwstuttgart.bytecode.simplifyRes; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Iterator; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; + +import de.dhbwstuttgart.bytecode.BytecodeGen; +import de.dhbwstuttgart.bytecode.TPHExtractor; +import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; +import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor; +import de.dhbwstuttgart.bytecode.signature.Signature; +import de.dhbwstuttgart.bytecode.signature.TypeToSignature; +import de.dhbwstuttgart.bytecode.signature.TypeToString; +import de.dhbwstuttgart.bytecode.utilities.MethodAndTPH; +import de.dhbwstuttgart.bytecode.utilities.Resolver; +import de.dhbwstuttgart.bytecode.utilities.Simplify; +import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; +import de.dhbwstuttgart.syntaxtree.ASTVisitor; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.Constructor; +import de.dhbwstuttgart.syntaxtree.Field; +import de.dhbwstuttgart.syntaxtree.FormalParameter; +import de.dhbwstuttgart.syntaxtree.GenericDeclarationList; +import de.dhbwstuttgart.syntaxtree.GenericTypeVar; +import de.dhbwstuttgart.syntaxtree.Method; +import de.dhbwstuttgart.syntaxtree.ParameterList; +import de.dhbwstuttgart.syntaxtree.SourceFile; +import de.dhbwstuttgart.syntaxtree.statement.ArgumentList; +import de.dhbwstuttgart.syntaxtree.statement.Assign; +import de.dhbwstuttgart.syntaxtree.statement.AssignToField; +import de.dhbwstuttgart.syntaxtree.statement.BinaryExpr; +import de.dhbwstuttgart.syntaxtree.statement.Block; +import de.dhbwstuttgart.syntaxtree.statement.CastExpr; +import de.dhbwstuttgart.syntaxtree.statement.DoStmt; +import de.dhbwstuttgart.syntaxtree.statement.EmptyStmt; +import de.dhbwstuttgart.syntaxtree.statement.ExpressionReceiver; +import de.dhbwstuttgart.syntaxtree.statement.FieldVar; +import de.dhbwstuttgart.syntaxtree.statement.ForStmt; +import de.dhbwstuttgart.syntaxtree.statement.IfStmt; +import de.dhbwstuttgart.syntaxtree.statement.InstanceOf; +import de.dhbwstuttgart.syntaxtree.statement.LambdaExpression; +import de.dhbwstuttgart.syntaxtree.statement.Literal; +import de.dhbwstuttgart.syntaxtree.statement.LocalVar; +import de.dhbwstuttgart.syntaxtree.statement.LocalVarDecl; +import de.dhbwstuttgart.syntaxtree.statement.MethodCall; +import de.dhbwstuttgart.syntaxtree.statement.NewArray; +import de.dhbwstuttgart.syntaxtree.statement.NewClass; +import de.dhbwstuttgart.syntaxtree.statement.Return; +import de.dhbwstuttgart.syntaxtree.statement.ReturnVoid; +import de.dhbwstuttgart.syntaxtree.statement.StaticClassName; +import de.dhbwstuttgart.syntaxtree.statement.Super; +import de.dhbwstuttgart.syntaxtree.statement.SuperCall; +import de.dhbwstuttgart.syntaxtree.statement.This; +import de.dhbwstuttgart.syntaxtree.statement.UnaryExpr; +import de.dhbwstuttgart.syntaxtree.statement.WhileStmt; +import de.dhbwstuttgart.syntaxtree.type.ExtendsWildcardType; +import de.dhbwstuttgart.syntaxtree.type.GenericRefType; +import de.dhbwstuttgart.syntaxtree.type.RefType; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; +import de.dhbwstuttgart.syntaxtree.type.SuperWildcardType; +import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; +import de.dhbwstuttgart.typeinference.result.ResultSet; + +/** + * @author fayez + * + */ +public class SimplifyResultFinder implements ASTVisitor { + private final TPHExtractor tphExtractor = new TPHExtractor(); + private Collection listOfResultSets; + private SourceFile sf; + private List tphsClass; + private SimplifyResultSourceFile simplifyResOfSourceFile; + private ResultSet resultSet; + private List methodNameAndParamsT = new ArrayList<>(); + private Resolver resolver; + + private String pkgName; + private String className; + // stores generics and their bounds of class + private Map genericsAndBounds = new HashMap<>(); + private Map methodParamsAndTypes = new HashMap<>(); + + /** + * @param sf + * @param listOfResultSets + */ + public SimplifyResultFinder(SourceFile sf, Collection listOfResultSets) { + this.sf = sf; + this.listOfResultSets = listOfResultSets; + } + + public SimplifyResultSourceFile findSimplifyRes() { + sf.accept(this); + return simplifyResOfSourceFile; + } + + /* + * (non-Javadoc) + * + * @see + * de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree. + * SourceFile) + */ + @Override + public void visit(SourceFile sourceFile) { + pkgName = sf.getPkgName(); + simplifyResOfSourceFile = new SimplifyResultSourceFile(pkgName); + for (ClassOrInterface cl : sourceFile.getClasses()) { + cl.accept(this); + } + } + + /* + * (non-Javadoc) + * + * @see + * de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree. + * ClassOrInterface) + */ + @Override + public void visit(ClassOrInterface classOrInterface) { + className = classOrInterface.getClassName().toString(); + SimplifyResult sRes = new SimplifyResult(); + SimplifyResultClass sResClass = new SimplifyResultClass(className); + List listOfResultSetsList = new ArrayList<>(listOfResultSets); + for (int i = 0; i < listOfResultSetsList.size(); i++) { + resultSet = listOfResultSetsList.get(i); + resolver = new Resolver(resultSet); + tphExtractor.setResultSet(resultSet); + + classOrInterface.accept(tphExtractor); + + + tphsClass = new ArrayList<>(); + for (String t : tphExtractor.allTPHS.keySet()) { + if (!tphExtractor.allTPHS.get(t)) + tphsClass.add(t); + } + + if (classOrInterface.getGenerics().iterator().hasNext() + || classOrInterface.getSuperClass().acceptTV(new TypeToSignature()).contains("<") + || !tphsClass.isEmpty()) { + + Map> constraints = Simplify.simplifyConstraintsClass(tphExtractor, tphsClass); + ArrayList consClass = new ArrayList<>(); + for (TPHConstraint cons : constraints.keySet()) { + String right = null; + boolean isToAdd = false; + for (String tph : tphsClass) { + if (cons.getLeft().equals(tph)) { + consClass.add(cons); + try { + right = getTPH(cons.getRight()); + isToAdd = true; + } catch (NoSuchElementException e) { + continue; + } + + } + } + if (isToAdd && !tphsClass.contains(right)) { + tphsClass.add(right); + removeFromMethod(right); + right = null; + isToAdd = false; + } + } + + sRes.setClassConstraints(consClass); + sRes.setTphsClass(tphsClass); + + TypeVariableFinder typeVariableFinder = new TypeVariableFinder(classOrInterface, genericsAndBounds, tphsClass, + consClass); + + typeVariableFinder.findTV(); + } + + sResClass.setSimplifyResults(sRes); + simplifyResOfSourceFile.addSimplifyResultClass(sResClass); + + for (Constructor c : classOrInterface.getConstructors()) { + c.accept(this); + } + + for (Method m : classOrInterface.getMethods()) { + m.accept(this); + } + + } + + } + + private void removeFromMethod(String name) { + for (MethodAndTPH m : tphExtractor.ListOfMethodsAndTph) { + ArrayList toRemove = new ArrayList<>(); + for (String tph : m.getTphs()) { + if (tph.equals(name)) { + toRemove.add(tph); + } + } + + if (!toRemove.isEmpty()) { + m.getTphs().removeAll(toRemove); + return; + } + } + + } + + private String getTPH(String name) { + for (String tph : tphExtractor.allTPHS.keySet()) { + if (tph.equals(name)) + return tph; + } + throw new NoSuchElementException("TPH " + name + " does not exist"); + } + + /* + * (non-Javadoc) + * + * @see + * de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree. + * Method) + */ + @Override + public void visit(Method method) { + String retType = resolver.getResolvedType(method.getReturnType()); + String methParamTypes = retType + method.name + "%%"; + method.getParameterList().accept(this); + + Iterator itr = method.getParameterList().iterator(); + while (itr.hasNext()) { + FormalParameter fp = itr.next(); + methParamTypes += resolver.getResolvedType(fp.getType()) + ";"; + } + + if (methodNameAndParamsT.contains(methParamTypes)) { + return; + } + methodNameAndParamsT.add(methParamTypes); + + /* Prüfe, ob die Rückgabe-Type der Methode eine Type-Variable ist */ + boolean hasGenInParameterList = genericsAndBounds.containsKey(retType) || retType.contains("TPH ") + || resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToSignature()) + .contains("<"); + /* + * Wenn die Rückgabe-Type eine Typ-variable ist, erzeuge direkt die Signature, + * wenn nicht, prüfe, ob einer der Parameter Typ-Variable als Typ hat + */ + if (!hasGenInParameterList) { + for (String paramName : methodParamsAndTypes.keySet()) { + String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToDescriptor()); + String sigOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature()); + if (genericsAndBounds.containsKey(typeOfParam) || typeOfParam.contains("TPH ") + || sigOfParam.contains("<")) { + hasGenInParameterList = true; + break; + } + } + } + + + /* if method has generics or return type is TPH, create signature */ + // zwite operand muss weggelassen werden + if (hasGenInParameterList || resultSet.resolveType(method.getReturnType()).resolvedType.acceptTV(new TypeToString()) + .equals("TPH")) { + + Map> constraints = Simplify.simplifyConstraints(method, + tphExtractor, tphsClass); + + SimplifyResultMethod sResMethod = new SimplifyResultMethod(methParamTypes, constraints); + + simplifyResOfSourceFile.getSimplifyResultsByName(pkgName,className).getSimplifyResultForMethod().add(sResMethod); + } + } + + /* + * (non-Javadoc) + * + * @see + * de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree. + * ParameterList) + */ + @Override + public void visit(ParameterList formalParameters) { + if(!methodParamsAndTypes.isEmpty()) + methodParamsAndTypes.clear(); + + Iterator itr = formalParameters.iterator(); + int i = 1; + while (itr.hasNext()) { + FormalParameter fp = itr.next(); + methodParamsAndTypes.put(fp.getName(), resultSet.resolveType(fp.getType()).resolvedType); + fp.accept(this); + i++; + } + + } + + /* + * (non-Javadoc) + * + * @see + * de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree. + * Constructor) + */ + @Override + public void visit(Constructor field) { + field.getParameterList().accept(this); + + String methParamTypes = field.name + "%%"; + + Iterator itr = field.getParameterList().iterator(); + while (itr.hasNext()) { + FormalParameter fp = itr.next(); + methParamTypes += resolver.getResolvedType(fp.getType()) + ";"; + } + + if (methodNameAndParamsT.contains(methParamTypes)) { + return; + } + methodNameAndParamsT.add(methParamTypes); + + boolean hasGen = false; + + for (String paramName : methodParamsAndTypes.keySet()) { + String typeOfParam = methodParamsAndTypes.get(paramName).acceptTV(new TypeToSignature()); + System.out.println(typeOfParam); + if (genericsAndBounds.containsKey(typeOfParam) || typeOfParam.contains("$") || typeOfParam.contains("<")) { + hasGen = true; + break; + } + } + if (hasGen) { + Map> constraints = Simplify.simplifyConstraints(field, tphExtractor, + tphsClass); + SimplifyResultMethod sResMethod = new SimplifyResultMethod(methParamTypes, constraints); + + simplifyResOfSourceFile.getSimplifyResultsByName(pkgName,className).getSimplifyResultForMethod().add(sResMethod); + } + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.ArgumentList) + */ + @Override + public void visit(ArgumentList argumentList) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.LambdaExpression) + */ + @Override + public void visit(LambdaExpression lambdaExpression) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.Assign) + */ + @Override + public void visit(Assign assign) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.BinaryExpr) + */ + @Override + public void visit(BinaryExpr binary) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.Block) + */ + @Override + public void visit(Block block) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.CastExpr) + */ + @Override + public void visit(CastExpr castExpr) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.EmptyStmt) + */ + @Override + public void visit(EmptyStmt emptyStmt) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.FieldVar) + */ + @Override + public void visit(FieldVar fieldVar) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.ForStmt) + */ + @Override + public void visit(ForStmt forStmt) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.IfStmt) + */ + @Override + public void visit(IfStmt ifStmt) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.InstanceOf) + */ + @Override + public void visit(InstanceOf instanceOf) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.LocalVar) + */ + @Override + public void visit(LocalVar localVar) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.LocalVarDecl) + */ + @Override + public void visit(LocalVarDecl localVarDecl) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.MethodCall) + */ + @Override + public void visit(MethodCall methodCall) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.NewClass) + */ + @Override + public void visit(NewClass methodCall) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.NewArray) + */ + @Override + public void visit(NewArray newArray) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.Return) + */ + @Override + public void visit(Return aReturn) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.ReturnVoid) + */ + @Override + public void visit(ReturnVoid aReturn) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.StaticClassName) + */ + @Override + public void visit(StaticClassName staticClassName) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.Super) + */ + @Override + public void visit(Super aSuper) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.This) + */ + @Override + public void visit(This aThis) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.WhileStmt) + */ + @Override + public void visit(WhileStmt whileStmt) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.DoStmt) + */ + @Override + public void visit(DoStmt whileStmt) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.AssignToField) + */ + @Override + public void visit(AssignToField assignLeftSide) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see + * de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart.parser. + * SyntaxTreeGenerator.AssignToLocal) + */ + @Override + public void visit(AssignToLocal assignLeftSide) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.SuperCall) + */ + @Override + public void visit(SuperCall superCall) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.ExpressionReceiver) + */ + @Override + public void visit(ExpressionReceiver expressionReceiver) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.UnaryExpr) + */ + @Override + public void visit(UnaryExpr unaryExpr) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see de.dhbwstuttgart.syntaxtree.StatementVisitor#visit(de.dhbwstuttgart. + * syntaxtree.statement.Literal) + */ + @Override + public void visit(Literal literal) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see + * de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree. + * GenericTypeVar) + */ + @Override + public void visit(GenericTypeVar genericTypeVar) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see + * de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree. + * FormalParameter) + */ + @Override + public void visit(FormalParameter formalParameter) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see + * de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree. + * GenericDeclarationList) + */ + @Override + public void visit(GenericDeclarationList genericTypeVars) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see + * de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree. + * Field) + */ + @Override + public void visit(Field field) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see + * de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.type + * .RefType) + */ + @Override + public void visit(RefType refType) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see + * de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.type + * .SuperWildcardType) + */ + @Override + public void visit(SuperWildcardType superWildcardType) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see + * de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.type + * .TypePlaceholder) + */ + @Override + public void visit(TypePlaceholder typePlaceholder) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see + * de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.type + * .ExtendsWildcardType) + */ + @Override + public void visit(ExtendsWildcardType extendsWildcardType) { + // TODO Auto-generated method stub + + } + + /* + * (non-Javadoc) + * + * @see + * de.dhbwstuttgart.syntaxtree.ASTVisitor#visit(de.dhbwstuttgart.syntaxtree.type + * .GenericRefType) + */ + @Override + public void visit(GenericRefType genericRefType) { + // TODO Auto-generated method stub + + } + +} diff --git a/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResultMethod.java b/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResultMethod.java new file mode 100644 index 00000000..94f505fa --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResultMethod.java @@ -0,0 +1,42 @@ +package de.dhbwstuttgart.bytecode.simplifyRes; + +import java.util.Map; +import java.util.Set; + +import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; + +/** + * The simplify results of a methed + * + * @author fayez + * + */ +public class SimplifyResultMethod { + + private final String methodID; + private final Map> conastraintsAndEqualTPHs; + + + public SimplifyResultMethod(String methodName, Map> conastraintsAndEqualTPHs) { + this.methodID = methodName; + this.conastraintsAndEqualTPHs = conastraintsAndEqualTPHs; + } + + + /** + * @return the methodName + */ + public String getMethodID() { + return methodID; + } + + + /** + * @return the conastraintsAndEqualTPHs + */ + public Map> getConastraintsAndEqualTPHs() { + return conastraintsAndEqualTPHs; + } + + +} \ No newline at end of file diff --git a/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResultSourceFile.java b/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResultSourceFile.java new file mode 100644 index 00000000..6d2cd4b2 --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/SimplifyResultSourceFile.java @@ -0,0 +1,45 @@ +/** + * + */ +package de.dhbwstuttgart.bytecode.simplifyRes; + +import java.util.ArrayList; +import java.util.List; +import java.util.NoSuchElementException; + +/** + * The simplify results of a source file (package) + * + * @author fayez + * + */ +public class SimplifyResultSourceFile { + private String pkgName; + private final List simplifyResForSF = new ArrayList<>(); + + /** + * @param pkgName + */ + public SimplifyResultSourceFile(String pkgName) { + this.pkgName = pkgName; + } + + public List getSimplifyResForSF() { + return simplifyResForSF; + } + /** + * Appends the simplify results of a class to simplifyResForSF + * + * @param sResClass simplify results of a class to added + */ + public void addSimplifyResultClass(SimplifyResultClass sResClass) { + simplifyResForSF.add(sResClass); + } + + public SimplifyResult getSimplifyResultsByName(String pkgName, String name) { + if(this.pkgName.equals(pkgName)) + return simplifyResForSF.stream().filter(sr->sr.getClassName().equals(name)).findAny().get().getSimplifyResults(); + + throw new NoSuchElementException("Simplify results for the class "+pkgName+"."+name+" are not found"); + } +} diff --git a/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/TypeVariableFinder.java b/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/TypeVariableFinder.java new file mode 100644 index 00000000..1da23b09 --- /dev/null +++ b/src/main/java/de/dhbwstuttgart/bytecode/simplifyRes/TypeVariableFinder.java @@ -0,0 +1,88 @@ +/** + * + */ +package de.dhbwstuttgart.bytecode.simplifyRes; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import org.objectweb.asm.Type; + +import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; +import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor; +import de.dhbwstuttgart.syntaxtree.ClassOrInterface; +import de.dhbwstuttgart.syntaxtree.GenericTypeVar; +import de.dhbwstuttgart.syntaxtree.type.GenericRefType; +import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; + +/** + * @author fayez + * + */ +public class TypeVariableFinder { + private ClassOrInterface classOrInterface; + private Map genericsAndBounds; + private List tphsClass; + private List consClass; + + public TypeVariableFinder(ClassOrInterface classOrInterface, Map genericsAndBounds, + List tphsClass, List consClass) { + this.classOrInterface = classOrInterface; + this.genericsAndBounds = genericsAndBounds; + this.tphsClass = tphsClass; + this.consClass = consClass; + } + + public void findTV() { + Iterator itr = classOrInterface.getGenerics().iterator(); + + while(itr.hasNext()) { + GenericTypeVar g = itr.next(); + getBoundsOfTypeVar(g,genericsAndBounds); + } + + if(!consClass.isEmpty()) { + ArrayList types = new ArrayList<>(); + ArrayList superTypes = new ArrayList<>(); + + for(TPHConstraint cons : consClass) { + types.add(cons.getLeft()); + superTypes.add(cons.getRight()); + } + + for(TPHConstraint cons : consClass) { + String t = cons.getLeft()+"$"; + String bound = cons.getRight()+"$"; + genericsAndBounds.put(t, bound); + } + + for(TPHConstraint cons : consClass) { + if(!types.contains(cons.getRight()) && !genericsAndBounds.keySet().contains(cons.getRight()+"$")) { + String t = cons.getRight()+"$"; + String bound = Type.getInternalName(Object.class); + genericsAndBounds.put(t, bound); + } + } + } + } + + /** + * Get bounds of type variable + * @param g type variable + * @param genAndBounds + */ + private void getBoundsOfTypeVar(GenericTypeVar g, Map genAndBounds) { + + Iterator bItr = g.getBounds().iterator(); + while(bItr.hasNext()) { + RefTypeOrTPHOrWildcardOrGeneric b =bItr.next(); + String boundDesc = b.acceptTV(new TypeToDescriptor()); + // Ensure that <...> extends java.lang.Object OR ... + genAndBounds.put(g.getName(), boundDesc); + } + } + +} diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java index a88e0740..6174a0b5 100644 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java +++ b/src/main/java/de/dhbwstuttgart/bytecode/utilities/Simplify.java @@ -6,6 +6,7 @@ import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Set; import org.objectweb.asm.Type; @@ -19,8 +20,8 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; public class Simplify { - public static HashMap> simplifyConstraints(Method method, TPHExtractor tphExtractor, - ArrayList tphsClass) { + public static Map> simplifyConstraints(Method method, TPHExtractor tphExtractor, + List tphsClass) { // 1. check if there are any simple cycles like L set L=R and: // * remove both constraints @@ -89,7 +90,7 @@ public class Simplify { System.out.println("AFTER DELETE ALL CONST: " + allCons.size()); allCons.forEach(c -> System.out.println(c.toString())); System.out.println("----------------"); - HashMap> result = new HashMap<>(); + Map> result = new HashMap<>(); // check if there is any long cycle (e.g. A equalTPHs = getEqualsTPHs(result, c); + Set equalTPHs = getEqualsTPHs(result, c); TPHConstraint constraint = getKeyConstraint(result, c); equalTPHs.add(c.getLeft()); equalTPHs.add(c.getRight()); @@ -454,6 +455,11 @@ public class Simplify { return result; } + private static boolean isTPHInResEqual(Map> result, String left) { + // TODO Auto-generated method stub + return false; + } + private static boolean containsConstraint(ArrayList allCons, TPHConstraint c) { for(TPHConstraint con:allCons) { if(c.getLeft().equals(con.getLeft()) && c.getRight().equals(c.getRight())) { @@ -475,8 +481,8 @@ public class Simplify { } - public static HashMap> simplifyConstraintsClass(TPHExtractor tphExtractor, - ArrayList tphsClass) { + public static Map> simplifyConstraintsClass(TPHExtractor tphExtractor, + List tphsClass) { // all constraints that will be simplified ArrayList allCons = tphExtractor.allCons; ArrayList consToRemove = new ArrayList<>(); @@ -505,7 +511,7 @@ public class Simplify { int size = allCons.size(); - HashMap> result = new HashMap<>(); + HashMap> result = new HashMap<>(); // check if there is any long cycle (e.g. A equalTPHs = getEqualsTPHs(result, c); + Set equalTPHs = getEqualsTPHs(result, c); TPHConstraint constraint = getKeyConstraint(result, c); equalTPHs.add(c.getLeft()); equalTPHs.add(c.getRight()); @@ -721,8 +727,8 @@ public class Simplify { return false; } - private static boolean isTphInEqualSet(HashMap> result, String tph) { - for (HashSet hs : result.values()) { + private static boolean isTphInEqualSet(Map> result, String tph) { + for (Set hs : result.values()) { if (hs.contains(tph)) return true; } @@ -766,8 +772,8 @@ public class Simplify { return null; } - private static boolean isTPHInResEqual(HashMap> result, String left) { - for (HashSet eq : result.values()) { + private static boolean isTPHInResEqual(HashMap> result, String left) { + for (Set eq : result.values()) { if (eq.contains(left)) { return true; } @@ -796,8 +802,8 @@ public class Simplify { } } - public static HashMap> simplifyContraints( - HashMap> allConstraints) { + public static Map> simplifyContraints( + Map> allConstraints) { // 1. check if there are any cycles like L set L=R and: // * remove both constraints @@ -842,11 +848,11 @@ public class Simplify { System.out.println("AFTER DELETE ALL CONST: " + allCons.size()); allCons.forEach(c -> System.out.println(c.toString())); System.out.println("----------------"); - HashMap> result = new HashMap<>(); + Map> result = new HashMap<>(); for (TPHConstraint c : allCons) { if (c.getRel() == Relation.EQUAL) { - HashSet equalTPHs = getEqualsTPHs(result, c); + Set equalTPHs = getEqualsTPHs(result, c); TPHConstraint constraint = getKeyConstraint(result, c); equalTPHs.add(c.getLeft()); equalTPHs.add(c.getRight()); @@ -986,7 +992,7 @@ public class Simplify { return null; } - private static boolean isTPHInConstraint(HashMap> result, String sub) { + private static boolean isTPHInConstraint(Map> result, String sub) { for (TPHConstraint c : result.keySet()) { if (c.getLeft().equals(sub)) return true; @@ -1017,7 +1023,7 @@ public class Simplify { return new ExtendsConstraint(toFind.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS); } - private static TPHConstraint getKeyConstraint(HashMap> result, + private static TPHConstraint getKeyConstraint(Map> result, TPHConstraint toFind) { for (TPHConstraint c : result.keySet()) { @@ -1028,7 +1034,7 @@ public class Simplify { return new ExtendsConstraint(toFind.getRight(), Type.getInternalName(Object.class), Relation.EXTENDS); } - private static HashSet getEqualsTPHs(HashMap> result, TPHConstraint toFind) { + private static Set getEqualsTPHs(Map> result, TPHConstraint toFind) { for (TPHConstraint c : result.keySet()) { if (c.containTPH(toFind.getLeft()) || c.containTPH(toFind.getRight())) return result.get(c); diff --git a/src/main/java/de/dhbwstuttgart/bytecode/utilities/SimplifyResult.java b/src/main/java/de/dhbwstuttgart/bytecode/utilities/SimplifyResult.java deleted file mode 100644 index 6517c2bc..00000000 --- a/src/main/java/de/dhbwstuttgart/bytecode/utilities/SimplifyResult.java +++ /dev/null @@ -1,42 +0,0 @@ -/** - * - */ -package de.dhbwstuttgart.bytecode.utilities; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; - -import de.dhbwstuttgart.bytecode.constraint.TPHConstraint; -import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder; - -/** - * @author fayez - * - */ -public class SimplifyResult { - private final ArrayList classConstraints; - private final ArrayList tphsClass; - private final HashMap>> methodsConstraints; - - public SimplifyResult(ArrayList classConstraints, ArrayList tphsClass, - HashMap>> methodsConstraints) { - super(); - this.classConstraints = classConstraints; - this.tphsClass = tphsClass; - this.methodsConstraints = methodsConstraints; - } - - public ArrayList getClassConstraints() { - return classConstraints; - } - - public HashMap>> getMethodsConstraints() { - return methodsConstraints; - } - - public ArrayList getTphsClass() { - return tphsClass; - } - -} diff --git a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java index e7af8af2..b636ecfb 100644 --- a/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java +++ b/src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java @@ -4,7 +4,9 @@ package de.dhbwstuttgart.core; import de.dhbwstuttgart.bytecode.BytecodeGen; import de.dhbwstuttgart.bytecode.Exception.BytecodeGeneratorError; -import de.dhbwstuttgart.bytecode.utilities.SimplifyResult; +import de.dhbwstuttgart.bytecode.simplifyRes.SimplifyResult; +import de.dhbwstuttgart.bytecode.simplifyRes.SimplifyResultFinder; +import de.dhbwstuttgart.bytecode.simplifyRes.SimplifyResultSourceFile; import de.dhbwstuttgart.environment.CompilationEnvironment; import de.dhbwstuttgart.parser.JavaTXParser; import de.dhbwstuttgart.parser.NullToken; @@ -654,16 +656,39 @@ public class JavaTXCompiler { SourceFile ret = generator.convert(tree, environment.packageCrawler); return ret; } + + public List getSimplifyResultsForAllSourceFiles() throws ClassNotFoundException{ + List result = new ArrayList<>(); + for(File f : sourceFiles.keySet()) { + SourceFile sf = sourceFiles.get(f); + List typeinferenceResult = this.typeInference(); + SimplifyResultFinder sResFinder = new SimplifyResultFinder(sf, typeinferenceResult); + SimplifyResultSourceFile simplifyResOfSF = sResFinder.findSimplifyRes(); + result.add(simplifyResOfSF); + } + return result; + } + + public List getSimplifyResultsForAllSourceFiles(List typeinferenceResult) throws ClassNotFoundException{ + List result = new ArrayList<>(); + for(File f : sourceFiles.keySet()) { + SourceFile sf = sourceFiles.get(f); + SimplifyResultFinder sResFinder = new SimplifyResultFinder(sf, typeinferenceResult); + SimplifyResultSourceFile simplifyResOfSF = sResFinder.findSimplifyRes(); + result.add(simplifyResOfSF); + } + return result; + } + // um pfad erweitern public void generateBytecode(String path) throws ClassNotFoundException, IOException, BytecodeGeneratorError { for(File f : sourceFiles.keySet()) { HashMap classFiles = new HashMap<>(); SourceFile sf = sourceFiles.get(f); List typeinferenceResult = this.typeInference(); - BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult,sf,path); -// BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult.get(0)); + List simplifyResultsForAllSourceFiles = getSimplifyResultsForAllSourceFiles(typeinferenceResult); + BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult,simplifyResultsForAllSourceFiles,sf,path); bytecodeGen.visit(sf); - this.simplifyResultsSF.add(bytecodeGen.getSimplifyResultsList()); this.writeClassFile(bytecodeGen.getClassFiles(), path); } } diff --git a/src/test/java/bytecode/FieldTphConsMethTest.java b/src/test/java/bytecode/FieldTphConsMethTest.java index 382c31e4..4ef61617 100644 --- a/src/test/java/bytecode/FieldTphConsMethTest.java +++ b/src/test/java/bytecode/FieldTphConsMethTest.java @@ -28,12 +28,13 @@ public class FieldTphConsMethTest { path = System.getProperty("user.dir")+"/src/test/resources/bytecode/javFiles/FieldTphConsMeth.jav"; fileToTest = new File(path); compiler = new JavaTXCompiler(fileToTest); + compiler.getSimplifyResultsForAllSourceFiles(); compiler.generateBytecode(System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/"); pathToClassFile = System.getProperty("user.dir")+"/src/test/resources/testBytecode/generatedBC/"; loader = new URLClassLoader(new URL[] {new URL("file://"+pathToClassFile)}); classToTest = loader.loadClass("FieldTphConsMeth"); } - + @Test public void test() throws Exception { instanceOfClass = classToTest.getConstructor(Object.class).newInstance("C");