From 4de81a05b3cc682a92eb43fb023314d580f639fb Mon Sep 17 00:00:00 2001 From: Hubert Plociniczak Date: Wed, 10 Feb 2010 16:51:13 +0000 Subject: Closes #2651 --- .../scala/tools/nsc/dependencies/Changes.scala | 35 ++++++++++++++-------- 1 file changed, 23 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/dependencies/Changes.scala b/src/compiler/scala/tools/nsc/dependencies/Changes.scala index 2486c71acb..3c000f8a18 100644 --- a/src/compiler/scala/tools/nsc/dependencies/Changes.scala +++ b/src/compiler/scala/tools/nsc/dependencies/Changes.scala @@ -41,6 +41,8 @@ abstract class Changes { } case class ParentChanged(e: Entity) extends Change + private val changedTypeParams = new mutable.ListBuffer[String] + private def sameSymbol(sym1: Symbol, sym2: Symbol): Boolean = sym1.fullName == sym2.fullName private def sameFlags(sym1: Symbol, sym2: Symbol): Boolean = @@ -49,14 +51,14 @@ abstract class Changes { annotationsChecked.forall(a => (sym1.hasAnnotation(a) == sym2.hasAnnotation(a))) - private def sameType(tp1: Type, tp2: Type) = { + private def sameType(tp1: Type, tp2: Type)(implicit strict: Boolean) = { def typeOf(tp: Type): String = tp.toString + "[" + tp.getClass + "]" val res = sameType0(tp1, tp2) //if (!res) println("\t different types: " + typeOf(tp1) + " : " + typeOf(tp2)) res } - private def sameType0(tp1: Type, tp2: Type): Boolean = ((tp1, tp2) match { + private def sameType0(tp1: Type, tp2: Type)(implicit strict: Boolean): Boolean = ((tp1, tp2) match { /*case (ErrorType, _) => false case (WildcardType, _) => false case (_, ErrorType) => false @@ -75,12 +77,18 @@ abstract class Changes { case (ConstantType(value1), ConstantType(value2)) => value1 == value2 case (TypeRef(pre1, sym1, args1), TypeRef(pre2, sym2, args2)) => - sameType(pre1, pre2) && - (sameSymbol(sym1, sym2) || - ( sym1.isType && sym2.isType && sameType(sym1.info, sym2.info))) && - (sym1.variance == sym2.variance) && - ((tp1.isHigherKinded && tp2.isHigherKinded && tp1.normalize =:= tp2.normalize) || - sameTypes(args1, args2)) + val testSymbols = + if (!sameSymbol(sym1, sym2)) { + val v = (!strict && sym1.isType && sym2.isType && sameType(sym1.info, sym2.info)) + if (v) changedTypeParams += sym1.fullName + v + } else + !sym1.isTypeParameter || !changedTypeParams.contains(sym1.fullName) + + testSymbols && sameType(pre1, pre2) && + (sym1.variance == sym2.variance) && + ((tp1.isHigherKinded && tp2.isHigherKinded && tp1.normalize =:= tp2.normalize) || + sameTypes(args1, args2)) // @M! normalize reduces higher-kinded case to PolyType's case (RefinedType(parents1, ref1), RefinedType(parents2, ref2)) => @@ -106,7 +114,7 @@ abstract class Changes { case (PolyType(tparams1, res1), PolyType(tparams2, res2)) => sameTypeParams(tparams1, tparams2) && sameType(res1, res2) case (ExistentialType(tparams1, res1), ExistentialType(tparams2, res2)) => - sameTypeParams(tparams1, tparams2) && sameType(res1, res2) + sameTypeParams(tparams1, tparams2)(false) && sameType(res1, res2)(false) case (TypeBounds(lo1, hi1), TypeBounds(lo2, hi2)) => sameType(lo1, lo2) && sameType(hi1, hi2) case (BoundedWildcardType(bounds), _) => @@ -139,25 +147,28 @@ abstract class Changes { ((tp1n ne tp1) || (tp2n ne tp2)) && sameType(tp1n, tp2n) } - private def sameTypeParams(tparams1: List[Symbol], tparams2: List[Symbol]) = + private def sameTypeParams(tparams1: List[Symbol], tparams2: List[Symbol])(implicit strict: Boolean) = sameTypes(tparams1 map (_.info), tparams2 map (_.info)) && sameTypes(tparams1 map (_.tpe), tparams2 map (_.tpe)) && (tparams1 corresponds tparams2)((t1, t2) => sameAnnotations(t1, t2)) - def sameTypes(tps1: List[Type], tps2: List[Type]) = (tps1 corresponds tps2)(sameType) + private def sameTypes(tps1: List[Type], tps2: List[Type])(implicit strict: Boolean) = + (tps1 corresponds tps2)(sameType(_, _)) /** Return the list of changes between 'from' and 'toSym.info'. */ def changeSet(from: Type, toSym: Symbol): List[Change] = { implicit val defaultReason = "types" + implicit val defaultStrictTypeRefTest = true val to = toSym.info + changedTypeParams.clear def omitSymbols(s: Symbol): Boolean = !s.hasFlag(LOCAL | LIFTED | PRIVATE) val cs = new mutable.ListBuffer[Change] if ((from.parents zip to.parents) exists { case (t1, t2) => !sameType(t1, t2) }) cs += Changed(toEntity(toSym))(from.parents.zip(to.parents).toString) - if (!sameTypeParams(from.typeParams, to.typeParams)) + if (!sameTypeParams(from.typeParams, to.typeParams)(false)) cs += Changed(toEntity(toSym))(" tparams: " + from.typeParams.zip(to.typeParams)) // new members not yet visited -- cgit v1.2.3