diff options
author | Paul Phillips <paulp@improving.org> | 2012-02-29 14:20:31 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2012-02-29 14:20:31 -0800 |
commit | 105dc63121c84a45711b02f77f8e4a04074f7425 (patch) | |
tree | 9ff1a9f8bc5595d509632e9c6e3d7abc25145f35 | |
parent | a183c6ad31011b4fb1785655dd3d671b8f5bb519 (diff) | |
download | scala-105dc63121c84a45711b02f77f8e4a04074f7425.tar.gz scala-105dc63121c84a45711b02f77f8e4a04074f7425.tar.bz2 scala-105dc63121c84a45711b02f77f8e4a04074f7425.zip |
Merge remote-tracking branches 'VladUreche/issue/5527' and 'dragos/master' into develop
-rw-r--r-- | src/compiler/scala/reflect/internal/SymbolTable.scala | 8 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/ast/parser/Parsers.scala | 4 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/interactive/Global.scala | 1 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/util/WeakHashSet.scala | 60 | ||||
-rw-r--r-- | test/files/run/t5527.check | 20 | ||||
-rw-r--r-- | test/files/run/t5527.scala | 41 |
7 files changed, 129 insertions, 7 deletions
diff --git a/src/compiler/scala/reflect/internal/SymbolTable.scala b/src/compiler/scala/reflect/internal/SymbolTable.scala index 7745b21aad..c8c1a51102 100644 --- a/src/compiler/scala/reflect/internal/SymbolTable.scala +++ b/src/compiler/scala/reflect/internal/SymbolTable.scala @@ -8,6 +8,7 @@ package internal import scala.collection.{ mutable, immutable } import util._ +import scala.tools.nsc.util.WeakHashSet abstract class SymbolTable extends api.Universe with Collections @@ -266,9 +267,10 @@ abstract class SymbolTable extends api.Universe } } - def newWeakMap[K, V]() = recordCache(mutable.WeakHashMap[K, V]()) - def newMap[K, V]() = recordCache(mutable.HashMap[K, V]()) - def newSet[K]() = recordCache(mutable.HashSet[K]()) + def newWeakMap[K, V]() = recordCache(mutable.WeakHashMap[K, V]()) + def newMap[K, V]() = recordCache(mutable.HashMap[K, V]()) + def newSet[K]() = recordCache(mutable.HashSet[K]()) + def newWeakSet[K <: AnyRef]() = recordCache(new WeakHashSet[K]()) } /** Break into repl debugger if assertion is true. */ diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala index 2b95300bad..0e5f9ee80e 100644 --- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala +++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala @@ -2967,9 +2967,9 @@ self => val annots = annotations(true) val pos = in.offset val mods = (localModifiers() | implicitMod) withAnnotations annots - val defs = + val defs = joinComment( // for SI-5527 if (!(mods hasFlag ~(Flags.IMPLICIT | Flags.LAZY))) defOrDcl(pos, mods) - else List(tmplDef(pos, mods)) + else List(tmplDef(pos, mods))) in.token match { case RBRACE | CASE => defs :+ (Literal(Constant()) setPos o2p(in.offset)) diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala index 0f28407f5a..477cec8c8e 100644 --- a/src/compiler/scala/tools/nsc/interactive/Global.scala +++ b/src/compiler/scala/tools/nsc/interactive/Global.scala @@ -1052,7 +1052,6 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "") def newTyperRun() { currentTyperRun = new TyperRun - perRunCaches.clearAll() } class TyperResult(val tree: Tree) extends ControlThrowable diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala index e5df144f2e..be6200b353 100644 --- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala +++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala @@ -97,7 +97,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers { private val wasSpecializedForTypeVars = perRunCaches.newMap[Symbol, Set[Symbol]]() withDefaultValue Set() /** Concrete methods that use a specialized type, or override such methods. */ - private val concreteSpecMethods = perRunCaches.newSet[Symbol]() + private val concreteSpecMethods = perRunCaches.newWeakSet[Symbol]() private def isSpecialized(sym: Symbol) = sym hasAnnotation SpecializedClass private def hasSpecializedFlag(sym: Symbol) = sym hasFlag SPECIALIZED diff --git a/src/compiler/scala/tools/nsc/util/WeakHashSet.scala b/src/compiler/scala/tools/nsc/util/WeakHashSet.scala new file mode 100644 index 0000000000..6a10422b00 --- /dev/null +++ b/src/compiler/scala/tools/nsc/util/WeakHashSet.scala @@ -0,0 +1,60 @@ +package scala.tools.nsc.util + +import scala.collection.mutable +import scala.collection.mutable.ArrayBuffer +import scala.collection.mutable.Builder +import scala.collection.mutable.SetBuilder +import scala.runtime.AbstractFunction1 + +/** A bare-bones implementation of a mutable `Set` that uses weak references + * to hold the elements. + * + * This implementation offers only add/remove/test operations, + * therefore it does not fulfill the contract of Scala collection sets. + */ +class WeakHashSet[T <: AnyRef] extends AbstractFunction1[T, Boolean] { + private val underlying = mutable.HashSet[WeakReferenceWithEquals[T]]() + + /** Add the given element to this set. */ + def +=(elem: T): this.type = { + underlying += new WeakReferenceWithEquals(elem) + this + } + + /** Remove the given element from this set. */ + def -=(elem: T): this.type = { + underlying -= new WeakReferenceWithEquals(elem) + this + } + + /** Does the given element belong to this set? */ + def contains(elem: T): Boolean = + underlying.contains(new WeakReferenceWithEquals(elem)) + + /** Does the given element belong to this set? */ + def apply(elem: T): Boolean = contains(elem) + + /** Return the number of elements in this set, including reclaimed elements. */ + def size = underlying.size + + /** Remove all elements in this set. */ + def clear() = underlying.clear() +} + +/** A WeakReference implementation that implements equals and hashCode by + * delegating to the referent. + */ +class WeakReferenceWithEquals[T <: AnyRef](ref: T) { + def get(): T = underlying.get() + + override val hashCode = ref.hashCode + + override def equals(other: Any): Boolean = other match { + case wf: WeakReferenceWithEquals[_] => + underlying.get() == wf.get() + case _ => + false + } + + private val underlying = new java.lang.ref.WeakReference(ref) +} diff --git a/test/files/run/t5527.check b/test/files/run/t5527.check new file mode 100644 index 0000000000..cae1a80199 --- /dev/null +++ b/test/files/run/t5527.check @@ -0,0 +1,20 @@ +[[syntax trees at end of parser]]// Scala source: newSource1 +package <empty> { + abstract trait Test extends scala.ScalaObject { + def $init$() = { + () + }; + def sth: scala.Unit = { + /** Some comment here */ + object Maybe extends scala.ScalaObject { + def <init>() = { + super.<init>(); + () + }; + /** Some comment inside */ + def nothing() = () + }; + () + } + } +} diff --git a/test/files/run/t5527.scala b/test/files/run/t5527.scala new file mode 100644 index 0000000000..3badffde14 --- /dev/null +++ b/test/files/run/t5527.scala @@ -0,0 +1,41 @@ +import scala.tools.partest._ +import java.io._ +import scala.tools.nsc._ +import scala.tools.nsc.util.CommandLineParser +import scala.tools.nsc.doc.{Settings, DocFactory} +import scala.tools.nsc.reporters.ConsoleReporter + +object Test extends DirectTest { + + override def extraSettings: String = "-usejavacp -Xprint:parser -Yrangepos -Ystop-after:parser -d " + testOutput.path + + override def code = """ + // SI-5527 + trait Test { + def sth { + /** Some comment here */ + object Maybe { + /** Some comment inside */ + def nothing() = () + } + } + } + """ + + override def show(): Unit = { + // redirect err to out, for logging + val prevErr = System.err + System.setErr(System.out) + compile() + System.setErr(prevErr) + } + + override def newCompiler(args: String*): Global = { + // we want the Scaladoc compiler here, because it keeps DocDef nodes in the tree + val settings = new Settings(_ => ()) + val command = new ScalaDoc.Command((CommandLineParser tokenize extraSettings) ++ args.toList, settings) + new DocFactory(new ConsoleReporter(settings), settings).compiler + } + + override def isDebug = false // so we don't get the newSettings warning +} |