Backup. Not working state

This commit is contained in:
Andreas Stadelmeier 2021-11-30 03:47:07 +01:00
parent 6fd34fe523
commit 7cb3300e8a
4 changed files with 49 additions and 16 deletions

@ -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)))
}
}