summaryrefslogtreecommitdiff
path: root/src/reflect
diff options
context:
space:
mode:
authorLukas Rytz <lukas.rytz@gmail.com>2016-01-19 15:30:51 +0100
committerLukas Rytz <lukas.rytz@gmail.com>2016-01-19 16:27:41 +0100
commita3e62cc194699254aa689030b155a29af8356619 (patch)
tree1aec1b5af65d5483df58314e219dfce14f064c52 /src/reflect
parented74a84113fab294391eda19efab6d172f414c01 (diff)
downloadscala-a3e62cc194699254aa689030b155a29af8356619.tar.gz
scala-a3e62cc194699254aa689030b155a29af8356619.tar.bz2
scala-a3e62cc194699254aa689030b155a29af8356619.zip
SD-70 Don't share footnotes across multiple calls to universe.showRaw
Before this commit, multiple invocations of universe.showRaw used a shared weak map that caches footnotes. If the two printed objects have equal components printed as footnotes, e.g., an equal TypeRef, the result of the second invocation depends on whether the object has been collected (and removed from the weak map) or not. See https://github.com/scala/scala-dev/issues/70#issuecomment-171701671
Diffstat (limited to 'src/reflect')
-rw-r--r--src/reflect/scala/reflect/api/Printers.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala48
2 files changed, 24 insertions, 26 deletions
diff --git a/src/reflect/scala/reflect/api/Printers.scala b/src/reflect/scala/reflect/api/Printers.scala
index c0abc5120c..257dd6c43e 100644
--- a/src/reflect/scala/reflect/api/Printers.scala
+++ b/src/reflect/scala/reflect/api/Printers.scala
@@ -232,7 +232,7 @@ trait Printers { self: Universe =>
* @group Printers
*/
def showRaw(any: Any, printTypes: BooleanFlag = None, printIds: BooleanFlag = None, printOwners: BooleanFlag = None, printKinds: BooleanFlag = None, printMirrors: BooleanFlag = None, printPositions: BooleanFlag = None): String =
- render(any, newRawTreePrinter(_), printTypes, printIds, printOwners, printKinds, printMirrors, printPositions)
+ render(any, newRawTreePrinter, printTypes, printIds, printOwners, printKinds, printMirrors, printPositions)
/** Hook to define what `showRaw(...)` means.
* @group Printers
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index 8fb7a0c1d0..37b99c4345 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -1134,11 +1134,12 @@ trait Printers extends api.Printers { self: SymbolTable =>
def newRawTreePrinter(writer: PrintWriter): RawTreePrinter = new RawTreePrinter(writer)
// provides footnotes for types and mirrors
- import scala.collection.mutable.{Map, WeakHashMap, SortedSet}
- private val footnoteIndex = new FootnoteIndex
- private class FootnoteIndex {
+ private class Footnotes {
+ import scala.collection.mutable.{Map, WeakHashMap, SortedSet}
+
private val index = Map[Class[_], WeakHashMap[Any, Int]]()
private def classIndex[T: ClassTag] = index.getOrElseUpdate(classTag[T].runtimeClass, WeakHashMap[Any, Int]())
+
private val counters = Map[Class[_], Int]()
private def nextCounter[T: ClassTag] = {
val clazz = classTag[T].runtimeClass
@@ -1147,29 +1148,26 @@ trait Printers extends api.Printers { self: SymbolTable =>
counters(clazz)
}
- def mkFootnotes() = new Footnotes
- class Footnotes {
- private val footnotes = Map[Class[_], SortedSet[Int]]()
- private def classFootnotes[T: ClassTag] = footnotes.getOrElseUpdate(classTag[T].runtimeClass, SortedSet[Int]())
+ private val footnotes = Map[Class[_], SortedSet[Int]]()
+ private def classFootnotes[T: ClassTag] = footnotes.getOrElseUpdate(classTag[T].runtimeClass, SortedSet[Int]())
- def put[T: ClassTag](any: T): Int = {
- val index = classIndex[T].getOrElseUpdate(any, nextCounter[T])
- classFootnotes[T] += index
- index
- }
+ def put[T: ClassTag](any: T): Int = {
+ val index = classIndex[T].getOrElseUpdate(any, nextCounter[T])
+ classFootnotes[T] += index
+ index
+ }
- def get[T: ClassTag]: List[(Int, Any)] =
- classFootnotes[T].toList map (fi => (fi, classIndex[T].find{ case (any, ii) => ii == fi }.get._1))
-
- def print[T: ClassTag](printer: Printers.super.TreePrinter): Unit = {
- val footnotes = get[T]
- if (footnotes.nonEmpty) {
- printer.print(EOL)
- footnotes.zipWithIndex foreach {
- case ((fi, any), ii) =>
- printer.print("[", fi, "] ", any)
- if (ii < footnotes.length - 1) printer.print(EOL)
- }
+ def get[T: ClassTag]: List[(Int, Any)] =
+ classFootnotes[T].toList map (fi => (fi, classIndex[T].find{ case (any, ii) => ii == fi }.get._1))
+
+ def print[T: ClassTag](printer: Printers.super.TreePrinter): Unit = {
+ val footnotes = get[T]
+ if (footnotes.nonEmpty) {
+ printer.print(EOL)
+ footnotes.zipWithIndex foreach {
+ case ((fi, any), ii) =>
+ printer.print("[", fi, "] ", any)
+ if (ii < footnotes.length - 1) printer.print(EOL)
}
}
}
@@ -1180,7 +1178,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
private var depth = 0
private var printTypesInFootnotes = true
private var printingFootnotes = false
- private val footnotes = footnoteIndex.mkFootnotes()
+ private val footnotes = new Footnotes()
def print(args: Any*): Unit = {
// don't print type footnotes if the argument is a mere type