Generic Method inserts.
This commit is contained in:
parent
f6669f8c13
commit
7f29b39195
@ -8,6 +8,7 @@ import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
|
||||
import de.dhbwstuttgart.bytecode.constraint.TPHConstraint;
|
||||
import de.dhbwstuttgart.syntaxtree.Method;
|
||||
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
||||
|
||||
/**
|
||||
@ -34,6 +35,11 @@ public class SimplifyResult {
|
||||
public HashMap<String, HashMap<TPHConstraint, HashSet<String>>> getMethodsConstraints() {
|
||||
return methodsConstraints;
|
||||
}
|
||||
|
||||
public HashMap<TPHConstraint, HashSet<String>> getMethodsConstraints(String methodReturnType) {
|
||||
|
||||
return methodsConstraints.get(methodReturnType);
|
||||
}
|
||||
|
||||
public ArrayList<String> getTphsClass() {
|
||||
return tphsClass;
|
||||
|
@ -58,6 +58,7 @@ 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<>();
|
||||
@ -73,11 +74,13 @@ public class JavaTXCompiler {
|
||||
|
||||
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 {
|
||||
@ -85,6 +88,7 @@ public class JavaTXCompiler {
|
||||
for (File s : sources) {
|
||||
sourceFiles.put(s, parse(s));
|
||||
}
|
||||
INSTANCE = this;
|
||||
}
|
||||
|
||||
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException {
|
||||
@ -654,20 +658,26 @@ public class JavaTXCompiler {
|
||||
SourceFile ret = generator.convert(tree, environment.packageCrawler);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// um pfad erweitern
|
||||
public void generateBytecode(String path) throws ClassNotFoundException, IOException, BytecodeGeneratorError {
|
||||
for(File f : sourceFiles.keySet()) {
|
||||
HashMap<String,byte[]> classFiles = new HashMap<>();
|
||||
SourceFile sf = sourceFiles.get(f);
|
||||
List<ResultSet> typeinferenceResult = this.typeInference();
|
||||
BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult,sf,path);
|
||||
// BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult.get(0));
|
||||
bytecodeGen.visit(sf);
|
||||
this.simplifyResultsSF.add(bytecodeGen.getSimplifyResultsList());
|
||||
this.writeClassFile(bytecodeGen.getClassFiles(), path);
|
||||
generateBytecodForFile(path, classFiles, sf, typeinferenceResult);
|
||||
}
|
||||
}
|
||||
|
||||
public void generateBytecodForFile(String path, HashMap<String, byte[]> classFiles, SourceFile sf,
|
||||
List<ResultSet> typeinferenceResult) throws IOException {
|
||||
BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult,sf,path);
|
||||
// BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult.get(0));
|
||||
bytecodeGen.visit(sf);
|
||||
this.simplifyResultsSF.add(bytecodeGen.getSimplifyResultsList());
|
||||
this.writeClassFile(bytecodeGen.getClassFiles(), path);
|
||||
}
|
||||
|
||||
private void writeClassFile(HashMap<String, byte[]> classFiles, String path) throws IOException {
|
||||
FileOutputStream output;
|
||||
for(String name : classFiles.keySet()) {
|
||||
|
@ -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.*;
|
||||
|
||||
|
||||
@ -15,11 +19,21 @@ 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,32 @@
|
||||
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.utilities.SimplifyResult;
|
||||
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.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:
|
||||
@ -31,60 +52,116 @@ public class TypeInsertFactory {
|
||||
ResultSet resultSet) {
|
||||
ResolvedType resolvedType = resultSet.resolveType(type);
|
||||
TypeInsertPoint insertPoint = new TypeInsertPoint(offset,
|
||||
new TypeToInsertString(resolvedType.resolvedType).insert);
|
||||
new TypeToInsertString(resolvedType.resolvedType).insert);
|
||||
|
||||
List<List<HashMap<String, SimplifyResult>>> simplifyResults = JavaTXCompiler.INSTANCE.getSimplifyResults();
|
||||
for (List<HashMap<String, SimplifyResult>> simplifyResultsEntries : simplifyResults) {
|
||||
for (HashMap<String, SimplifyResult> simplifyResultsEntriesEntries : simplifyResultsEntries) {
|
||||
if (simplifyResultsEntriesEntries.get(cl.getClassName().toString()) != null) {
|
||||
SimplifyResult genericResult = simplifyResultsEntriesEntries.get(cl.getClassName().toString());
|
||||
return new TypeInsert(insertPoint, createGenericInsert(genericResult, cl, m, resultSet), resolvedType.getResultPair());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return new TypeInsert(insertPoint, new HashSet<>(), resolvedType.getResultPair());
|
||||
}
|
||||
|
||||
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=",";
|
||||
}else{
|
||||
offset = cl.getGenerics().getOffset();
|
||||
insert += "<";
|
||||
end = ">";
|
||||
private static Set<TypeInsertPoint> createGenericInsert(SimplifyResult genericResult, ClassOrInterface cl, Method m, ResultSet resultSet){
|
||||
Set<TypeInsertPoint> result = createGenericClassInserts(genericResult, cl);
|
||||
|
||||
for (Method method : cl.getMethods()) {
|
||||
|
||||
for (Entry<String, HashMap<TPHConstraint, HashSet<String>>> resultFromApi : genericResult.getMethodsConstraints().entrySet()) {
|
||||
createMethodConstraints(method, resultFromApi);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//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<>());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//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 += " & ";
|
||||
}
|
||||
}
|
||||
if(it.hasNext())insert+=",";
|
||||
}
|
||||
return new TypeInsertPoint(offset, insert + end);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Set<TypeInsertPoint> createMethodConstraints(Method method, Entry<String, HashMap<TPHConstraint, HashSet<String>>> resultFromApi) {
|
||||
Set<TypeInsertPoint> result = new HashSet<>();
|
||||
Token offset = new GenericDeclarationList(method.getGenerics(), new NullToken()).getOffset();
|
||||
|
||||
if (! (resultFromApi.getKey().contains(method.getName()))) {
|
||||
return result;
|
||||
}
|
||||
|
||||
List<TPHConstraint> methodConstraints = new ArrayList<>(resultFromApi.getValue().keySet());
|
||||
List<String> tphsMethod =
|
||||
new ArrayList<String>(((Collection<HashSet<String>>)resultFromApi.getValue().values()).stream().map(a -> a.stream()).flatMap(n -> n).collect(Collectors.toList()));
|
||||
|
||||
if (methodConstraints.size() == 0 && tphsMethod.size() == 0) {
|
||||
result.add(new TypeInsertPoint(offset, ""));
|
||||
return result;
|
||||
}
|
||||
|
||||
String insert = " <";
|
||||
|
||||
for (TPHConstraint genericInsertConstraint : methodConstraints) {
|
||||
insert += genericInsertConstraint.getLeft() + " extends " + genericInsertConstraint.getRight() + ", ";
|
||||
}
|
||||
|
||||
List<String> notExtendedConstraints = tphsMethod;
|
||||
for (TPHConstraint genericInsertConstraint : methodConstraints) {
|
||||
for (String gen : tphsMethod) {
|
||||
if (genericInsertConstraint.getLeft().equals(gen)) {
|
||||
notExtendedConstraints.remove(gen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String notExtendedConstraint : notExtendedConstraints) {
|
||||
insert += notExtendedConstraint + ", ";
|
||||
}
|
||||
|
||||
insert = insert.substring(0, insert.length() -2);
|
||||
insert += ">";
|
||||
|
||||
result.add(new TypeInsertPoint(offset, insert));
|
||||
return result;
|
||||
}
|
||||
|
||||
private static Set<TypeInsertPoint> createGenericClassInserts(SimplifyResult genericResult, ClassOrInterface cl) {
|
||||
Set<TypeInsertPoint> result = new HashSet<>();
|
||||
Token offset = cl.getGenerics().getOffset();
|
||||
|
||||
List<TPHConstraint> classConstraints = new ArrayList<TPHConstraint>(genericResult.getClassConstraints());
|
||||
List<String> tphsClass = new ArrayList<>(genericResult.getTphsClass());
|
||||
|
||||
if (classConstraints.size() == 0 && tphsClass.size() == 0) {
|
||||
result.add(new TypeInsertPoint(offset, ""));
|
||||
return result;
|
||||
}
|
||||
|
||||
String insert = " <";
|
||||
|
||||
for (TPHConstraint genericInsertConstraint : classConstraints) {
|
||||
insert += genericInsertConstraint.getLeft() + " extends " + genericInsertConstraint.getRight() + ", ";
|
||||
}
|
||||
|
||||
Set<String> notExtendedConstraints = new HashSet<>(genericResult.getTphsClass());
|
||||
for (TPHConstraint genericInsertConstraint : classConstraints) {
|
||||
for (String gen : tphsClass) {
|
||||
if (genericInsertConstraint.getLeft().equals(gen)) {
|
||||
notExtendedConstraints.remove(gen);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (String notExtendedConstraint : notExtendedConstraints) {
|
||||
insert += notExtendedConstraint + ", ";
|
||||
}
|
||||
|
||||
insert = insert.substring(0, insert.length() -2);
|
||||
insert += ">";
|
||||
|
||||
result.add(new TypeInsertPoint(offset, insert));
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
class TypeToInsertString implements ResultSetVisitor{
|
||||
|
Loading…
Reference in New Issue
Block a user