forked from JavaTX/JavaCompilerCore
geändert: src/de/dhbwstuttgart/core/JavaTXCompiler.java
geändert: src/de/dhbwstuttgart/strucTypes/visitor/InferTypes.java geändert: src/de/dhbwstuttgart/typeinference/unify/RuleSet.java nach merge mit plugin-Branch
This commit is contained in:
parent
4919dd34b2
commit
55f6fe47ac
@ -14,11 +14,6 @@ import java.util.stream.Collectors;
|
|||||||
import de.dhbwstuttgart.bytecode.BytecodeGen;
|
import de.dhbwstuttgart.bytecode.BytecodeGen;
|
||||||
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
import de.dhbwstuttgart.environment.CompilationEnvironment;
|
||||||
import de.dhbwstuttgart.parser.JavaTXParser;
|
import de.dhbwstuttgart.parser.JavaTXParser;
|
||||||
<<<<<<< HEAD
|
|
||||||
=======
|
|
||||||
import de.dhbwstuttgart.parser.NullToken;
|
|
||||||
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
|
||||||
>>>>>>> e0d5699ae7f35d8b7af47aeb4adfb33a5167cd00
|
|
||||||
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
|
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.SyntaxTreeGenerator;
|
||||||
import de.dhbwstuttgart.parser.antlr.Java8Parser.CompilationUnitContext;
|
import de.dhbwstuttgart.parser.antlr.Java8Parser.CompilationUnitContext;
|
||||||
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
import de.dhbwstuttgart.parser.scope.GenericsRegistry;
|
||||||
@ -46,16 +41,11 @@ import de.dhbwstuttgart.typeinference.result.ResultSet;
|
|||||||
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
|
import de.dhbwstuttgart.typeinference.typeAlgo.TYPE;
|
||||||
import de.dhbwstuttgart.typeinference.unify.RuleSet;
|
import de.dhbwstuttgart.typeinference.unify.RuleSet;
|
||||||
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
|
import de.dhbwstuttgart.typeinference.unify.TypeUnify;
|
||||||
<<<<<<< HEAD
|
|
||||||
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
import de.dhbwstuttgart.typeinference.unify.interfaces.IFiniteClosure;
|
||||||
=======
|
|
||||||
import de.dhbwstuttgart.typeinference.unify.distributeVariance;
|
|
||||||
>>>>>>> e0d5699ae7f35d8b7af47aeb4adfb33a5167cd00
|
|
||||||
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
import de.dhbwstuttgart.typeinference.unify.model.FiniteClosure;
|
||||||
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;
|
||||||
|
|
||||||
<<<<<<< HEAD
|
|
||||||
public class JavaTXCompiler {
|
public class JavaTXCompiler {
|
||||||
|
|
||||||
final CompilationEnvironment environment;
|
final CompilationEnvironment environment;
|
||||||
@ -187,229 +177,4 @@ public class JavaTXCompiler {
|
|||||||
SourceFile ret = generator.convert(tree, environment.packageCrawler);
|
SourceFile ret = generator.convert(tree, environment.packageCrawler);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
=======
|
}
|
||||||
import java.io.File;
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.FileWriter;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.util.*;
|
|
||||||
import java.util.stream.Collectors;
|
|
||||||
import java.util.stream.Stream;
|
|
||||||
|
|
||||||
public class JavaTXCompiler {
|
|
||||||
|
|
||||||
final CompilationEnvironment environment;
|
|
||||||
public final Map<File, SourceFile> sourceFiles = new HashMap<>();
|
|
||||||
Boolean log = true; //gibt an ob ein Log-File nach System.getProperty("user.dir")+"/test/logFiles/log" geschrieben werden soll?
|
|
||||||
|
|
||||||
public JavaTXCompiler(File sourceFile) throws IOException, ClassNotFoundException {
|
|
||||||
this(Arrays.asList(sourceFile));
|
|
||||||
}
|
|
||||||
|
|
||||||
public JavaTXCompiler(File sourceFile, Boolean log) throws IOException, ClassNotFoundException {
|
|
||||||
this(sourceFile);
|
|
||||||
this.log = log;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JavaTXCompiler(List<File> sources) throws IOException, ClassNotFoundException {
|
|
||||||
environment = new CompilationEnvironment(sources);
|
|
||||||
for (File s : sources) {
|
|
||||||
sourceFiles.put(s, parse(s));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public ConstraintSet<Pair> getConstraints() throws ClassNotFoundException {
|
|
||||||
List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
|
|
||||||
for (SourceFile sf : sourceFiles.values()) {
|
|
||||||
allClasses.addAll(sf.getClasses());
|
|
||||||
}
|
|
||||||
List<ClassOrInterface> importedClasses = new ArrayList<>();
|
|
||||||
//Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
|
|
||||||
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()));
|
|
||||||
importedClasses.add(importedClass);
|
|
||||||
}
|
|
||||||
allClasses.addAll(importedClasses);
|
|
||||||
|
|
||||||
return new TYPE(sourceFiles.values(), allClasses).getConstraints();
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ClassOrInterface> getAvailableClasses(SourceFile forSourceFile) throws ClassNotFoundException {
|
|
||||||
List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
|
|
||||||
for (SourceFile sf : sourceFiles.values()) {
|
|
||||||
allClasses.addAll(sf.getClasses());
|
|
||||||
}
|
|
||||||
List<ClassOrInterface> importedClasses = new ArrayList<>();
|
|
||||||
for (JavaClassName name : forSourceFile.getImports()) {
|
|
||||||
//TODO: Hier werden imports von eigenen (.jav) Klassen nicht beachtet
|
|
||||||
ClassOrInterface importedClass = ASTFactory.createClass(
|
|
||||||
ClassLoader.getSystemClassLoader().loadClass(name.toString()));
|
|
||||||
importedClasses.add(importedClass);
|
|
||||||
allClasses.addAll(importedClasses);
|
|
||||||
}
|
|
||||||
return allClasses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<ResultSet> typeInference() throws ClassNotFoundException {
|
|
||||||
List<ClassOrInterface> allClasses = new ArrayList<>();//environment.getAllAvailableClasses();
|
|
||||||
//Alle Importierten Klassen in allen geparsten Sourcefiles kommen ins FC
|
|
||||||
for(SourceFile sf : this.sourceFiles.values()) {
|
|
||||||
allClasses.addAll(getAvailableClasses(sf));
|
|
||||||
allClasses.addAll(sf.getClasses());
|
|
||||||
}
|
|
||||||
|
|
||||||
final ConstraintSet<Pair> cons = getConstraints();
|
|
||||||
|
|
||||||
FiniteClosure finiteClosure = UnifyTypeFactory.generateFC(allClasses);
|
|
||||||
System.out.println(finiteClosure);
|
|
||||||
ConstraintSet<UnifyPair> unifyCons = UnifyTypeFactory.convert(cons);
|
|
||||||
|
|
||||||
TypeUnify unify = new TypeUnify();
|
|
||||||
Set<Set<UnifyPair>> results = new HashSet<>();
|
|
||||||
Set<List<Constraint<UnifyPair>>> cardProd = unifyCons.cartesianProduct();
|
|
||||||
for (List<Constraint<UnifyPair>> xCons : cardProd ){
|
|
||||||
Set<UnifyPair> xConsSet = new HashSet<>();
|
|
||||||
for (Constraint<UnifyPair> constraint : xCons) {
|
|
||||||
xConsSet.addAll(constraint);
|
|
||||||
}
|
|
||||||
//.collect(Collectors.toCollection(ArrayList::new))))
|
|
||||||
System.out.println(xConsSet);
|
|
||||||
Set<String> paraTypeVarNames = allClasses.stream().map(x -> x.getMethods().stream().map(y -> y.getParameterList().getFormalparalist()
|
|
||||||
.stream().filter(z -> z.getType() instanceof TypePlaceholder)
|
|
||||||
.map(z -> ((TypePlaceholder)z.getType()).getName()).collect(Collectors.toCollection(HashSet::new)))
|
|
||||||
.reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return a;}, (a,b) -> { a.addAll(b); return a;} ) )
|
|
||||||
.reduce(new HashSet<String>(), (a,b) -> { a.addAll(b); return a;} );
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
|
|
||||||
xConsSet = xConsSet.stream().map(x -> {
|
|
||||||
//Hier muss ueberlegt werden, ob
|
|
||||||
//1. alle Argument- und Retuntyp-Variablen in allen UnifyPairs
|
|
||||||
// mit disableWildcardtable() werden.
|
|
||||||
//2. alle Typvariablen mit Argument- oder Retuntyp-Variablen
|
|
||||||
//in Beziehung auch auf disableWildcardtable() gesetzt werden muessen
|
|
||||||
//PL 2018-04-23
|
|
||||||
if ((x.getLhsType() instanceof PlaceholderType)) {
|
|
||||||
if (paraTypeVarNames.contains(x.getLhsType().getName())) {
|
|
||||||
((PlaceholderType)x.getLhsType()).setVariance((byte)1);
|
|
||||||
((PlaceholderType)x.getLhsType()).disableWildcardtable();
|
|
||||||
}
|
|
||||||
if (returnTypeVarNames.contains(x.getLhsType().getName())) {
|
|
||||||
((PlaceholderType)x.getLhsType()).setVariance((byte)-1);
|
|
||||||
((PlaceholderType)x.getLhsType()).disableWildcardtable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((x.getRhsType() instanceof PlaceholderType)) {
|
|
||||||
if (paraTypeVarNames.contains(x.getRhsType().getName())) {
|
|
||||||
((PlaceholderType)x.getRhsType()).setVariance((byte)1);
|
|
||||||
((PlaceholderType)x.getRhsType()).disableWildcardtable();
|
|
||||||
}
|
|
||||||
if (returnTypeVarNames.contains(x.getRhsType().getName())) {
|
|
||||||
((PlaceholderType)x.getRhsType()).setVariance((byte)-1);
|
|
||||||
((PlaceholderType)x.getRhsType()).disableWildcardtable();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return x;//HIER DIE JEWEILS RECHT BZW. LINKE SEITE AUF GLEICHE VARIANZ SETZEN WIE DIE JEWEILS ANDERE SEITE
|
|
||||||
}).map( y -> {
|
|
||||||
if ((y.getLhsType() instanceof PlaceholderType) && (y.getRhsType() instanceof PlaceholderType)) {
|
|
||||||
if (((PlaceholderType)y.getLhsType()).getVariance() != 0 && ((PlaceholderType)y.getRhsType()).getVariance() == 0) {
|
|
||||||
((PlaceholderType)y.getRhsType()).setVariance(((PlaceholderType)y.getLhsType()).getVariance());
|
|
||||||
}
|
|
||||||
if (((PlaceholderType)y.getLhsType()).getVariance() == 0 && ((PlaceholderType)y.getRhsType()).getVariance() != 0) {
|
|
||||||
((PlaceholderType)y.getLhsType()).setVariance(((PlaceholderType)y.getRhsType()).getVariance());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return y; } )
|
|
||||||
.collect(Collectors.toCollection(HashSet::new));
|
|
||||||
varianceInheritance(xConsSet);
|
|
||||||
Set<Set<UnifyPair>> result = unify.unifySequential(xConsSet, finiteClosure);
|
|
||||||
//Set<Set<UnifyPair>> result = unify.unify(xConsSet, finiteClosure);
|
|
||||||
results.addAll(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return results.stream().map((unifyPairs ->
|
|
||||||
new ResultSet(UnifyTypeFactory.convert(unifyPairs, generateTPHMap(cons))))).collect(Collectors.toList());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Vererbt alle Variancen
|
|
||||||
* @param eq The set of constraints
|
|
||||||
*/
|
|
||||||
private void varianceInheritance(Set<UnifyPair> eq) {
|
|
||||||
Set<PlaceholderType> usedTPH = new HashSet<>();
|
|
||||||
Set<PlaceholderType> phSet = eq.stream().map(x -> {
|
|
||||||
Set<PlaceholderType> pair = new HashSet<>();
|
|
||||||
if (x.getLhsType() instanceof PlaceholderType) pair.add((PlaceholderType)x.getLhsType());
|
|
||||||
if (x.getRhsType() instanceof PlaceholderType) pair.add((PlaceholderType)x.getRhsType());
|
|
||||||
return pair;
|
|
||||||
}).reduce(new HashSet<>(), (a,b) -> { a.addAll(b); return a;} , (c,d) -> { c.addAll(d); return c;});
|
|
||||||
|
|
||||||
ArrayList<PlaceholderType> phSetVariance = new ArrayList<>(phSet);
|
|
||||||
phSetVariance.removeIf(x -> (x.getVariance() == 0));
|
|
||||||
while(!phSetVariance.isEmpty()) {
|
|
||||||
PlaceholderType a = phSetVariance.remove(0);
|
|
||||||
usedTPH.add(a);
|
|
||||||
//HashMap<PlaceholderType,Integer> ht = new HashMap<>();
|
|
||||||
//ht.put(a, a.getVariance());
|
|
||||||
Set<UnifyPair> eq1 = new HashSet<>(eq);
|
|
||||||
eq1.removeIf(x -> !(x.getLhsType() instanceof PlaceholderType && ((PlaceholderType)x.getLhsType()).equals(a)));
|
|
||||||
eq1.stream().forEach(x -> { x.getRhsType().accept(new distributeVariance(), a.getVariance());});
|
|
||||||
eq1 = new HashSet<>(eq);
|
|
||||||
eq1.removeIf(x -> !(x.getRhsType() instanceof PlaceholderType && ((PlaceholderType)x.getRhsType()).equals(a)));
|
|
||||||
eq1.stream().forEach(x -> { x.getLhsType().accept(new distributeVariance(), a.getVariance());});
|
|
||||||
phSetVariance = new ArrayList<>(phSet);
|
|
||||||
phSetVariance.removeIf(x -> (x.getVariance() == 0 || usedTPH.contains(x)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Map<String, TypePlaceholder> generateTPHMap(ConstraintSet<Pair> constraints) {
|
|
||||||
HashMap<String, TypePlaceholder> ret = new HashMap<>();
|
|
||||||
constraints.map((Pair p) -> {
|
|
||||||
if (p.TA1 instanceof TypePlaceholder) {
|
|
||||||
ret.put(((TypePlaceholder) p.TA1).getName(), (TypePlaceholder) p.TA1);
|
|
||||||
}
|
|
||||||
if (p.TA2 instanceof TypePlaceholder) {
|
|
||||||
ret.put(((TypePlaceholder) p.TA2).getName(), (TypePlaceholder) p.TA2);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
});
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
private SourceFile parse(File sourceFile) throws IOException, java.lang.ClassNotFoundException {
|
|
||||||
CompilationUnitContext tree = JavaTXParser.parse(sourceFile);
|
|
||||||
SyntaxTreeGenerator generator = new SyntaxTreeGenerator(environment.getRegistry(sourceFile), new GenericsRegistry(null));
|
|
||||||
SourceFile ret = generator.convert(tree, environment.packageCrawler);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void generateBytecode() throws ClassNotFoundException, IOException {
|
|
||||||
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);
|
|
||||||
// BytecodeGen bytecodeGen = new BytecodeGen(classFiles,typeinferenceResult.get(0));
|
|
||||||
bytecodeGen.visit(sf);
|
|
||||||
this.writeClassFile(bytecodeGen.getClassFiles());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeClassFile(HashMap<String, byte[]> classFiles) throws IOException {
|
|
||||||
FileOutputStream output;
|
|
||||||
for(String name : classFiles.keySet()) {
|
|
||||||
byte[] bytecode = classFiles.get(name);
|
|
||||||
System.out.println("generating "+name+ ".class file ...");
|
|
||||||
output = new FileOutputStream(new File(System.getProperty("user.dir") + "/testBytecode/generatedBC/" +name+".class"));
|
|
||||||
output.write(bytecode);
|
|
||||||
output.close();
|
|
||||||
System.out.println(name+".class file generated");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -60,7 +60,7 @@ import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
|
|||||||
/**
|
/**
|
||||||
* Inferiert alle TypePlaceholder durch inferredTypes und erstzt sie durch
|
* Inferiert alle TypePlaceholder durch inferredTypes und erstzt sie durch
|
||||||
* GenericTypeVar, falls der Name des Typeplaceholder mit dem Namen eines
|
* GenericTypeVar, falls der Name des Typeplaceholder mit dem Namen eines
|
||||||
* generics in der GenericdeclarationList generics übereinstimmt.
|
* generics in der GenericdeclarationList generics <EFBFBD>bereinstimmt.
|
||||||
*
|
*
|
||||||
* @author mvr
|
* @author mvr
|
||||||
*
|
*
|
||||||
@ -382,7 +382,7 @@ public class InferTypes implements ASTReturnVisitor {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Literal visit(Literal literal) {
|
public Literal visit(Literal literal) {
|
||||||
throw new NotImplementedException();
|
return literal;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,11 +35,7 @@ import java.io.IOException;
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public class RuleSet implements IRuleSet{
|
public class RuleSet implements IRuleSet{
|
||||||
|
|
||||||
RuleSet() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Optional<UnifyPair> reduceUp(UnifyPair pair) {
|
public Optional<UnifyPair> reduceUp(UnifyPair pair) {
|
||||||
|
Loading…
Reference in New Issue
Block a user