Änderungen an der FC generierung und an dem Verhalten von GTVs im Type Algorithmus UNVOLLSTÄNDIG. Kleines Backup, da große Änderung am Type-Algorithmus noch ansteht.

This commit is contained in:
JanUlrich 2017-11-09 19:41:53 +01:00
parent 1d767a7696
commit fea86460e8
18 changed files with 216 additions and 61 deletions

View File

@ -60,4 +60,13 @@ public class CompilationEnvironment {
allNames = GatherNames.getNames(tree, new PackageCrawler(librarys)); allNames = GatherNames.getNames(tree, new PackageCrawler(librarys));
return new JavaClassRegistry(allNames); return new JavaClassRegistry(allNames);
} }
public List<ClassOrInterface> getAllAvailableClasses() {
List<ClassOrInterface> ret = new ArrayList<>();
for(Class c : new PackageCrawler(librarys).getAllAvailableClasses()){
ret.add(ASTFactory.createClass(c));
}
return ret;
}
} }

View File

@ -56,6 +56,16 @@ public class PackageCrawler {
return classes; return classes;
} }
public Set<Class<?>> getAllAvailableClasses(){
Reflections reflections = new Reflections(new ConfigurationBuilder()
.setScanners(new SubTypesScanner(false /* don't exclude Object.class */), new ResourcesScanner())
.setUrls(urls));
Set<Class<?>> classes = reflections.getSubTypesOf(Object.class);
return classes;
}
public List<String> getClassNames(String packageName){ public List<String> getClassNames(String packageName){
List<String> nameList = new ArrayList(); List<String> nameList = new ArrayList();
Set<Class<?>> classes = getClassesInPackage(packageName); Set<Class<?>> classes = getClassesInPackage(packageName);

View File

@ -184,7 +184,7 @@ public class SyntaxTreeGenerator{
block = stmtGen.convert(body.block()); block = stmtGen.convert(body.block());
} }
if(parentClass.equals(new JavaClassName(name))){ if(parentClass.equals(new JavaClassName(name))){
return new Constructor(modifiers, name, retType, modifiers, parameterList, block, gtvDeclarations, header.getStart(), fieldInitializations, superClass); return new Constructor(modifiers, name, retType, modifiers, parameterList, block, gtvDeclarations, header.getStart(), fieldInitializations);
}else{ }else{
return new Method(modifiers, name, retType, modifiers, parameterList,block, gtvDeclarations, header.getStart()); return new Method(modifiers, name, retType, modifiers, parameterList,block, gtvDeclarations, header.getStart());
} }
@ -222,7 +222,7 @@ public class SyntaxTreeGenerator{
if(ctx.superclass() != null){ if(ctx.superclass() != null){
superClass = convert(ctx.superclass()); superClass = convert(ctx.superclass());
}else{ }else{
superClass = ASTFactory.createObjectClass().getType(); superClass = new RefType(ASTFactory.createObjectClass().getClassName(), ctx.getStart());
} }
List<Field> fielddecl = convertFields(ctx.classBody(), generics); List<Field> fielddecl = convertFields(ctx.classBody(), generics);
List<Method> methods = convertMethods(ctx.classBody(), name, superClass, generics); List<Method> methods = convertMethods(ctx.classBody(), name, superClass, generics);
@ -269,7 +269,7 @@ public class SyntaxTreeGenerator{
int modifiers = 0; int modifiers = 0;
ParameterList params = new ParameterList(new ArrayList<>(), offset); ParameterList params = new ParameterList(new ArrayList<>(), offset);
Block block = new Block(new ArrayList<>(), offset); Block block = new Block(new ArrayList<>(), offset);
return new Constructor(Modifier.PUBLIC, className, classType, modifiers, params, block, classGenerics, offset, fieldInitializations, superClass); return new Constructor(Modifier.PUBLIC, className, classType, modifiers, params, block, classGenerics, offset, fieldInitializations);
} }
private RefType convert(Java8Parser.SuperclassContext superclass) { private RefType convert(Java8Parser.SuperclassContext superclass) {
@ -434,7 +434,7 @@ public class SyntaxTreeGenerator{
}else{ }else{
genericParams = createEmptyGenericDeclarationList(ctx.Identifier()); genericParams = createEmptyGenericDeclarationList(ctx.Identifier());
} }
RefType superClass = ASTFactory.createObjectClass().getType(); RefType superClass = ASTFactory.createObjectType();
List<Field> fields = convertFields(ctx.interfaceBody()); List<Field> fields = convertFields(ctx.interfaceBody());
List<Method> methods = convertMethods(ctx.interfaceBody(), name, superClass, generics); List<Method> methods = convertMethods(ctx.interfaceBody(), name, superClass, generics);

View File

@ -77,7 +77,7 @@ public class TypeGenerator {
public static List<RefTypeOrTPHOrWildcardOrGeneric> convert(Java8Parser.TypeBoundContext typeBoundContext, JavaClassRegistry reg, GenericsRegistry generics) { public static List<RefTypeOrTPHOrWildcardOrGeneric> convert(Java8Parser.TypeBoundContext typeBoundContext, JavaClassRegistry reg, GenericsRegistry generics) {
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
if(typeBoundContext == null){ if(typeBoundContext == null){
ret.add(ASTFactory.createObjectClass().getType()); ret.add(ASTFactory.createObjectType());
return ret; return ret;
} }
if(typeBoundContext.typeVariable() != null){ if(typeBoundContext.typeVariable() != null){

View File

@ -19,4 +19,8 @@ public class GenericTypeName extends JavaClassName {
+ DELIMITER + methodName + DELIMITER + methodName
+ DELIMITER + super.toString(); + DELIMITER + super.toString();
} }
public JavaClassName getParentClass() {
return parentClass;
}
} }

View File

@ -60,10 +60,12 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
return this.methods; return this.methods;
} }
/*
public RefType getType() { public RefType getType() {
return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset()); return generateTypeOfClass(this.getClassName(), this.getGenerics(), this.getOffset());
} }
*/
//TODO: Das hier ist ein Problem. Je nach Kontext wird hier ein anderer Typ benötigt
public static RefType generateTypeOfClass(JavaClassName name, GenericDeclarationList genericsOfClass ,Token offset){ public static RefType generateTypeOfClass(JavaClassName name, GenericDeclarationList genericsOfClass ,Token offset){
//Hier wird immer ein generischer Typ generiert, also mit Type placeholdern //Hier wird immer ein generischer Typ generiert, also mit Type placeholdern
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
@ -74,6 +76,10 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
return new RefType(name, params, offset); return new RefType(name, params, offset);
} }
/**
* Die Superklasse im Kontext dieser ClassOrInterface
* Das bedeutet, dass generische Variablen als GenericRefTypes dargestellt sind
*/
public RefType getSuperClass() { public RefType getSuperClass() {
return superClass; return superClass;
} }

View File

@ -15,8 +15,8 @@ public class Constructor extends Method {
//TODO: Constructor braucht ein super-Statement //TODO: Constructor braucht ein super-Statement
public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block codeInsideConstructor, public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block codeInsideConstructor,
GenericDeclarationList gtvDeclarations, Token offset, List<Statement> fieldInitializations, RefType superClass) { GenericDeclarationList gtvDeclarations, Token offset, List<Statement> fieldInitializations) {
super(modifier, name, returnType, modifiers, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations, superClass), gtvDeclarations, offset); super(modifier, name, returnType, modifiers, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations), gtvDeclarations, offset);
} }
@ -25,7 +25,7 @@ public class Constructor extends Method {
* welche die Felder der zugehörigen Klasse dieses * welche die Felder der zugehörigen Klasse dieses
* Konstruktor initialisieren * Konstruktor initialisieren
*/ */
protected static Block prepareBlock(Block constructorBlock, List<Statement> fieldInitializations, RefType superClass){ protected static Block prepareBlock(Block constructorBlock, List<Statement> fieldInitializations){
List<Statement> statements = constructorBlock.getStatements(); List<Statement> statements = constructorBlock.getStatements();
statements.add(0, new SuperCall(constructorBlock.getOffset())); statements.add(0, new SuperCall(constructorBlock.getOffset()));
return new Block(statements, constructorBlock.getOffset()); return new Block(statements, constructorBlock.getOffset());

View File

@ -1,6 +1,7 @@
package de.dhbwstuttgart.syntaxtree; package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.parser.scope.GenericTypeName; import de.dhbwstuttgart.parser.scope.GenericTypeName;
import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import org.antlr.v4.runtime.Token; import org.antlr.v4.runtime.Token;
@ -53,6 +54,14 @@ public class GenericTypeVar extends SyntaxTreeNode
return name; return name;
} }
public String getParsedName(){
return name.toString();
}
public JavaClassName definingClass(){
return name.getParentClass();
}
@Override @Override
public void accept(ASTVisitor visitor) { public void accept(ASTVisitor visitor) {
visitor.visit(this); visitor.visit(this);

View File

@ -2,6 +2,8 @@ package de.dhbwstuttgart.syntaxtree;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import java.util.Collection;
public interface TypeScope { public interface TypeScope {
Iterable<? extends GenericTypeVar> getGenerics(); Iterable<? extends GenericTypeVar> getGenerics();

View File

@ -5,6 +5,7 @@ import java.lang.reflect.Constructor;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericContext; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericContext;
import de.dhbwstuttgart.parser.scope.GenericTypeName; import de.dhbwstuttgart.parser.scope.GenericTypeName;
@ -45,7 +46,11 @@ public class ASTFactory {
java.lang.Class superjreClass = jreClass.getSuperclass(); java.lang.Class superjreClass = jreClass.getSuperclass();
RefType superClass; RefType superClass;
if(superjreClass != null){ if(superjreClass != null){
superClass = (RefType) createType(superjreClass, name, ""); List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(TypeVariable tv : superjreClass.getTypeParameters()){
params.add(new RefType(new GenericTypeName(new GenericContext( name, null),tv.getName()), new NullToken()));
}
superClass = new RefType(new JavaClassName(superjreClass.getName()), params, new NullToken());
}else{//Jede Klasse und jedes Interface erbt von Object: (auch Object selbst!) }else{//Jede Klasse und jedes Interface erbt von Object: (auch Object selbst!)
superClass = (RefType) createType(java.lang.Object.class, name, ""); superClass = (RefType) createType(java.lang.Object.class, name, "");
} }
@ -83,13 +88,12 @@ public class ASTFactory {
return null; return null;
} }
return new de.dhbwstuttgart.syntaxtree.Constructor(constructor.getModifiers(), name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>(), return new de.dhbwstuttgart.syntaxtree.Constructor(constructor.getModifiers(), name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>());
createType(inClass.getSuperclass()));
} }
private static RefType createType(Class classType) { //private static RefType createType(Class classType) {
return createClass(classType).getType(); // return createClass(classType).getType();
} //}
public static Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass){ public static Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass){
String name = jreMethod.getName(); String name = jreMethod.getName();
@ -182,6 +186,9 @@ public class ASTFactory {
public static ClassOrInterface createObjectClass() { public static ClassOrInterface createObjectClass() {
return createClass(Object.class); return createClass(Object.class);
} }
public static RefType createObjectType() {
return new RefType(createClass(Object.class).getClassName(), new NullToken());
}
/* /*
public Constructor createEmptyConstructor(Class parent){ public Constructor createEmptyConstructor(Class parent){

View File

@ -3,11 +3,13 @@ package de.dhbwstuttgart.syntaxtree.factory;
import java.util.*; import java.util.*;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.exceptions.DebugException; import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.exceptions.NotImplementedException; import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.scope.JavaClassName; import de.dhbwstuttgart.parser.scope.JavaClassName;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface; import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.GenericTypeVar;
import de.dhbwstuttgart.syntaxtree.type.*; import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.syntaxtree.type.Void; import de.dhbwstuttgart.syntaxtree.type.Void;
import de.dhbwstuttgart.typeinference.constraints.ConstraintSet; import de.dhbwstuttgart.typeinference.constraints.ConstraintSet;
@ -26,19 +28,73 @@ import de.dhbwstuttgart.typeinference.unify.model.SuperType;
import de.dhbwstuttgart.typeinference.unify.model.TypeParams; import de.dhbwstuttgart.typeinference.unify.model.TypeParams;
import de.dhbwstuttgart.typeinference.unify.model.UnifyType; import de.dhbwstuttgart.typeinference.unify.model.UnifyType;
public class UnifyTypeFactory { public class UnifyTypeFactory {
public static FiniteClosure generateFC(List<ClassOrInterface> fromAvailableClasses){ public static FiniteClosure generateFC(List<ClassOrInterface> fromClasses) throws ClassNotFoundException {
/*
TODO: Generics werden zu TPHs
Die transitive Hülle muss funktionieren.
Man darf schreiben List<A> extends AL<A>
und Vector<B> extends List<B>
hier muss dann aber dennoch die Vererbung V < L < AL
hergestellt werden.
In einem solchen Vererbungsbaum dürfen die TPH auch die gleichen Namen haben.
Generell dürfen sie immer die gleichen Namen haben.
TODO: die transitive Hülle bilden
*/
HashSet<UnifyPair> pairs = new HashSet<>(); HashSet<UnifyPair> pairs = new HashSet<>();
for(ClassOrInterface cl : fromAvailableClasses){ for(ClassOrInterface cly : fromClasses){
UnifyType t1 = UnifyTypeFactory.convert(cl.getType()); pairs.addAll(getSuperTypes(cly, fromClasses));
UnifyType t2 = UnifyTypeFactory.convert(cl.getSuperClass());
pairs.add(generateSmallerPair(t1, t2));
} }
return new FiniteClosure(pairs); return new FiniteClosure(pairs);
} }
/**
* Bildet eine Kette vom übergebenen Typ bis hin zum höchsten bekannten Typ
* Als Generics werden TPHs benutzt, welche der Unifikationsalgorithmus korrekt interpretieren muss.
* Die verwendeten TPHs werden in der Kette nach oben gereicht, so erhält der selbe GTV immer den selben TPH
* @param forType
* @return
*/
private static List<UnifyPair> getSuperTypes(ClassOrInterface forType, List<ClassOrInterface> availableClasses) throws ClassNotFoundException {
return getSuperTypes(forType, availableClasses, new HashMap<>());
}
private static List<UnifyPair> getSuperTypes(ClassOrInterface forType, List<ClassOrInterface> availableClasses, HashMap<String, PlaceholderType> gtvs) throws ClassNotFoundException {
List<UnifyType> params = new ArrayList<>();
//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());
params.add(gtvs.get(gtv.getParsedName()));
}
Optional<ClassOrInterface> hasSuperclass = availableClasses.stream().filter(cl -> forType.getSuperClass().getName().equals(cl.getClassName())).findAny();
ClassOrInterface superClass;
if(!hasSuperclass.isPresent()) //TODO: Wenn es die Object-Klasse ist, dann ist es in Ordnung, ansonsten Fehler ausgeben:
{
superClass = ASTFactory.createClass(ClassLoader.getSystemClassLoader().loadClass(forType.getSuperClass().getName().toString()));
}else{
superClass = hasSuperclass.get();
}
List<UnifyPair> superTypes;
if(superClass.getClassName().equals(ASTFactory.createObjectClass().getClassName())){
superTypes = Arrays.asList(generateSmallerPair(convert(ASTFactory.createObjectType()), convert(ASTFactory.createObjectType())));
}else{
superTypes = getSuperTypes(superClass, availableClasses, gtvs);
}
TypeParams paramList = new TypeParams(params);
UnifyType t1 = new ReferenceType(forType.getClassName().toString(), paramList);
UnifyType t2 = superTypes.get(0).getLhsType();
UnifyPair ret = generateSmallerPair(t1, t2);
List<UnifyPair> retList = new ArrayList<>();
retList.add(ret);
retList.addAll(superTypes);
return retList;
}
public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){ public static UnifyPair generateSmallerPair(UnifyType tl, UnifyType tr){
return new UnifyPair(tl, tr, PairOperator.SMALLER); return new UnifyPair(tl, tr, PairOperator.SMALLER);
} }

