Ä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));
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;
}
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){
List<String> nameList = new ArrayList();
Set<Class<?>> classes = getClassesInPackage(packageName);

View File

@ -184,7 +184,7 @@ public class SyntaxTreeGenerator{
block = stmtGen.convert(body.block());
}
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{
return new Method(modifiers, name, retType, modifiers, parameterList,block, gtvDeclarations, header.getStart());
}
@ -222,7 +222,7 @@ public class SyntaxTreeGenerator{
if(ctx.superclass() != null){
superClass = convert(ctx.superclass());
}else{
superClass = ASTFactory.createObjectClass().getType();
superClass = new RefType(ASTFactory.createObjectClass().getClassName(), ctx.getStart());
}
List<Field> fielddecl = convertFields(ctx.classBody(), generics);
List<Method> methods = convertMethods(ctx.classBody(), name, superClass, generics);
@ -269,7 +269,7 @@ public class SyntaxTreeGenerator{
int modifiers = 0;
ParameterList params = new ParameterList(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) {
@ -434,7 +434,7 @@ public class SyntaxTreeGenerator{
}else{
genericParams = createEmptyGenericDeclarationList(ctx.Identifier());
}
RefType superClass = ASTFactory.createObjectClass().getType();
RefType superClass = ASTFactory.createObjectType();
List<Field> fields = convertFields(ctx.interfaceBody());
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) {
List<RefTypeOrTPHOrWildcardOrGeneric> ret = new ArrayList<>();
if(typeBoundContext == null){
ret.add(ASTFactory.createObjectClass().getType());
ret.add(ASTFactory.createObjectType());
return ret;
}
if(typeBoundContext.typeVariable() != null){

View File

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

View File

@ -60,10 +60,12 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
return this.methods;
}
/*
public RefType getType() {
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){
//Hier wird immer ein generischer Typ generiert, also mit Type placeholdern
List<RefTypeOrTPHOrWildcardOrGeneric> params = new ArrayList<>();
@ -74,6 +76,10 @@ public class ClassOrInterface extends SyntaxTreeNode implements TypeScope{
return new RefType(name, params, offset);
}
/**
* Die Superklasse im Kontext dieser ClassOrInterface
* Das bedeutet, dass generische Variablen als GenericRefTypes dargestellt sind
*/
public RefType getSuperClass() {
return superClass;
}

View File

@ -15,8 +15,8 @@ public class Constructor extends Method {
//TODO: Constructor braucht ein super-Statement
public Constructor(int modifier, String name, RefTypeOrTPHOrWildcardOrGeneric returnType, int modifiers, ParameterList parameterList, Block codeInsideConstructor,
GenericDeclarationList gtvDeclarations, Token offset, List<Statement> fieldInitializations, RefType superClass) {
super(modifier, name, returnType, modifiers, parameterList, prepareBlock(codeInsideConstructor,fieldInitializations, superClass), gtvDeclarations, offset);
GenericDeclarationList gtvDeclarations, Token offset, List<Statement> fieldInitializations) {
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
* 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();
statements.add(0, new SuperCall(constructorBlock.getOffset()));
return new Block(statements, constructorBlock.getOffset());

View File

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

View File

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

View File

@ -5,6 +5,7 @@ import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.List;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.GenericContext;
import de.dhbwstuttgart.parser.scope.GenericTypeName;
@ -45,7 +46,11 @@ public class ASTFactory {
java.lang.Class superjreClass = jreClass.getSuperclass();
RefType superClass;
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!)
superClass = (RefType) createType(java.lang.Object.class, name, "");
}
@ -83,13 +88,12 @@ public class ASTFactory {
return null;
}
return new de.dhbwstuttgart.syntaxtree.Constructor(constructor.getModifiers(), name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>(),
createType(inClass.getSuperclass()));
return new de.dhbwstuttgart.syntaxtree.Constructor(constructor.getModifiers(), name,returnType, modifier, parameterList, block, gtvDeclarations, offset, new ArrayList<>());
}
private static RefType createType(Class classType) {
return createClass(classType).getType();
}
//private static RefType createType(Class classType) {
// return createClass(classType).getType();
//}
public static Method createMethod(java.lang.reflect.Method jreMethod, java.lang.Class inClass){
String name = jreMethod.getName();
@ -182,6 +186,9 @@ public class ASTFactory {
public static ClassOrInterface createObjectClass() {
return createClass(Object.class);
}
public static RefType createObjectType() {
return new RefType(createClass(Object.class).getClassName(), new NullToken());
}
/*
public Constructor createEmptyConstructor(Class parent){

View File

@ -3,11 +3,13 @@ package de.dhbwstuttgart.syntaxtree.factory;
import java.util.*;
import java.util.stream.Collectors;
import de.dhbwstuttgart.environment.CompilationEnvironment;
import de.dhbwstuttgart.exceptions.DebugException;
import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.parser.NullToken;
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.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.UnifyType;
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<>();
for(ClassOrInterface cl : fromAvailableClasses){
UnifyType t1 = UnifyTypeFactory.convert(cl.getType());
UnifyType t2 = UnifyTypeFactory.convert(cl.getSuperClass());
pairs.add(generateSmallerPair(t1, t2));
for(ClassOrInterface cly : fromClasses){
pairs.addAll(getSuperTypes(cly, fromClasses));
}
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){
return new UnifyPair(tl, tr, PairOperator.SMALLER);
}

View File

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

View File

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

View File

@ -46,7 +46,8 @@ public class TypeInferenceInformation {
for(ClassOrInterface cl : classes){
for(Field m : cl.getFieldDecl()){
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 {
/**
* 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,
PairOperator equalsdot, TypeScope currentScope, TypeScope additionalScope,
GenericsResolver resolver){
@ -30,6 +41,7 @@ public class ConstraintsFactory {
return createPair(t1,t2,PairOperator.SMALLERDOT, currentScope, additionalScope, resolver);
}
private static RefTypeOrTPHOrWildcardOrGeneric checkGeneric(RefTypeOrTPHOrWildcardOrGeneric type,
TypeScope currentScope, TypeScope additionalScope,
GenericsResolver resolver){

View File

@ -6,14 +6,12 @@ import de.dhbwstuttgart.exceptions.NotImplementedException;
import de.dhbwstuttgart.exceptions.TypeinferenceException;
import de.dhbwstuttgart.parser.NullToken;
import de.dhbwstuttgart.parser.SyntaxTreeGenerator.AssignToLocal;
import de.dhbwstuttgart.parser.antlr.Java8Parser;
import de.dhbwstuttgart.syntaxtree.*;
import de.dhbwstuttgart.syntaxtree.statement.*;
import de.dhbwstuttgart.syntaxtree.statement.literal.Literal;
import de.dhbwstuttgart.syntaxtree.statement.literal.Null;
import de.dhbwstuttgart.syntaxtree.type.FunN;
import de.dhbwstuttgart.syntaxtree.type.RefType;
import de.dhbwstuttgart.syntaxtree.type.RefTypeOrTPHOrWildcardOrGeneric;
import de.dhbwstuttgart.syntaxtree.type.TypePlaceholder;
import de.dhbwstuttgart.syntaxtree.type.*;
import de.dhbwstuttgart.typeinference.assumptions.FieldAssumption;
import de.dhbwstuttgart.typeinference.assumptions.MethodAssumption;
import de.dhbwstuttgart.typeinference.assumptions.TypeInferenceBlockInformation;
@ -113,8 +111,10 @@ public class TYPEStmt implements StatementVisitor{
for(FieldAssumption fieldAssumption : info.getFields(fieldVar.fieldVarName)){
Constraint constraint = new Constraint();
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(
fieldVar.receiver.getType(),fieldAssumption.getReceiverType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver));
*/
constraint.add(ConstraintsFactory.createPair(
fieldVar.getType(),fieldAssumption.getType(), info.getCurrentTypeScope(), fieldAssumption.getTypeScope(), resolver));
oderConstraints.add(constraint);
@ -122,6 +122,9 @@ public class TYPEStmt implements StatementVisitor{
if(oderConstraints.size() == 0)
throw new TypeinferenceException("Kein Feld "+fieldVar.fieldVarName+ " gefunden", fieldVar.getOffset());
constraintsSet.addOderConstraint(oderConstraints);
//Wegen dem Problem oben:
throw new NotImplementedException();
}
@Override
@ -213,8 +216,15 @@ public class TYPEStmt implements StatementVisitor{
@Override
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(
aThis.getType(), info.getCurrentClass().getType(), PairOperator.EQUALSDOT, info.getCurrentTypeScope(),
aThis.getType(), thisType, PairOperator.EQUALSDOT, info.getCurrentTypeScope(),
createNullTypeScope(), getResolverInstance()));
}
@ -280,7 +290,18 @@ public class TYPEStmt implements StatementVisitor{
protected Constraint<Pair> generateConstraint(MethodCall forMethod, MethodAssumption assumption,
TypeInferenceBlockInformation info, GenericsResolver resolver){
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));
methodConstraint.add(ConstraintsFactory.createPair(assumption.getReturnType(), forMethod.getType(),
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) {
List<MethodAssumption> ret = new ArrayList<>();
/*
if(name.equals("apply")){
List<RefTypeOrTPHOrWildcardOrGeneric> funNParams = new ArrayList<>();
for(int i = 0; i< numArgs + 1 ; i++){
@ -320,13 +342,14 @@ public class TYPEStmt implements StatementVisitor{
}
}));
}
*/
for(ClassOrInterface cl : info.getAvailableClasses()){
for(Method m : cl.getMethods()){
if(m.getName().equals(name) &&
m.getParameterList().getFormalparalist().size() == numArgs){
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)));
}
}
@ -361,7 +384,7 @@ public class TYPEStmt implements StatementVisitor{
if(cl.getClassName().equals(ofType.getName())){
for(Method m : cl.getConstructors()){
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)));
}
}

View File

@ -28,6 +28,7 @@ public class FiniteClosure implements IFiniteClosure {
*/
private HashMap<String, Set<Node<UnifyType>>> strInheritanceGraph;
/**
* 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){
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);
if(types.get(i)==null)throw new NullPointerException();
}
// Hashcode calculation is expensive and must be cached.
hashCode = Arrays.deepHashCode(typeParams);
@ -150,6 +152,10 @@ public final class TypeParams implements Iterable<UnifyType>{
if(other.size() != this.size())
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++)
if(!(this.get(i).equals(other.get(i))))
return false;