summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHubert Plociniczak <hubert.plociniczak@epfl.ch>2010-02-10 16:51:13 +0000
committerHubert Plociniczak <hubert.plociniczak@epfl.ch>2010-02-10 16:51:13 +0000
commit4de81a05b3cc682a92eb43fb023314d580f639fb (patch)
treed96436ea1aac0a332dab5bdc3aab31b71b12bd43
parenta165920200847b9aa336786dffc5d33ce5b86ab8 (diff)
downloadscala-4de81a05b3cc682a92eb43fb023314d580f639fb.tar.gz
scala-4de81a05b3cc682a92eb43fb023314d580f639fb.tar.bz2
scala-4de81a05b3cc682a92eb43fb023314d580f639fb.zip
Closes #2651
-rw-r--r--src/compiler/scala/tools/nsc/dependencies/Changes.scala35
-rw-r--r--test/files/buildmanager/t2651_1/A.scala1
-rw-r--r--test/files/buildmanager/t2651_1/B.scala2
-rw-r--r--test/files/buildmanager/t2651_1/C.scala3
-rw-r--r--test/files/buildmanager/t2651_1/D.scala3
-rw-r--r--test/files/buildmanager/t2651_1/t2651_1.changes/A2.scala2
-rw-r--r--test/files/buildmanager/t2651_1/t2651_1.check19
-rw-r--r--test/files/buildmanager/t2651_1/t2651_1.test3
-rw-r--r--test/files/buildmanager/t2651_2/A.scala1
-rw-r--r--test/files/buildmanager/t2651_2/t2651_2.changes/A2.scala1
-rw-r--r--test/files/buildmanager/t2651_2/t2651_2.check6
-rw-r--r--test/files/buildmanager/t2651_2/t2651_2.test3
-rw-r--r--test/files/buildmanager/t2651_3/A.scala3
-rw-r--r--test/files/buildmanager/t2651_3/t2651_3.changes/A2.scala3
-rw-r--r--test/files/buildmanager/t2651_3/t2651_3.check6
-rw-r--r--test/files/buildmanager/t2651_3/t2651_3.test3
-rw-r--r--test/files/buildmanager/t2651_4/A.scala5
-rw-r--r--test/files/buildmanager/t2651_4/B.scala3
-rw-r--r--test/files/buildmanager/t2651_4/t2651_4.changes/A2.scala5
-rw-r--r--test/files/buildmanager/t2651_4/t2651_4.check13
-rw-r--r--test/files/buildmanager/t2651_4/t2651_4.test3
21 files changed, 111 insertions, 12 deletions
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
diff --git a/test/files/buildmanager/t2651_1/A.scala b/test/files/buildmanager/t2651_1/A.scala
new file mode 100644
index 0000000000..d712f6febe
--- /dev/null
+++ b/test/files/buildmanager/t2651_1/A.scala
@@ -0,0 +1 @@
+trait A[T]
diff --git a/test/files/buildmanager/t2651_1/B.scala b/test/files/buildmanager/t2651_1/B.scala
new file mode 100644
index 0000000000..a8aca3d0ed
--- /dev/null
+++ b/test/files/buildmanager/t2651_1/B.scala
@@ -0,0 +1,2 @@
+trait B[T] extends A[T]
+
diff --git a/test/files/buildmanager/t2651_1/C.scala b/test/files/buildmanager/t2651_1/C.scala
new file mode 100644
index 0000000000..690dcf518d
--- /dev/null
+++ b/test/files/buildmanager/t2651_1/C.scala
@@ -0,0 +1,3 @@
+object C {
+ new A[Int] {}
+}
diff --git a/test/files/buildmanager/t2651_1/D.scala b/test/files/buildmanager/t2651_1/D.scala
new file mode 100644
index 0000000000..51273ad986
--- /dev/null
+++ b/test/files/buildmanager/t2651_1/D.scala
@@ -0,0 +1,3 @@
+object D {
+ def x[T](a: A[T]) = a
+}
diff --git a/test/files/buildmanager/t2651_1/t2651_1.changes/A2.scala b/test/files/buildmanager/t2651_1/t2651_1.changes/A2.scala
new file mode 100644
index 0000000000..574b522149
--- /dev/null
+++ b/test/files/buildmanager/t2651_1/t2651_1.changes/A2.scala
@@ -0,0 +1,2 @@
+trait A
+
diff --git a/test/files/buildmanager/t2651_1/t2651_1.check b/test/files/buildmanager/t2651_1/t2651_1.check
new file mode 100644
index 0000000000..8d2cbc8194
--- /dev/null
+++ b/test/files/buildmanager/t2651_1/t2651_1.check
@@ -0,0 +1,19 @@
+builder > A.scala B.scala C.scala D.scala
+compiling Set(A.scala, B.scala, C.scala, D.scala)
+Changes: Map()
+builder > A.scala
+compiling Set(A.scala)
+Changes: Map(trait A -> List(Changed(Class(A))[ tparams: List()]))
+invalidate B.scala because parents have changed [Changed(Class(A))[ tparams: List()]]
+invalidate C.scala because parents have changed [Changed(Class(A))[ tparams: List()]]
+invalidate D.scala because it references changed class [Changed(Class(A))[ tparams: List()]]
+compiling Set(B.scala, C.scala, D.scala)
+B.scala:1: error: A does not take type parameters
+trait B[T] extends A[T]
+ ^
+C.scala:2: error: A does not take type parameters
+ new A[Int] {}
+ ^
+D.scala:2: error: A does not take type parameters
+ def x[T](a: A[T]) = a
+ ^
diff --git a/test/files/buildmanager/t2651_1/t2651_1.test b/test/files/buildmanager/t2651_1/t2651_1.test
new file mode 100644
index 0000000000..4f67d5e233
--- /dev/null
+++ b/test/files/buildmanager/t2651_1/t2651_1.test
@@ -0,0 +1,3 @@
+>>compile A.scala B.scala C.scala D.scala
+>>update A.scala=>A2.scala
+>>compile A.scala
diff --git a/test/files/buildmanager/t2651_2/A.scala b/test/files/buildmanager/t2651_2/A.scala
new file mode 100644
index 0000000000..d712f6febe
--- /dev/null
+++ b/test/files/buildmanager/t2651_2/A.scala
@@ -0,0 +1 @@
+trait A[T]
diff --git a/test/files/buildmanager/t2651_2/t2651_2.changes/A2.scala b/test/files/buildmanager/t2651_2/t2651_2.changes/A2.scala
new file mode 100644
index 0000000000..7fb573e077
--- /dev/null
+++ b/test/files/buildmanager/t2651_2/t2651_2.changes/A2.scala
@@ -0,0 +1 @@
+trait A[S]
diff --git a/test/files/buildmanager/t2651_2/t2651_2.check b/test/files/buildmanager/t2651_2/t2651_2.check
new file mode 100644
index 0000000000..dd789b7565
--- /dev/null
+++ b/test/files/buildmanager/t2651_2/t2651_2.check
@@ -0,0 +1,6 @@
+builder > A.scala
+compiling Set(A.scala)
+Changes: Map()
+builder > A.scala
+compiling Set(A.scala)
+Changes: Map(trait A -> List())
diff --git a/test/files/buildmanager/t2651_2/t2651_2.test b/test/files/buildmanager/t2651_2/t2651_2.test
new file mode 100644
index 0000000000..d0614473ce
--- /dev/null
+++ b/test/files/buildmanager/t2651_2/t2651_2.test
@@ -0,0 +1,3 @@
+>>compile A.scala
+>>update A.scala=>A2.scala
+>>compile A.scala
diff --git a/test/files/buildmanager/t2651_3/A.scala b/test/files/buildmanager/t2651_3/A.scala
new file mode 100644
index 0000000000..14f9e4662f
--- /dev/null
+++ b/test/files/buildmanager/t2651_3/A.scala
@@ -0,0 +1,3 @@
+trait A[T, S] {
+ def x: T
+}
diff --git a/test/files/buildmanager/t2651_3/t2651_3.changes/A2.scala b/test/files/buildmanager/t2651_3/t2651_3.changes/A2.scala
new file mode 100644
index 0000000000..51bf27d1fa
--- /dev/null
+++ b/test/files/buildmanager/t2651_3/t2651_3.changes/A2.scala
@@ -0,0 +1,3 @@
+trait A[T, S] {
+ def x: S
+}
diff --git a/test/files/buildmanager/t2651_3/t2651_3.check b/test/files/buildmanager/t2651_3/t2651_3.check
new file mode 100644
index 0000000000..d4bac196e9
--- /dev/null
+++ b/test/files/buildmanager/t2651_3/t2651_3.check
@@ -0,0 +1,6 @@
+builder > A.scala
+compiling Set(A.scala)
+Changes: Map()
+builder > A.scala
+compiling Set(A.scala)
+Changes: Map(trait A -> List(Changed(Definition(A.x))[method x changed from ()T to ()S flags: <deferred> <method>]))
diff --git a/test/files/buildmanager/t2651_3/t2651_3.test b/test/files/buildmanager/t2651_3/t2651_3.test
new file mode 100644
index 0000000000..d0614473ce
--- /dev/null
+++ b/test/files/buildmanager/t2651_3/t2651_3.test
@@ -0,0 +1,3 @@
+>>compile A.scala
+>>update A.scala=>A2.scala
+>>compile A.scala
diff --git a/test/files/buildmanager/t2651_4/A.scala b/test/files/buildmanager/t2651_4/A.scala
new file mode 100644
index 0000000000..63f2a1643e
--- /dev/null
+++ b/test/files/buildmanager/t2651_4/A.scala
@@ -0,0 +1,5 @@
+trait A[T, S] {
+ def x: T
+ def y(a: T)
+ def z[B <: T]
+}
diff --git a/test/files/buildmanager/t2651_4/B.scala b/test/files/buildmanager/t2651_4/B.scala
new file mode 100644
index 0000000000..b33dbde676
--- /dev/null
+++ b/test/files/buildmanager/t2651_4/B.scala
@@ -0,0 +1,3 @@
+trait B extends A[Int, String] {
+ def x = 3
+}
diff --git a/test/files/buildmanager/t2651_4/t2651_4.changes/A2.scala b/test/files/buildmanager/t2651_4/t2651_4.changes/A2.scala
new file mode 100644
index 0000000000..f155129d13
--- /dev/null
+++ b/test/files/buildmanager/t2651_4/t2651_4.changes/A2.scala
@@ -0,0 +1,5 @@
+trait A[S, T] {
+ def x: T
+ def y(a: T)
+ def z[B <: T]
+}
diff --git a/test/files/buildmanager/t2651_4/t2651_4.check b/test/files/buildmanager/t2651_4/t2651_4.check
new file mode 100644
index 0000000000..c4ce382b5f
--- /dev/null
+++ b/test/files/buildmanager/t2651_4/t2651_4.check
@@ -0,0 +1,13 @@
+builder > A.scala B.scala
+compiling Set(A.scala, B.scala)
+Changes: Map()
+builder > A.scala
+compiling Set(A.scala)
+Changes: Map(trait A -> List(Changed(Definition(A.x))[method x changed from ()T to ()T flags: <deferred> <method>], Changed(Definition(A.y))[method y changed from (a: T)Unit to (a: T)Unit flags: <deferred> <method>], Changed(Definition(A.z))[method z changed from [B <: T]()Unit to [B <: T]()Unit flags: <deferred> <method>]))
+invalidate B.scala because inherited method changed [Changed(Definition(A.x))[method x changed from ()T to ()T flags: <deferred> <method>]]
+compiling Set(B.scala)
+B.scala:2: error: type mismatch;
+ found : Int(3)
+ required: String
+ def x = 3
+ ^
diff --git a/test/files/buildmanager/t2651_4/t2651_4.test b/test/files/buildmanager/t2651_4/t2651_4.test
new file mode 100644
index 0000000000..6f3bd03361
--- /dev/null
+++ b/test/files/buildmanager/t2651_4/t2651_4.test
@@ -0,0 +1,3 @@
+>>compile A.scala B.scala
+>>update A.scala=>A2.scala
+>>compile A.scala