FiniteClosure korrekt generieren

This commit is contained in:
JanUlrich 2018-02-19 11:33:08 +01:00
parent b7bb0fa1c4
commit d53faa0c86
5 changed files with 48 additions and 41 deletions

View File

@ -2,6 +2,7 @@ package de.dhbwstuttgart.parser.SyntaxTreeGenerator;
import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.factory.ASTFactory;
@ -11,6 +12,7 @@ import de.dhbwstuttgart.typeinference.constraints.Pair;
import de.dhbwstuttgart.typeinference.unify.model.*;
import java.util.*;
import java.util.stream.Collectors;
public class FCGenerator {
/**
@ -19,12 +21,15 @@ public class FCGenerator {
*
* @param availableClasses - Alle geparsten Klassen
*/
public static Set<UnifyPair> toFC(Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
HashSet<UnifyPair> pairs = new HashSet<>();
public static Set<UnifyPair> toUnifyFC(Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
return toFC(availableClasses).stream().map(t -> UnifyTypeFactory.convert(t)).collect(Collectors.toSet());
}
public static Set<Pair> toFC(Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
HashSet<Pair> pairs = new HashSet<>();
for(ClassOrInterface cly : availableClasses){
pairs.addAll(getSuperTypes(cly, availableClasses));
}
System.out.println(pairs);
return pairs;
}
@ -35,20 +40,20 @@ public class FCGenerator {
* @param forType
* @return
*/
private static List<UnifyPair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses) throws ClassNotFoundException {
return getSuperTypes(forType, availableClasses, new HashMap<>());
}
//TODO: implements Interface auch als superklassen beachten
private static List<UnifyPair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses, HashMap<String, UnifyType> gtvs) throws ClassNotFoundException {
List<UnifyType> params = new ArrayList<>();
private static List<Pair> getSuperTypes(ClassOrInterface forType, Collection<ClassOrInterface> availableClasses, HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs) throws ClassNotFoundException {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
//Die GTVs, die in forType hinzukommen:
HashMap<String, UnifyType> newGTVs = new HashMap<>();
HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> newGTVs = new HashMap<>();
//Generics mit gleichem Namen müssen den selben TPH bekommen
for(GenericTypeVar gtv : forType.getGenerics()){
if(!gtvs.containsKey(gtv.getParsedName())){
gtvs.put(gtv.getParsedName(), PlaceholderType.freshPlaceholder());
newGTVs.put(gtv.getParsedName(), PlaceholderType.freshPlaceholder());
gtvs.put(gtv.getParsedName(), TypePlaceholder.fresh(new NullToken()));
newGTVs.put(gtv.getParsedName(), TypePlaceholder.fresh(new NullToken()));
}
params.add(gtvs.get(gtv.getParsedName()));
}
@ -73,27 +78,26 @@ public class FCGenerator {
while(itGenParams.hasNext()){
RefTypeOrTPHOrWildcardOrGeneric setType = itSetParams.next();
//In diesem Typ die GTVs durch TPHs und Einsetzungen austauschen:
UnifyType setSetType = setType.acceptTV(new TypeExchanger(gtvs));
RefTypeOrTPHOrWildcardOrGeneric setSetType = setType.acceptTV(new TypeExchanger(gtvs));
newGTVs.put(itGenParams.next().getParsedName(), setSetType);
}
UnifyType superType = forType.getSuperClass().acceptTV(new TypeExchanger(newGTVs));
RefTypeOrTPHOrWildcardOrGeneric superType = forType.getSuperClass().acceptTV(new TypeExchanger(newGTVs));
TypeParams paramList = new TypeParams(params);
UnifyType t1 = new ReferenceType(forType.getClassName().toString(), paramList);
UnifyType t2 = superType;
RefTypeOrTPHOrWildcardOrGeneric t1 = new RefType(forType.getClassName(), params, new NullToken());
RefTypeOrTPHOrWildcardOrGeneric t2 = superType;
UnifyPair ret = UnifyTypeFactory.generateSmallerPair(t1, t2);
Pair ret = new Pair(t1, t2, PairOperator.SMALLER);
List<UnifyPair> superTypes;
List<Pair> superTypes;
//Rekursiver Aufruf. Abbruchbedingung ist Object als Superklasse:
if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){
superTypes = Arrays.asList(UnifyTypeFactory.generateSmallerPair(UnifyTypeFactory.convert(ASTFactory.createObjectType()), UnifyTypeFactory.convert(ASTFactory.createObjectType())));
superTypes = Arrays.asList(new Pair(ASTFactory.createObjectType(), ASTFactory.createObjectType(), PairOperator.SMALLER));
}else{
superTypes = getSuperTypes(superClass, availableClasses, newGTVs);
}
List<UnifyPair> retList = new ArrayList<>();
List<Pair> retList = new ArrayList<>();
retList.add(ret);
retList.addAll(superTypes);
@ -103,42 +107,41 @@ public class FCGenerator {
/**
* Tauscht die GTVs in einem Typ gegen die entsprechenden Typen in der übergebenen Map aus.
*/
private static class TypeExchanger implements TypeVisitor<UnifyType>{
private static class TypeExchanger implements TypeVisitor<RefTypeOrTPHOrWildcardOrGeneric>{
private final HashMap<String, UnifyType> gtvs;
private final HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs;
TypeExchanger(HashMap<String, UnifyType> gtvs){
TypeExchanger(HashMap<String, RefTypeOrTPHOrWildcardOrGeneric> gtvs){
this.gtvs = gtvs;
}
@Override
public UnifyType visit(RefType refType) {
List<UnifyType> params = new ArrayList<>();
public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) {
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(RefTypeOrTPHOrWildcardOrGeneric param : refType.getParaList()){
params.add(param.acceptTV(this));
}
TypeParams paramList = new TypeParams(params);
UnifyType ret = new ReferenceType(refType.getName().toString(), paramList);
RefTypeOrTPHOrWildcardOrGeneric ret = new RefType(refType.getName(), params, new NullToken());
return ret;
}
@Override
public UnifyType visit(SuperWildcardType superWildcardType) {
public RefTypeOrTPHOrWildcardOrGeneric visit(SuperWildcardType superWildcardType) {
throw new DebugException("Dieser Fall darf nicht auftreten");
}
@Override
public UnifyType visit(TypePlaceholder typePlaceholder) {
public RefTypeOrTPHOrWildcardOrGeneric visit(TypePlaceholder typePlaceholder) {
throw new DebugException("Dieser Fall darf nicht auftreten");
}
@Override
public UnifyType visit(ExtendsWildcardType extendsWildcardType) {
public RefTypeOrTPHOrWildcardOrGeneric visit(ExtendsWildcardType extendsWildcardType) {
throw new DebugException("Dieser Fall darf nicht auftreten");
}
@Override
public UnifyType visit(GenericRefType genericRefType) {
public RefTypeOrTPHOrWildcardOrGeneric visit(GenericRefType genericRefType) {
if(! gtvs.containsKey(genericRefType.getParsedName()))
throw new DebugException("Dieser Fall darf nicht auftreten");
//TODO: Diesen Dirty-Hack beseitigen. Fehler tritt bei java.lang.invoke.LambdaFormEditor$Transform$Kind auf.

View File

@ -1,6 +1,7 @@
package de.dhbwstuttgart.sat.asp.writer;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.FCGenerator;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.sat.asp.writer.model.*;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
@ -19,25 +20,25 @@ public class ASPGenerator {
ASPWriter writer = new ASPWriter();
private final String asp;
public ASPGenerator(ConstraintSet<Pair> constraints, Collection<ClassOrInterface> fcClasses){
public ASPGenerator(ConstraintSet<Pair> constraints, Collection<ClassOrInterface> fcClasses) throws ClassNotFoundException {
List<Constraint<Pair>> constraints1 = constraints.cartesianProduct().iterator().next();
List<Pair> constraintPairs = new ArrayList<>();
for(Constraint<Pair> constraint : constraints1){
System.out.println(UnifyTypeFactory.convert(constraint));
constraintPairs.addAll(constraint);
}
asp = toASP(constraintPairs, fcClasses);
asp = toASP(constraintPairs, FCGenerator.toFC(fcClasses));
}
public String getASP(){
return asp;
}
private String toASP(List<Pair> constraintSet, Collection<ClassOrInterface> fcClasses){
private String toASP(List<Pair> constraintSet, Collection<Pair> fc){
TypeConverter converter = new TypeConverter();
for(ClassOrInterface cl : fcClasses){
ASPRefType superClass = (ASPRefType) cl.getSuperClass().acceptTV(converter);
ASPPairSmaller fcEntry = new ASPPairSmaller(new ASPFCType(convert(cl)), new ASPFCType(superClass), writer);
for(Pair fcp : fc){
//Wenn dieser Cast fehlschlägt stimmt etwas nicht. Alle Paare in der FC müssen smaller Operatoren haen
ASPPairSmaller fcEntry = (ASPPairSmaller) convert(fcp);
writer.add(new ASPStatement(fcEntry.toASP()));
}
for(Pair cons : constraintSet){
@ -55,6 +56,9 @@ public class ASPGenerator {
return new ASPPairEquals(ls, rs,writer);
}else if(pair.OperatorSmallerDot()){
return new ASPPairSmallerDot(ls, rs, writer);
}else if(pair.OperatorSmaller()){
//Diese Cast müssen auch immer funktionieren, da in smaller Constraints nur RefTypes vorkommen
return new ASPPairSmaller(new ASPFCType((ASPRefType) ls), new ASPFCType((ASPRefType) rs), writer);
}else throw new NotImplementedException();
}

View File

@ -3,13 +3,11 @@ package de.dhbwstuttgart.syntaxtree.factory;
import java.util.*;
import java.util.stream.Collectors;
import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.FCGenerator;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.syntaxtree.type.WildcardType;
@ -35,7 +33,7 @@ public class UnifyTypeFactory {
Generell dürfen sie immer die gleichen Namen haben.
TODO: die transitive Hülle bilden
*/
return new FiniteClosure(FCGenerator.toFC(fromClasses));
return new FiniteClosure(FCGenerator.toUnifyFC(fromClasses));
}
public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){

View File

@ -19,7 +19,7 @@ public class ClingoTest {
public static final String tempDirectory = "/tmp/";
@Test
public void test() throws IOException, InterruptedException {
public void test() throws IOException, InterruptedException, ClassNotFoundException {
String content = "";
content = new ASPGenerator(this.getPairs(), this.getFC()).getASP();

View File

@ -14,7 +14,9 @@ import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
public class ASPTest {
@ -44,9 +46,9 @@ public class ASPTest {
//filesToTest.add(new File(rootDirectory+"Matrix.jav"));
//filesToTest.add(new File(rootDirectory+"Import.jav"));
JavaTXCompiler compiler = new JavaTXCompiler(fileToTest);
List<ClassOrInterface> allClasses = new ArrayList<>();
Set<ClassOrInterface> allClasses = new HashSet<>();
for(SourceFile sf : compiler.sourceFiles.values()) {
//allClasses.addAll(compiler.getAvailableClasses(sf));
allClasses.addAll(compiler.getAvailableClasses(sf));
}
for(SourceFile sf : compiler.sourceFiles.values()) {
allClasses.addAll(sf.getClasses());