From d53faa0c86f393edcc9f47200866ab844ccecefe Mon Sep 17 00:00:00 2001 From: JanUlrich Date: Mon, 19 Feb 2018 11:33:08 +0100 Subject: [PATCH] FiniteClosure korrekt generieren --- .../SyntaxTreeGenerator/FCGenerator.java | 61 ++++++++++--------- .../sat/asp/writer/ASPGenerator.java | 16 +++-- .../syntaxtree/factory/UnifyTypeFactory.java | 4 +- test/asp/ClingoTest.java | 2 +- test/asp/typeinference/ASPTest.java | 6 +- 5 files changed, 48 insertions(+), 41 deletions(-) diff --git a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java index 7863c8ed..ea2b17a6 100644 --- a/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java +++ b/src/de/dhbwstuttgart/parser/SyntaxTreeGenerator/FCGenerator.java @@ -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 toFC(Collection availableClasses) throws ClassNotFoundException { - HashSet pairs = new HashSet<>(); + public static Set toUnifyFC(Collection availableClasses) throws ClassNotFoundException { + return toFC(availableClasses).stream().map(t -> UnifyTypeFactory.convert(t)).collect(Collectors.toSet()); + } + + public static Set toFC(Collection availableClasses) throws ClassNotFoundException { + HashSet 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 getSuperTypes(ClassOrInterface forType, Collection availableClasses) throws ClassNotFoundException { + private static List getSuperTypes(ClassOrInterface forType, Collection availableClasses) throws ClassNotFoundException { return getSuperTypes(forType, availableClasses, new HashMap<>()); } //TODO: implements Interface auch als superklassen beachten - private static List getSuperTypes(ClassOrInterface forType, Collection availableClasses, HashMap gtvs) throws ClassNotFoundException { - List params = new ArrayList<>(); + private static List getSuperTypes(ClassOrInterface forType, Collection availableClasses, HashMap gtvs) throws ClassNotFoundException { + List params = new ArrayList<>(); //Die GTVs, die in forType hinzukommen: - HashMap newGTVs = new HashMap<>(); + HashMap 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 superTypes; + List 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 retList = new ArrayList<>(); + List 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{ + private static class TypeExchanger implements TypeVisitor{ - private final HashMap gtvs; + private final HashMap gtvs; - TypeExchanger(HashMap gtvs){ + TypeExchanger(HashMap gtvs){ this.gtvs = gtvs; } @Override - public UnifyType visit(RefType refType) { - List params = new ArrayList<>(); + public RefTypeOrTPHOrWildcardOrGeneric visit(RefType refType) { + List 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. diff --git a/src/de/dhbwstuttgart/sat/asp/writer/ASPGenerator.java b/src/de/dhbwstuttgart/sat/asp/writer/ASPGenerator.java index ea162c11..38652b43 100644 --- a/src/de/dhbwstuttgart/sat/asp/writer/ASPGenerator.java +++ b/src/de/dhbwstuttgart/sat/asp/writer/ASPGenerator.java @@ -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 constraints, Collection fcClasses){ + public ASPGenerator(ConstraintSet constraints, Collection fcClasses) throws ClassNotFoundException { List> constraints1 = constraints.cartesianProduct().iterator().next(); List constraintPairs = new ArrayList<>(); for(Constraint 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 constraintSet, Collection fcClasses){ + private String toASP(List constraintSet, Collection 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(); } diff --git a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java index a962c2bc..4ecaa136 100644 --- a/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java +++ b/src/de/dhbwstuttgart/syntaxtree/factory/UnifyTypeFactory.java @@ -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){ diff --git a/test/asp/ClingoTest.java b/test/asp/ClingoTest.java index dbfa70d8..83f3a26f 100644 --- a/test/asp/ClingoTest.java +++ b/test/asp/ClingoTest.java @@ -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(); diff --git a/test/asp/typeinference/ASPTest.java b/test/asp/typeinference/ASPTest.java index b41d9405..cea141f9 100644 --- a/test/asp/typeinference/ASPTest.java +++ b/test/asp/typeinference/ASPTest.java @@ -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 allClasses = new ArrayList<>(); + Set 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());