Backup. Not working state
This commit is contained in:
parent
6fd34fe523
commit
7cb3300e8a
src
@ -7,7 +7,7 @@ object InsertTypes {
|
||||
* @param eq
|
||||
* @return
|
||||
*/
|
||||
private def normalize(eq:Set[UnifyConstraint]) = {
|
||||
private def flatten(eq:Set[UnifyConstraint]) = {
|
||||
def substHelper(a: UnifyTV, withType: UnifyType,in: UnifyType) :UnifyType = in match {
|
||||
case UnifyRefType(n, p) => UnifyRefType(n,p.map(t => substHelper(a, withType, t)))
|
||||
case UnifyTV(n) =>
|
||||
@ -32,9 +32,33 @@ object InsertTypes {
|
||||
ret ++ alessdotB.map(cons => UnifyEqualsDot(cons.left, cons.right))
|
||||
}
|
||||
|
||||
|
||||
def insert(unifyResult: Set[Set[UnifyConstraint]], into: Class): Class = {
|
||||
|
||||
val normalized = unifyResult.map(normalize(_))
|
||||
val flatted = unifyResult.map(flatten(_))
|
||||
|
||||
/**
|
||||
* We have to also replace Reftypes with Generic variables
|
||||
* The unify algorithm does not know generic types and uses UnifyRefType for every type
|
||||
* we have to reverse that
|
||||
*/
|
||||
val genericNames:Set[String] = into.genericParams.map(_._1).flatMap(_ match {
|
||||
case GenericType(name) => Some(name)
|
||||
case _ => None
|
||||
}).toSet
|
||||
def convertFromUnifyConstraint(t: UnifyType): Type = t match {
|
||||
case UnifyTV(a) => TypeVariable(a)
|
||||
case UnifyRefType(n, List()) => if(genericNames.contains(n)) GenericType(n) else RefType(n, List())
|
||||
case UnifyRefType(n, params) => RefType(n, params.map(convertFromUnifyConstraint(_)))
|
||||
}
|
||||
def convertFromUnifyConstraint(c: UnifyConstraint): Constraint = c match {
|
||||
case UnifyLessDot(a, b) => LessDot(convertFromUnifyConstraint(a), convertFromUnifyConstraint(b))
|
||||
}
|
||||
def convertFromUnifyConstraint(cons: Set[UnifyConstraint]): Set[Constraint] = cons.map(convertFromUnifyConstraint(_))
|
||||
// TODO
|
||||
val constraints = flatted.map(convertFromUnifyConstraint(_))
|
||||
|
||||
/*
|
||||
|
||||
def extractTVNames(unifyType: UnifyType): Set[String] = unifyType match {
|
||||
case UnifyTV(name) => Set(name)
|
||||
@ -48,7 +72,8 @@ object InsertTypes {
|
||||
case UnifyLessDot(a,b) => Set(a, b)
|
||||
case UnifyEqualsDot(a,b) => Set(a,b)
|
||||
})).flatMap(extractTVNames(_))
|
||||
val constraints = normalized.map(_.map(replaceTVWithGeneric(_, genericNames)))
|
||||
val constraints = normalized.map(_.map(replaceRefTypeWithGeneric(_, genericNames)))
|
||||
*/
|
||||
val newMethods = into.methods.flatMap(m => constraints.map(cons => insert(cons, m)))
|
||||
Class(into.name, into.genericParams, into.superType, into.fields, newMethods)
|
||||
}
|
||||
@ -80,27 +105,30 @@ object InsertTypes {
|
||||
def substType(t: Type) = constraints.map(_ match {
|
||||
case EqualsDot(t1, t2) => if(t.equals(t1)) t2 else null
|
||||
case _ => null
|
||||
}).find(_ != null).getOrElse(t)
|
||||
}).find(_ != null)
|
||||
.map(replaceTVWithGeneric(_))
|
||||
.getOrElse(if(t.isInstanceOf[TypeVariable]) GenericType(t.asInstanceOf[TypeVariable].name) else t)
|
||||
|
||||
def getAllGenerics(from: Type): Set[Type] = from match {
|
||||
case RefType(name, params) => params.flatMap(getAllGenerics(_)).toSet
|
||||
case GenericType(a) => Set(GenericType(a))
|
||||
}
|
||||
|
||||
val genericRetType = substType(replaceTVWithGeneric(into.retType))
|
||||
val genericParams = into.params.map(p => (substType(replaceTVWithGeneric(p._1)), p._2))
|
||||
val genericsUsedInMethod = (Set(genericRetType) ++ genericParams.map(_._1)).flatMap(getAllGenerics(_))
|
||||
val constraintsForMethod = getLinkedConstraints(genericsUsedInMethod, constraints)
|
||||
val genericRetType = substType(into.retType)
|
||||
val genericParams = into.params.map(p => (substType(p._1), p._2))
|
||||
val tvsUsedInMethod = (Set(genericRetType) ++ genericParams.map(_._1)).flatMap(getAllGenerics(_))
|
||||
val constraintsForMethod = getLinkedConstraints(tvsUsedInMethod, constraints)
|
||||
|
||||
Method(into.genericParams ++ constraintsForMethod, genericRetType, into.name, genericParams, into.retExpr)
|
||||
}
|
||||
private def replaceTVWithGeneric(in: UnifyConstraint, genericNames: Set[String]): Constraint= in match {
|
||||
case UnifyLessDot(a,b) => LessDot(replaceTVWithGeneric(a, genericNames), replaceTVWithGeneric(b, genericNames))
|
||||
case UnifyEqualsDot(a, b) => EqualsDot(replaceTVWithGeneric(a, genericNames), replaceTVWithGeneric(b, genericNames))
|
||||
|
||||
private def replaceRefTypeWithGeneric(in: UnifyConstraint, genericNames: Set[String]): Constraint= in match {
|
||||
case UnifyLessDot(a,b) => LessDot(replaceRefTypeWithGeneric(a, genericNames), replaceRefTypeWithGeneric(b, genericNames))
|
||||
case UnifyEqualsDot(a, b) => EqualsDot(replaceRefTypeWithGeneric(a, genericNames), replaceRefTypeWithGeneric(b, genericNames))
|
||||
}
|
||||
private def replaceTVWithGeneric(in: UnifyType, genericNames: Set[String]) : Type = in match {
|
||||
private def replaceRefTypeWithGeneric(in: UnifyType, genericNames: Set[String]) : Type = in match {
|
||||
case UnifyRefType(name, List()) => if(genericNames.contains(name)) GenericType(name) else RefType(name,List())
|
||||
case UnifyRefType(name, params) => RefType(name, params.map(replaceTVWithGeneric(_, genericNames)))
|
||||
case UnifyRefType(name, params) => RefType(name, params.map(replaceRefTypeWithGeneric(_, genericNames)))
|
||||
case UnifyTV(name) => GenericType(name)
|
||||
}
|
||||
|
||||
|
@ -79,8 +79,8 @@ object Main {
|
||||
"class " + cl.name + prettyPrintGenericList(cl.genericParams.map(it => LessDot(it._1, it._2))) +
|
||||
" extends " + prettyPrintType(cl.superType) + "{\n" +
|
||||
cl.fields.map(f => {
|
||||
prettyPrintType(f._1) + " " + f._2 + ";"
|
||||
}).mkString("\n") +
|
||||
" " + prettyPrintType(f._1) + " " + f._2 + ";"
|
||||
}).mkString("\n") + "\n" +
|
||||
cl.methods.map(m => {
|
||||
" "+ prettyPrintGenericList(m.genericParams) + " " +
|
||||
prettyPrintType(m.retType) +" "+ m.name +"(" + m.params.map(tp=>prettyPrintType(tp._1) + " " + tp._2).mkString(", ") + ") {\n"+
|
||||
|
@ -284,7 +284,7 @@ object Unify {
|
||||
private def substHelper(a: UnifyTV, withType: UnifyType,in: UnifyType) :UnifyType = in match {
|
||||
case UnifyRefType(n, p) => UnifyRefType(n,p.map(t => substHelper(a, withType, t)))
|
||||
case UnifyTV(n) =>
|
||||
if(a.equals(in)){withType}else{in}
|
||||
if(a.name.equals(n)){withType}else{in}
|
||||
}
|
||||
|
||||
def subst(a: UnifyTV, substType: UnifyType,eq: Set[UnifyConstraint]): Set[UnifyConstraint] = {
|
||||
|
@ -73,4 +73,9 @@ class IntegrationTest extends FunSuite {
|
||||
val result = FJTypeinference.typeinference(input )
|
||||
println(result.map(it => Main.prettyPrintAST(it._2)))
|
||||
}
|
||||
test("list.add.2") {
|
||||
val input = "class List<A extends Object> extends Object{\n A head;\n List<A> tail;\n add( a){\n return new List(a, this);\n}\nget(){\nreturn this.head;\n}\n}\n\nclass Test extends Object{\nm(a){\nreturn a.add(this).get();\n}\n}"
|
||||
val result = FJTypeinference.typeinference(input )
|
||||
println(result.map(it => Main.prettyPrintAST(it._2)))
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user