diff --git a/src/main/scala/hb/dhbw/FJTypeinference.scala b/src/main/scala/hb/dhbw/FJTypeinference.scala index 193a5f9..29f5ad4 100644 --- a/src/main/scala/hb/dhbw/FJTypeinference.scala +++ b/src/main/scala/hb/dhbw/FJTypeinference.scala @@ -13,12 +13,19 @@ object FJTypeinference { private def convertOrConstraints(constraints: List[Constraint]): Set[Set[Set[UnifyConstraint]]] = constraints.map( convertOrCons ).toSet - def convertType(t: Type): UnifyType = t match { + private def convertType(t: Type): UnifyType = t match { case GenericType(name) => UnifyRefType(name, List()) case RefType(n, p) => UnifyRefType(n,p.map(convertType)) case TypeVariable(n) => UnifyTV(n) } + private def convertRefType(unifyType: UnifyRefType): FJNamedType = FJNamedType(unifyType.name, unifyType.params.map(convert(_))) + + private def convert(unifyType: UnifyType): FJType = unifyType match { + case UnifyRefType(n, p) => FJNamedType(n, p.map(convert(_))) + case UnifyTV(n) => FJTypeVariable(n) + } + private def convertSingleConstraint(constraint: Constraint) = constraint match { case LessDot(l, r) => UnifyLessDot(convertType(l),convertType(r)) case EqualsDot(l, r) => UnifyEqualsDot(convertType(l),convertType(r)) @@ -31,10 +38,14 @@ object FJTypeinference { val classExtension: (UnifyRefType, UnifyRefType) = (cToUnifyType(c), convertType(c.superType).asInstanceOf[UnifyRefType]) genericBounds + classExtension } - ).toSet) + ).map(it => (convertRefType(it._1), convertRefType(it._2))).toSet) private def cToUnifyType(c: Class): UnifyRefType = UnifyRefType(c.name, c.genericParams.map(it => convertType(it._1))) private def removeOverloadedSubtypeMethods(in: Class, finiteClosure: FiniteClosure) = { + def convertToFJType(in: Type): FJNamedType = in match { + case GenericType(name) => FJNamedType(name, List()) + case RefType(n, p) => FJNamedType(n,p.map(convertToFJType)) + } def methodIsSupertype(m : Method, superMethod: Method) = { def getBound(t: Type) = t match { case GenericType(x) => @@ -42,8 +53,7 @@ object FJTypeinference { .find(p => p._1.equals(GenericType(x))).map(_._2).get case x => x } - //finiteClosure.superTypes(getBound(m.retType)) - false + finiteClosure.aIsSubtypeOfb(convertToFJType(getBound(m.retType)), convertToFJType(getBound(superMethod.retType))) } val methodNames = in.methods.map(_.name) diff --git a/src/main/scala/hb/dhbw/FiniteClosure.scala b/src/main/scala/hb/dhbw/FiniteClosure.scala index c3411b9..b1b9bec 100644 --- a/src/main/scala/hb/dhbw/FiniteClosure.scala +++ b/src/main/scala/hb/dhbw/FiniteClosure.scala @@ -1,8 +1,9 @@ package hb.dhbw -sealed case class FJType() -sealed case class FJNamedType(name: String, params: List[FJType]) extends FJType -sealed case class FJTypeVariable(name: String) extends FJType +sealed trait FJType +case class FJNamedType(name: String, params: List[FJType]) extends FJType +case class FJTypeVariable(name: String) extends FJType + class FiniteClosure(val extendsRelations : Set[(FJNamedType, FJNamedType)]){ @@ -39,12 +40,9 @@ class FiniteClosure(val extendsRelations : Set[(FJNamedType, FJNamedType)]){ sClass.result() } - private def convert(unifyType: UnifyType): FJType = unifyType match { - case UnifyRefType(n, p) => FJNamedType(n, p.map(convert(_))) - case UnifyTV(n) => FJTypeVariable(n) - } + def superTypes(of : FJNamedType) : Set[FJNamedType] = calculateSupertypes(of) - def superTypes(of : UnifyRefType) : Set[UnifyRefType] = calculateSupertypes(convert(of).asInstanceOf[FJNamedType]) + def aIsSubtypeOfb(a: FJNamedType, b: FJNamedType): Boolean = calculateSupertypes(a).contains(b) def isPossibleSupertype(of: String, superType: String): Boolean = { val extendsMap = extendsRelations.map(p => (p._1.name,p._2.name)).toMap diff --git a/src/main/scala/hb/dhbw/Unify.scala b/src/main/scala/hb/dhbw/Unify.scala index 7bf3e0a..b19637e 100644 --- a/src/main/scala/hb/dhbw/Unify.scala +++ b/src/main/scala/hb/dhbw/Unify.scala @@ -89,7 +89,7 @@ object Unify { }) val cUnifyLessDotACons: Set[Set[Set[UnifyConstraint]]] = eq.map(c => c match{ case UnifyLessDot(UnifyRefType(name,params), UnifyTV(a)) => - fc.superTypes(UnifyRefType(name,params)) + getSuperTypes(UnifyRefType(name,params), fc) .map(superType => Set(UnifyEqualsDot(UnifyTV(a), superType).asInstanceOf[UnifyConstraint])) case _ => null }).filter(s => s!=null) @@ -115,7 +115,7 @@ object Unify { val aUnifyLessDotCCons = aUnifyLessDotCConsAndBs.map{ case (ac:UnifyLessDot,Some(b)) => Set(Set(UnifyLessDot(b, ac.right))) ++ - fc.superTypes(ac.right.asInstanceOf[UnifyRefType]) + getSuperTypes(ac.right.asInstanceOf[UnifyRefType], fc) .map(superType => Set(UnifyEqualsDot(b, superType))) case (ac, None) => null }.filter(c => c != null).asInstanceOf[Set[Set[Set[UnifyConstraint]]]] @@ -167,11 +167,22 @@ object Unify { case x => x }) + private def convert(fjType: FJType): UnifyType = fjType match { + case FJNamedType(n, p) => UnifyRefType(n, p.map(convert)) + case FJTypeVariable(n) => UnifyTV(n) + } + private def convertNamedType(fjType: FJNamedType): UnifyRefType = UnifyRefType(fjType.name, fjType.params.map(convert)) + private def convertRefType(unifyType: UnifyRefType): FJNamedType = FJNamedType(unifyType.name, unifyType.params.map(convert(_))) + private def convert(unifyType: UnifyType): FJType = unifyType match { + case UnifyRefType(n, p) => FJNamedType(n, p.map(convert(_))) + case UnifyTV(n) => FJTypeVariable(n) + } + private def getSuperTypes(of: UnifyRefType, fc: FiniteClosure) = fc.superTypes(convertRefType(of)).map(convertNamedType) def adaptRule(eq: Set[UnifyConstraint], fc: FiniteClosure) = { eq.map(c => c match { case UnifyLessDot(UnifyRefType(an, ap), UnifyRefType(bn, bp)) => { if(fc.isPossibleSupertype(an, bn)){ - UnifyEqualsDot(fc.superTypes(UnifyRefType(an, ap)).find(r => r.name.equals(bn)).get, UnifyRefType(bn, bp)) + UnifyEqualsDot(getSuperTypes(UnifyRefType(an, ap), fc).find(r => r.name.equals(bn)).get, UnifyRefType(bn, bp)) }else{ UnifyLessDot(UnifyRefType(an, ap), UnifyRefType(bn, bp)) }