Merge branch 'bigRefactoring' into simplifyRes
# Conflicts: # src/main/java/de/dhbwstuttgart/bytecode/utilities/SimplifyResult.java # src/main/java/de/dhbwstuttgart/core/JavaTXCompiler.java
This commit is contained in:
commit
5b75250fcf
@ -3,8 +3,11 @@
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.simplifyRes;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import com.google.common.collect.Collections2;
|
||||
|
||||
/**
|
||||
* @author fayez
|
||||
*
|
||||
@ -12,7 +15,9 @@ import java.util.List;
|
||||
public class GenericGeneratorResultsForAllMethods {
|
||||
private final List<MethodAndConstraints> methodsAndConstraints;
|
||||
|
||||
|
||||
public GenericGeneratorResultsForAllMethods() {
|
||||
this(Collections.emptyList());
|
||||
}
|
||||
/**
|
||||
* @param methodsAndConstraints
|
||||
*/
|
||||
|
@ -40,9 +40,11 @@ public class GenericGenratorResultForSourceFile {
|
||||
public GenericsGeneratorResultForClass getSimplifyResultsByName(String pkgName, String name) {
|
||||
|
||||
if (this.pkgName.equals(pkgName)) {
|
||||
return genericGeneratorResultForAllClasses.stream().filter(sr -> sr.getClassName().equals(name)).findAny()
|
||||
.orElseThrow(() -> new NoSuchElementException(
|
||||
"Simplify results for the class " + pkgName + "." + name + " are not found"));
|
||||
return genericGeneratorResultForAllClasses
|
||||
.stream()
|
||||
.filter(sr -> sr.getClassName().equals(name))
|
||||
.findAny()
|
||||
.orElse(new GenericsGeneratorResultForClass(name));
|
||||
}
|
||||
throw new NoSuchElementException("Simplify results for the class " + pkgName + "." + name + " are not found");
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
*/
|
||||
package de.dhbwstuttgart.bytecode.simplifyRes;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -14,6 +15,9 @@ public class GenericsGeneratorResultForClass {
|
||||
private final List<GenericsGeneratorResult> classConstraints;
|
||||
private final GenericGeneratorResultsForAllMethods methodsAndTheirConstraints;
|
||||
|
||||
public GenericsGeneratorResultForClass(String className) {
|
||||
this(className, Collections.emptyList(), new GenericGeneratorResultsForAllMethods());
|
||||
}
|
||||
/**
|
||||
* @param className
|
||||
* @param classConstraints
|
||||
@ -52,6 +56,9 @@ public class GenericsGeneratorResultForClass {
|
||||
.anyMatch(i -> i.equals(id));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public List<GenericsGeneratorResult> getMethodConstraintsByID(String id) {
|
||||
return methodsAndTheirConstraints.getMethodsAndConstraints().stream().filter(mc -> mc.getMethodID().equals(id))
|
||||
.findFirst().get().getConstraints();
|
||||
|
@ -59,21 +59,29 @@ import org.apache.commons.io.output.NullOutputStream;
|
||||
|
||||
public class JavaTXCompiler {
|
||||
|
||||
public static JavaTXCompiler INSTANCE;
|
||||
final CompilationEnvironment environment;
|
||||
Boolean resultmodel = true;
|
||||
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
||||
Boolean log = true; // gibt an ob ein Log-File nach
|
||||
// System.getProperty("user.dir")+"src/test/java/logFiles" geschrieben werden
|
||||
// soll?
|
||||
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+"src/test/java/logFiles" geschrieben werden soll?
|
||||
public volatile UnifyTaskModel usedTasks = new UnifyTaskModel();
|
||||
|
||||
/**
|
||||
* Äußerste Liste der Source-Files.
|
||||
* Danach Liste der Klassen in Source File.
|
||||
* Danach Map Klassenname
|
||||
*/
|
||||
private List<List<HashMap<String, SimplifyResult>>> simplifyResultsSF = new ArrayList<>();
|
||||
|
||||
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
||||
this(Arrays.asList(sourceFile));
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
|
||||
this(sourceFile);
|
||||
this.log = log;
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
public JavaTXCompiler(List<File> sources) throws IOException, ClassNotFoundException {
|
||||
@ -81,6 +89,7 @@ public class JavaTXCompiler {
|
||||
for (File s : sources) {
|
||||
sourceFiles.put(s, parse(s));
|
||||
}
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException {
|
||||
@ -93,8 +102,8 @@ public class JavaTXCompiler {
|
||||
for (File forSourceFile : sourceFiles.keySet())
|
||||
for (JavaClassName name : sourceFiles.get(forSourceFile).getImports()) {
|
||||
//TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
|
||||
ClassOrInterface importedClass = ASTFactory
|
||||
.createClass(ClassLoader.getSystemClassLoader().loadClass(name.toString()));
|
||||
ClassOrInterface importedClass = ASTFactory.createClass(
|
||||
ClassLoader.getSystemClassLoader().loadClass(name.toString()));
|
||||
importedClasses.add(importedClass);
|
||||
}
|
||||
allClasses.addAll(importedClasses);
|
||||
@ -102,6 +111,18 @@ public class JavaTXCompiler {
|
||||
return new TYPE(sourceFiles.values(), allClasses).getConstraints();
|
||||
}
|
||||
|
||||
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
|
||||
//PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal hinzugefuegt werden
|
||||
//List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
|
||||
Set<ClassOrInterface> allClasses = new HashSet<>();
|
||||
|
||||
/* PL 2018-09-19 geloescht werden bereits in typeInference hinzugefuegt
|
||||
}
|
||||
allClasses.addAll(importedClasses);
|
||||
|
||||
return new TYPE(sourceFiles.values(), allClasses).getConstraints();
|
||||
}
|
||||
|
||||
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
|
||||
// PL 2018-09-18: List durch Set ersetzt, damit die Klassen nur einmal
|
||||
// hinzugefuegt werden
|
||||
@ -711,6 +732,20 @@ public class JavaTXCompiler {
|
||||
return ret;
|
||||
}
|
||||
|
||||
public void generateBytecodForFile(String path, HashMap<String, byte[]> classFiles, SourceFile sf,
|
||||
List<ResultSet> typeinferenceResult) throws IOException {
|
||||
try {
|
||||
List<GenericGenratorResultForSourceFile> genericResults = getGeneratedGenericResultsForAllSourceFiles(typeinferenceResult);
|
||||
BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult, genericResults, sf,path);
|
||||
bytecodeGen.visit(sf);
|
||||
this.writeClassFile(bytecodeGen.getClassFiles(), path);
|
||||
} catch (ClassNotFoundException e) {
|
||||
// TODO Auto-generated catch block
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public List<GenericGenratorResultForSourceFile> getGeneratedGenericResultsForAllSourceFiles()
|
||||
throws ClassNotFoundException {
|
||||
List<GenericGenratorResultForSourceFile> result = new ArrayList<>();
|
||||
|
@ -2,6 +2,10 @@ package de.dhbwstuttgart.syntaxtree;
|
||||
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
|
||||
@ -16,10 +20,20 @@ public class GenericDeclarationList extends SyntaxTreeNode implements Iterable<G
|
||||
private Token offsetOfLastElement;
|
||||
private List<GenericTypeVar> gtvs = new ArrayList<>();
|
||||
|
||||
public GenericDeclarationList(List<GenericTypeVar> values, Token endOffset) {
|
||||
@SuppressWarnings("unchecked")
|
||||
public GenericDeclarationList(Iterable<? extends GenericTypeVar> values, Token endOffset) {
|
||||
super(endOffset);
|
||||
gtvs = isListOfGenericTypeVar(values) ? (List<GenericTypeVar>)values : Lists.newArrayList(values);
|
||||
this.offsetOfLastElement = endOffset;
|
||||
}
|
||||
|
||||
public GenericDeclarationList(ArrayList<GenericTypeVar> values, Token endOffset) {
|
||||
super(endOffset);
|
||||
gtvs = values;
|
||||
this.offsetOfLastElement = endOffset;
|
||||
this.offsetOfLastElement = endOffset; }
|
||||
|
||||
private boolean isListOfGenericTypeVar(Iterable<? extends GenericTypeVar> values) {
|
||||
return values instanceof List && ((List<?>)values).size() > 0 && ((List<?>)values).get(0) instanceof GenericTypeVar;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1,11 +1,37 @@
|
||||
package de.dhbwstuttgart.typedeployment;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.Exception.BytecodeGeneratorError;
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
import de.dhbwstuttgart.bytecode.descriptor.TypeToDescriptor;
|
||||
import de.dhbwstuttgart.bytecode.simplifyRes.GenericGenratorResultForSourceFile;
|
||||
import de.dhbwstuttgart.bytecode.simplifyRes.GenericsGeneratorResult;
|
||||
import de.dhbwstuttgart.bytecode.simplifyRes.GenericsGeneratorResultForClass;
|
||||
import de.dhbwstuttgart.bytecode.utilities.MethodUtility;
|
||||
import de.dhbwstuttgart.bytecode.utilities.Resolver;
|
||||
import de.dhbwstuttgart.core.JavaTXCompiler;
|
||||
import de.dhbwstuttgart.parser.NullToken;
|
||||
import de.dhbwstuttgart.syntaxtree.*;
|
||||
import de.dhbwstuttgart.syntaxtree.statement.NewArray;
|
||||
import de.dhbwstuttgart.syntaxtree.type.*;
|
||||
import de.dhbwstuttgart.typeinference.result.*;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
|
||||
import org.antlr.v4.parse.ANTLRParser.action_return;
|
||||
import org.antlr.v4.parse.ANTLRParser.block_return;
|
||||
import org.antlr.v4.parse.ANTLRParser.labeledAlt_return;
|
||||
import org.antlr.v4.parse.ANTLRParser.parserRule_return;
|
||||
import org.antlr.v4.runtime.Token;
|
||||
import org.objectweb.asm.Type;
|
||||
import org.stringtemplate.v4.compiler.STParser.ifstat_return;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.Serializable;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.print.DocFlavor.STRING;
|
||||
import javax.security.auth.kerberos.KerberosKey;
|
||||
|
||||
/**
|
||||
* TODO:
|
||||
@ -29,61 +55,89 @@ public class TypeInsertFactory {
|
||||
|
||||
public static TypeInsert createInsertPoints(RefTypeOrTPHOrWildcardOrGeneric type, Token offset, ClassOrInterface cl, Method m,
|
||||
ResultSet resultSet) {
|
||||
|
||||
try {
|
||||
ResolvedType resolvedType = resultSet.resolveType(type);
|
||||
TypeInsertPoint insertPoint = new TypeInsertPoint(offset,
|
||||
new TypeToInsertString(resolvedType.resolvedType).insert);
|
||||
List<GenericGenratorResultForSourceFile> simplifyResults = JavaTXCompiler.INSTANCE.getGeneratedGenericResultsForAllSourceFiles();
|
||||
for (GenericGenratorResultForSourceFile simplifyResultsEntries : simplifyResults) {
|
||||
GenericsGeneratorResultForClass genericResultsForClass = simplifyResultsEntries.getSimplifyResultsByName("", cl.getClassName().toString());
|
||||
return new TypeInsert(insertPoint, createGenericInsert(genericResultsForClass, cl, m, resultSet), resolvedType.getResultPair());
|
||||
}
|
||||
|
||||
return new TypeInsert(insertPoint, new HashSet<>(), resolvedType.getResultPair());
|
||||
} catch (ClassNotFoundException e) {
|
||||
e.printStackTrace();
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static TypeInsertPoint createGenericInsert(Set<GenericInsertPair> toInsert, ClassOrInterface cl, Method m){
|
||||
//Momentan wird Methode ignoriert. Parameter werden immer als Klassenparameter angefügt:
|
||||
//Offset zum Einstzen bestimmen:
|
||||
Token offset;
|
||||
String insert = "";
|
||||
String end;
|
||||
if(cl.getGenerics().iterator().hasNext()){
|
||||
//offset = cl.getGenerics().iterator().next().getOffset();
|
||||
offset = cl.getGenerics().getOffset();
|
||||
end=",";
|
||||
private static synchronized Set<TypeInsertPoint> createGenericInsert(GenericsGeneratorResultForClass genericResult, ClassOrInterface cl, Method m, ResultSet resultSet){
|
||||
Set<TypeInsertPoint> result = createGenericClassInserts(genericResult, cl);
|
||||
|
||||
for (Method method : cl.getMethods()) {
|
||||
Resolver resolver = new Resolver(resultSet);
|
||||
List<GenericsGeneratorResult> methodConstraints = genericResult.getMethodConstraintsByID(MethodUtility.createID(resolver, method));
|
||||
createMethodConstraints(method, methodConstraints);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Set<TypeInsertPoint> createMethodConstraints(Method method, List<GenericsGeneratorResult> constraints) {
|
||||
Set<TypeInsertPoint> result = new HashSet<>();
|
||||
Token offset = new GenericDeclarationList(method.getGenerics(), new NullToken()).getOffset();
|
||||
|
||||
if (constraints.size() == 0) {
|
||||
result.add(new TypeInsertPoint(offset, ""));
|
||||
return result;
|
||||
}
|
||||
|
||||
String insert = " <";
|
||||
|
||||
for (GenericsGeneratorResult genericInsertConstraint : constraints) {
|
||||
if (genericInsertConstraint.getConstraint().getRight().equals(Type.getInternalName(Object.class))) {
|
||||
insert += genericInsertConstraint.getConstraint().getLeft();
|
||||
} else {
|
||||
offset = cl.getGenerics().getOffset();
|
||||
insert += "<";
|
||||
end = ">";
|
||||
}
|
||||
|
||||
//Alle einzusetzenden Generics und deren Bounds bestimmen:
|
||||
HashMap<TypePlaceholder, HashSet<TypePlaceholder>> genericsAndBounds = new HashMap<>();
|
||||
for(GenericInsertPair p : toInsert){
|
||||
if(!genericsAndBounds.containsKey(p.TA1)){
|
||||
genericsAndBounds.put((TypePlaceholder) p.TA1, new HashSet<>());
|
||||
}
|
||||
if(p.TA2 != null){
|
||||
genericsAndBounds.get(p.TA1).add((TypePlaceholder) p.TA2);
|
||||
if(!genericsAndBounds.containsKey(p.TA2)){
|
||||
genericsAndBounds.put((TypePlaceholder) p.TA2, new HashSet<>());
|
||||
}
|
||||
insert += genericInsertConstraint.getConstraint().getLeft() + " extends " + genericInsertConstraint.getConstraint().getRight() + ", ";
|
||||
}
|
||||
}
|
||||
|
||||
//String zum Einsetzen (Generics mit bounds) generieren:
|
||||
Iterator<TypePlaceholder> it = genericsAndBounds.keySet().iterator();
|
||||
if(! it.hasNext())return new TypeInsertPoint(offset, "");
|
||||
while(it.hasNext()){
|
||||
TypePlaceholder tph = it.next();
|
||||
insert += tph.getName();
|
||||
Set<TypePlaceholder> bounds = genericsAndBounds.get(tph);
|
||||
if(bounds.size() > 0){
|
||||
insert += " extends ";
|
||||
Iterator<TypePlaceholder> boundIt = bounds.iterator();
|
||||
while(boundIt.hasNext()){
|
||||
TypePlaceholder bound = boundIt.next();
|
||||
insert += bound.getName();
|
||||
if(boundIt.hasNext())insert += " & ";
|
||||
insert = insert.substring(0, insert.length() -2);
|
||||
insert += ">";
|
||||
|
||||
result.add(new TypeInsertPoint(offset, insert));
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Set<TypeInsertPoint> createGenericClassInserts(GenericsGeneratorResultForClass genericResult, ClassOrInterface cl) {
|
||||
Set<TypeInsertPoint> result = new HashSet<>();
|
||||
Token offset = cl.getGenerics().getOffset();
|
||||
|
||||
List<GenericsGeneratorResult> classConstraints = genericResult.getClassConstraints();
|
||||
|
||||
if (classConstraints.size() == 0) {
|
||||
result.add(new TypeInsertPoint(offset, ""));
|
||||
return result;
|
||||
}
|
||||
|
||||
String insert = " <";
|
||||
|
||||
for (GenericsGeneratorResult genericInsertConstraint : classConstraints) {
|
||||
if (genericInsertConstraint.getConstraint().getRight().equals(Type.getInternalName(Object.class))) {
|
||||
insert += genericInsertConstraint.getConstraint().getLeft();
|
||||
} else {
|
||||
insert += genericInsertConstraint.getConstraint().getLeft() + " extends " + genericInsertConstraint.getConstraint().getRight() + ", ";
|
||||
}
|
||||
}
|
||||
if(it.hasNext())insert+=",";
|
||||
}
|
||||
return new TypeInsertPoint(offset, insert + end);
|
||||
|
||||
insert = insert.substring(0, insert.length() -2);
|
||||
insert += ">";
|
||||
|
||||
result.add(new TypeInsertPoint(offset, insert));
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user