View File

@ -1,21 +1,22 @@
package de.dhbwstuttgart.typeinference.assumptions; package de.dhbwstuttgart.typeinference.assumptions;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.TypeScope;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric; import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
public class FieldAssumption extends Assumption{ public class FieldAssumption extends Assumption{
private RefTypeOrTPHOrWildcardOrGeneric receiverType; private ClassOrInterface receiverClass;
private RefTypeOrTPHOrWildcardOrGeneric type; private RefTypeOrTPHOrWildcardOrGeneric type;
public FieldAssumption(RefTypeOrTPHOrWildcardOrGeneric receiverType, public FieldAssumption(ClassOrInterface receiverType,
RefTypeOrTPHOrWildcardOrGeneric type, TypeScope scope){ RefTypeOrTPHOrWildcardOrGeneric type, TypeScope scope){
super(scope); super(scope);
this.type = type; this.type = type;
this.receiverType = receiverType; this.receiverClass = receiverType;
} }
public RefTypeOrTPHOrWildcardOrGeneric getReceiverType() { public ClassOrInterface getReceiverClass() {
return receiverType; return receiverClass;
} }
public RefTypeOrTPHOrWildcardOrGeneric getType() { public RefTypeOrTPHOrWildcardOrGeneric getType() {

View File

@ -1,5 +1,6 @@
package de.dhbwstuttgart.typeinference.assumptions; package de.dhbwstuttgart.typeinference.assumptions;
import de.dhbwstuttgart.syntaxtree.ClassOrInterface;
import de.dhbwstuttgart.syntaxtree.ParameterList; import de.dhbwstuttgart.syntaxtree.ParameterList;
import de.dhbwstuttgart.syntaxtree.TypeScope; import de.dhbwstuttgart.syntaxtree.TypeScope;
import de.dhbwstuttgart.syntaxtree.statement.Assign; import de.dhbwstuttgart.syntaxtree.statement.Assign;
@ -10,11 +11,11 @@ import java.util.List;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public class MethodAssumption extends Assumption{ public class MethodAssumption extends Assumption{
private RefType receiver; private ClassOrInterface receiver;
private RefTypeOrTPHOrWildcardOrGeneric retType; private RefTypeOrTPHOrWildcardOrGeneric retType;
List<RefTypeOrTPHOrWildcardOrGeneric> params; List<RefTypeOrTPHOrWildcardOrGeneric> params;
public MethodAssumption(RefType receiver, RefTypeOrTPHOrWildcardOrGeneric retType, public MethodAssumption(ClassOrInterface receiver, RefTypeOrTPHOrWildcardOrGeneric retType,
List<RefTypeOrTPHOrWildcardOrGeneric> params, TypeScope scope){ List<RefTypeOrTPHOrWildcardOrGeneric> params, TypeScope scope){
super(scope); super(scope);
this.receiver = receiver; this.receiver = receiver;
@ -22,7 +23,14 @@ public class MethodAssumption extends Assumption{
this.params = params; this.params = params;
} }
/*
public RefType getReceiverType() { public RefType getReceiverType() {
return receiver;
}
*/
public ClassOrInterface getReceiver(){
return receiver; return receiver;
} }

View File

@ -46,7 +46,8 @@ public class TypeInferenceInformation {
for(ClassOrInterface cl : classes){ for(ClassOrInterface cl : classes){
for(Field m : cl.getFieldDecl()){ for(Field m : cl.getFieldDecl()){
if(m.getName().equals(name)){ if(m.getName().equals(name)){
ret.add(new FieldAssumption(cl.getType(), checkGTV(m.getType()), new TypeScopeContainer(cl, m)));
ret.add(new FieldAssumption(cl, checkGTV(m.getType()), new TypeScopeContainer(cl, m)));
} }
} }
} }

View File

@ -17,6 +17,17 @@ import java.util.Map;
public class ConstraintsFactory { public class ConstraintsFactory {
/**
* Erstellt ein Pair Element für den Unify.
* Die Methode löst gleichzeitig GTVs in den Typen t1 und t2 auf.
* @param t1
* @param t2
* @param equalsdot
* @param currentScope
* @param additionalScope
* @param resolver
* @return
*/
public static Pair createPair(RefTypeOrTPHOrWildcardOrGeneric t1, RefTypeOrTPHOrWildcardOrGeneric t2, public static Pair createPair(RefTypeOrTPHOrWildcardOrGeneric t1, RefTypeOrTPHOrWildcardOrGeneric t2,
PairOperator equalsdot, TypeScope currentScope, TypeScope additionalScope, PairOperator equalsdot, TypeScope currentScope, TypeScope additionalScope,
GenericsResolver resolver){ GenericsResolver resolver){
@ -30,6 +41,7 @@ public class ConstraintsFactory {
return createPair(t1,t2,PairOperator.SMALLERDOT, currentScope, additionalScope, resolver); return createPair(t1,t2,PairOperator.SMALLERDOT, currentScope, additionalScope, resolver);
} }
private static RefTypeOrTPHOrWildcardOrGeneric checkGeneric(RefTypeOrTPHOrWildcardOrGeneric type, private static RefTypeOrTPHOrWildcardOrGeneric checkGeneric(RefTypeOrTPHOrWildcardOrGeneric type,
TypeScope currentScope, TypeScope additionalScope, TypeScope currentScope, TypeScope additionalScope,
GenericsResolver resolver){ GenericsResolver resolver){

View File

@ -6,14 +6,12 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.exceptions.TypeinferenceException; import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.NullToken; import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal; import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.parser.antlr.Java8Parser;
import de.dhbwstuttgart.syntaxtree.*; import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.*; import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal; import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
import de.dhbwstuttgart.syntaxtree.statement.literal.Null; import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
import de.dhbwstuttgart.syntaxtree.type.FunN; import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption; import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption; import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation; import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
@ -113,8 +111,10 @@ public class TYPEStmt implements StatementVisitor{
for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){ for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){
Constraint constraint = new Constraint(); Constraint constraint = new Constraint();
GenericsResolver resolver = getResolverInstance(); GenericsResolver resolver = getResolverInstance();
/*TODO Hier muss der Typ der Klasse ermittelt werden. In diesem müssen Generics mit TPHs ausgetauscht werden
constraint.add(ConstraintsFactory.createPair( constraint.add(ConstraintsFactory.createPair(
fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver)); fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver));
*/
constraint.add(ConstraintsFactory.createPair( constraint.add(ConstraintsFactory.createPair(
fieldVar.getType(),fieldAssumption.getType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver)); fieldVar.getType(),fieldAssumption.getType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver));
oderConstraints.add(constraint); oderConstraints.add(constraint);
@ -122,6 +122,9 @@ public class TYPEStmt implements StatementVisitor{
if(oderConstraints.size() == 0) if(oderConstraints.size() == 0)
throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset()); throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset());
constraintsSet.addOderConstraint(oderConstraints); constraintsSet.addOderConstraint(oderConstraints);
//Wegen dem Problem oben:
throw new NotImplementedException();
} }
@Override @Override
@ -213,8 +216,15 @@ public class TYPEStmt implements StatementVisitor{
@Override @Override
public void visit(This aThis) { public void visit(This aThis) {
//Im Falle von this, müssen die Generics in der Klasse als RefTypes behandelt werden.
ClassOrInterface currentClass = info.getCurrentClass();
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(GenericTypeVar gtv : currentClass.getGenerics()){
params.add(new GenericRefType(gtv.getName(), aThis.getOffset()));
}
RefType thisType = new RefType(currentClass.getClassName(), params, aThis.getOffset());
constraintsSet.addUndConstraint(ConstraintsFactory.createPair( constraintsSet.addUndConstraint(ConstraintsFactory.createPair(
aThis.getType(), info.getCurrentClass().getType(), PairOperator.EQUALSDOT, info.getCurrentTypeScope(), aThis.getType(), thisType, PairOperator.EQUALSDOT, info.getCurrentTypeScope(),
createNullTypeScope(), getResolverInstance())); createNullTypeScope(), getResolverInstance()));
} }
@ -280,7 +290,18 @@ public class TYPEStmt implements StatementVisitor{
protected Constraint<Pair> generateConstraint(MethodCall forMethod, MethodAssumption assumption, protected Constraint<Pair> generateConstraint(MethodCall forMethod, MethodAssumption assumption,
TypeInferenceBlockInformation info, GenericsResolver resolver){ TypeInferenceBlockInformation info, GenericsResolver resolver){
Constraint methodConstraint = new Constraint(); Constraint methodConstraint = new Constraint();
methodConstraint.add(ConstraintsFactory.createPair(forMethod.receiver.getType(), assumption.getReceiverType(), ClassOrInterface receiverCl = assumption.getReceiver();
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
for(GenericTypeVar gtv : receiverCl.getGenerics()){
//if(gtv.definingClass().equals(info.getCurrentClass().getClassName())){
// params.add(new GenericRefType(gtv.getName(), forMethod.getOffset()));
//}else{
//Die Generics werden alle zu TPHs umgewandelt.
params.add(TypePlaceholder.fresh(forMethod.getOffset()));
//}
}
RefTypeOrTPHOrWildcardOrGeneric receiverType = new RefType(assumption.getReceiver().getClassName(), params, forMethod.getOffset());
methodConstraint.add(ConstraintsFactory.createPair(forMethod.receiver.getType(), receiverType,
PairOperator.SMALLERDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver)); PairOperator.SMALLERDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver));
methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(), methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(),
PairOperator.EQUALSDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver)); PairOperator.EQUALSDOT, info.getCurrentTypeScope(), assumption.getTypeScope(), resolver));
@ -302,6 +323,7 @@ public class TYPEStmt implements StatementVisitor{
public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) { public static List<MethodAssumption> getMethods(String name, int numArgs, TypeInferenceBlockInformation info) {
List<MethodAssumption> ret = new ArrayList<>(); List<MethodAssumption> ret = new ArrayList<>();
/*
if(name.equals("apply")){ if(name.equals("apply")){
List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>(); List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>();
for(int i = 0; i< numArgs + 1 ; i++){ for(int i = 0; i< numArgs + 1 ; i++){
@ -320,13 +342,14 @@ public class TYPEStmt implements StatementVisitor{
} }
})); }));
} }
*/
for(ClassOrInterface cl : info.getAvailableClasses()){ for(ClassOrInterface cl : info.getAvailableClasses()){
for(Method m : cl.getMethods()){ for(Method m : cl.getMethods()){
if(m.getName().equals(name) && if(m.getName().equals(name) &&
m.getParameterList().getFormalparalist().size() == numArgs){ m.getParameterList().getFormalparalist().size() == numArgs){
RefTypeOrTPHOrWildcardOrGeneric retType = info.checkGTV(m.getType()); RefTypeOrTPHOrWildcardOrGeneric retType = info.checkGTV(m.getType());
ret.add(new MethodAssumption(cl.getType(), retType, convertParams(m.getParameterList(),info), ret.add(new MethodAssumption(cl, retType, convertParams(m.getParameterList(),info),
createTypeScope(cl, m))); createTypeScope(cl, m)));
} }
} }
@ -361,7 +384,7 @@ public class TYPEStmt implements StatementVisitor{
if(cl.getClassName().equals(ofType.getName())){ if(cl.getClassName().equals(ofType.getName())){
for(Method m : cl.getConstructors()){ for(Method m : cl.getConstructors()){
if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){ if(m.getParameterList().getFormalparalist().size() == argList.getArguments().size()){
ret.add(new MethodAssumption(cl.getType(), ofType, convertParams(m.getParameterList(), ret.add(new MethodAssumption(cl, ofType, convertParams(m.getParameterList(),
info), createTypeScope(cl, m))); info), createTypeScope(cl, m)));
} }
} }

View File

@ -28,6 +28,7 @@ public class FiniteClosure implements IFiniteClosure {
*/ */
private HashMap<String, Set<Node<UnifyType>>> strInheritanceGraph; private HashMap<String, Set<Node<UnifyType>>> strInheritanceGraph;
/** /**
* The initial pairs of that define the inheritance tree * The initial pairs of that define the inheritance tree
*/ */

View File

@ -24,8 +24,10 @@ public final class TypeParams implements Iterable<UnifyType>{
*/ */
public TypeParams(List<UnifyType> types){ public TypeParams(List<UnifyType> types){
typeParams = new UnifyType[types.size()]; typeParams = new UnifyType[types.size()];
for(int i=0;i<types.size();i++) for(int i=0;i<types.size();i++){
typeParams[i] = types.get(i); typeParams[i] = types.get(i);
if(types.get(i)==null)throw new NullPointerException();
}
// Hashcode calculation is expensive and must be cached. // Hashcode calculation is expensive and must be cached.
hashCode = Arrays.deepHashCode(typeParams); hashCode = Arrays.deepHashCode(typeParams);
@ -150,6 +152,10 @@ public final class TypeParams implements Iterable<UnifyType>{
if(other.size() != this.size()) if(other.size() != this.size())
return false; return false;
for(int i = 0; i < this.size(); i++){
if(this.get(i) == null)
System.out.print("s");
}
for(int i = 0; i < this.size(); i++) for(int i = 0; i < this.size(); i++)
if(!(this.get(i).equals(other.get(i)))) if(!(this.get(i).equals(other.get(i))))
return false; return false;