summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/build/maven/maven-deploy.xml38
-rw-r--r--src/build/pack.xml4
-rw-r--r--src/compiler/scala/reflect/internal/Symbols.scala3
-rw-r--r--src/compiler/scala/reflect/internal/Trees.scala10
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/DocComments.scala122
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala41
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/page/Template.scala4
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RangePositions.scala26
-rw-r--r--src/compiler/scala/tools/nsc/settings/ScalaSettings.scala1
-rw-r--r--src/compiler/scala/tools/nsc/transform/AddInterfaces.scala9
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala26
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala26
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala27
-rwxr-xr-xsrc/compiler/scala/tools/nsc/util/DocStrings.scala87
-rw-r--r--src/library/scala/collection/mutable/ConcurrentTrieMap.scala (renamed from src/library/scala/collection/mutable/Ctrie.scala)100
-rw-r--r--src/library/scala/collection/parallel/immutable/ParHashMap.scala12
-rw-r--r--src/library/scala/collection/parallel/immutable/ParHashSet.scala12
-rw-r--r--src/library/scala/collection/parallel/immutable/ParRange.scala12
-rw-r--r--src/library/scala/collection/parallel/immutable/ParVector.scala12
-rw-r--r--src/library/scala/collection/parallel/mutable/ParArray.scala2
-rw-r--r--src/library/scala/collection/parallel/mutable/ParConcurrentTrieMap.scala (renamed from src/library/scala/collection/parallel/mutable/ParCtrie.scala)66
-rw-r--r--src/library/scala/collection/parallel/mutable/ParHashMap.scala2
-rw-r--r--src/library/scala/collection/parallel/mutable/ParHashSet.scala2
-rw-r--r--src/library/scala/reflect/api/Trees.scala18
-rw-r--r--src/library/scala/util/Properties.scala24
31 files changed, 430 insertions, 281 deletions
diff --git a/src/build/maven/maven-deploy.xml b/src/build/maven/maven-deploy.xml
index 2e490163e0..e0f31a5db2 100644
--- a/src/build/maven/maven-deploy.xml
+++ b/src/build/maven/maven-deploy.xml
@@ -16,10 +16,15 @@
<property name="local.release.repository" value="${user.home}/.m2/repository" />
<property name="repository.credentials.id" value="sonatype-nexus" />
<property name="settings.file" value="${user.home}/.m2/settings.xml" />
-
+ <condition property="version.is.snapshot">
+ <contains string="${maven.version.number}" substring="-SNAPSHOT"/>
+ </condition>
+
<echo>Using server[${repository.credentials.id}] for maven repository credentials.
Please make sure that your ~/.m2/settings.xml has the needed username/password for this server id
</echo>
+
+
</target>
<target name="init.maven" depends="init.properties">
@@ -241,28 +246,31 @@
</target>
<!-- Local Targets -->
- <target name="deploy.snapshot.local" depends="deploy.local.init" description="Deploys the bundled snapshot of the Scala Lanaguage to a local maven repository">
- <deploy-local-all version="${maven.snapshot.version.number}" repository="${local.snapshot.repository}" />
+ <target name="deploy.snapshot.local" depends="deploy.local.init" if="version.is.snapshot" description="Deploys the bundled snapshot of the Scala Lanaguage to a local maven repository">
+ <deploy-local-all version="${maven.version.number}" repository="${local.snapshot.repository}" />
</target>
- <target name="deploy.release.local" depends="deploy.local.init" description="Deploys the bundled files as a release into the local Maven repository">
- <deploy-local-all version="${version.number}" repository="${local.release.repository}" />
+ <target name="deploy.release.local" depends="deploy.local.init" unless="version.is.snapshot" description="Deploys the bundled files as a release into the local Maven repository">
+ <deploy-local-all version="${maven.version.number}" repository="${local.release.repository}" />
</target>
+ <target name="deploy.local" depends="deploy.snapshot.local, deploy.release.local" description="Deploys the bundle files to the local maven repo."/>
- <!-- Remote Targets -->
- <target name="deploy.signed.snapshot" depends="deploy.remote.init" description="Deploys the bundled files as a snapshot into the desired remote Maven repository">
- <deploy-remote-signed-all version="${maven.snapshot.version.number}" repository="${remote.snapshot.repository}" />
+ <!-- Remote Signed Targets -->
+ <target name="deploy.signed.snapshot" depends="deploy.remote.init" if="version.is.snapshot" description="Deploys the bundled files as a snapshot into the desired remote Maven repository">
+ <deploy-remote-signed-all version="${maven.version.number}" repository="${remote.snapshot.repository}" />
</target>
- <target name="deploy.signed.release" depends="deploy.remote.init" description="Deploys the bundled files as a release into the desired remote Maven repository">
- <deploy-remote-signed-all version="${version.number}" repository="${remote.release.repository}" />
+ <target name="deploy.signed.release" depends="deploy.remote.init" unless="version.is.snapshot" description="Deploys the bundled files as a release into the desired remote Maven repository">
+ <deploy-remote-signed-all version="${maven.version.number}" repository="${remote.release.repository}" />
</target>
-
- <target name="deploy.snapshot" depends="deploy.remote.init" description="Deploys the bundled files as a snapshot into the desired remote Maven repository">
- <deploy-remote-all version="${maven.snapshot.version.number}" repository="${remote.snapshot.repository}" />
+ <target name="deploy.signed" depends="deploy.signed.release, deploy.signed.snapshot" description="Deploys signed bundles to remote repo"/>
+ <!-- Remote unsigned targets -->
+ <target name="deploy.snapshot" depends="deploy.remote.init" if="version.is.snapshot" description="Deploys the bundled files as a snapshot into the desired remote Maven repository">
+ <deploy-remote-all version="${maven.version.number}" repository="${remote.snapshot.repository}" />
</target>
- <target name="deploy.release" depends="deploy.remote.init" description="Deploys the bundled files as a release into the desired remote Maven repository">
- <deploy-remote-all version="${version.number}" repository="${remote.release.repository}" />
+ <target name="deploy.release" depends="deploy.remote.init" unless="version.is.snapshot" description="Deploys the bundled files as a release into the desired remote Maven repository">
+ <deploy-remote-all version="${maven.version.number}" repository="${remote.release.repository}" />
</target>
+ <target name="deploy" depends="deploy.snapshot, deploy.release" description="Deploys unsigned artifacts to the maven repo."/>
</project>
diff --git a/src/build/pack.xml b/src/build/pack.xml
index 90aec8e25b..e79895e3a8 100644
--- a/src/build/pack.xml
+++ b/src/build/pack.xml
@@ -299,7 +299,7 @@ MAIN DISTRIBUTION SBAZ
<target name="pack-maven.latest.unix" depends="pack-maven.docs" unless="os.win">
<symlink link="${dists.dir}/maven/latest"
- resource="${dists.dir}/maven/${version.number}"
+ resource="${version.number}"
overwrite="yes"/>
</target>
@@ -315,8 +315,6 @@ MAIN DISTRIBUTION SBAZ
<copy tofile="${dists.dir}/maven/${version.number}/build.xml"
file="${src.dir}/build/maven/maven-deploy.xml"/>
<!-- export properties for use when deploying -->
- <property name="maven.snapshot.version.number"
- value="${version.major}.${version.minor}.${version.patch}-SNAPSHOT"/>
<echoproperties destfile="${dists.dir}/maven/${version.number}/build.properties"/>
</target>
diff --git a/src/compiler/scala/reflect/internal/Symbols.scala b/src/compiler/scala/reflect/internal/Symbols.scala
index febc2ef330..9678d2b8cd 100644
--- a/src/compiler/scala/reflect/internal/Symbols.scala
+++ b/src/compiler/scala/reflect/internal/Symbols.scala
@@ -500,8 +500,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isClassLocalToConstructor = isClass && hasFlag(INCONSTRUCTOR)
final def isDerivedValueClass =
- isClass && info.parents.headOption.getOrElse(AnyClass.tpe).typeSymbol == AnyValClass &&
- !isPrimitiveValueClass
+ isClass && info.firstParent.typeSymbol == AnyValClass && !isPrimitiveValueClass
final def isMethodWithExtension =
isMethod && owner.isDerivedValueClass && !isParamAccessor && !isConstructor && !hasFlag(SUPERACCESSOR)
diff --git a/src/compiler/scala/reflect/internal/Trees.scala b/src/compiler/scala/reflect/internal/Trees.scala
index 77ea7392a8..9b1712b790 100644
--- a/src/compiler/scala/reflect/internal/Trees.scala
+++ b/src/compiler/scala/reflect/internal/Trees.scala
@@ -283,10 +283,16 @@ trait Trees extends api.Trees { self: SymbolTable =>
}
}
- private object posAssigner extends Traverser {
+ trait PosAssigner extends Traverser {
+ var pos: Position
+ }
+ protected[this] lazy val posAssigner: PosAssigner = new DefaultPosAssigner
+
+ protected class DefaultPosAssigner extends PosAssigner {
var pos: Position = _
override def traverse(t: Tree) {
- if (t != EmptyTree && t.pos == NoPosition) {
+ if (t eq EmptyTree) ()
+ else if (t.pos == NoPosition) {
t.setPos(pos)
super.traverse(t) // TODO: bug? shouldn't the traverse be outside of the if?
// @PP: it's pruning whenever it encounters a node with a
diff --git a/src/compiler/scala/tools/nsc/ast/DocComments.scala b/src/compiler/scala/tools/nsc/ast/DocComments.scala
index 6a6379cca2..678f7b3028 100755
--- a/src/compiler/scala/tools/nsc/ast/DocComments.scala
+++ b/src/compiler/scala/tools/nsc/ast/DocComments.scala
@@ -19,6 +19,8 @@ import scala.collection.mutable
*/
trait DocComments { self: Global =>
+ var cookedDocComments = Map[Symbol, String]()
+
def reporter: Reporter
/** The raw doc comment map */
@@ -50,21 +52,29 @@ trait DocComments { self: Global =>
else sym.owner.ancestors map (sym overriddenSymbol _) filter (_ != NoSymbol)
}
- /** The raw doc comment of symbol `sym`, minus @usecase and @define sections, augmented by
+ /** The raw doc comment of symbol `sym`, minus usecase and define sections, augmented by
* missing sections of an inherited doc comment.
* If a symbol does not have a doc comment but some overridden version of it does,
* the doc comment of the overridden version is copied instead.
*/
- def cookedDocComment(sym: Symbol, docStr: String = ""): String = {
- val ownComment = if (docStr.length == 0) docComments get sym map (_.template) getOrElse ""
- else DocComment(docStr).template
- superComment(sym) match {
- case None =>
- ownComment
- case Some(sc) =>
- if (ownComment == "") sc
- else merge(sc, ownComment, sym)
- }
+ def cookedDocComment(sym: Symbol, docStr: String = ""): String = cookedDocComments.get(sym) match {
+ case Some(comment) =>
+ comment
+ case None =>
+ val ownComment = if (docStr.length == 0) docComments get sym map (_.template) getOrElse ""
+ else DocComment(docStr).template
+ val comment = superComment(sym) match {
+ case None =>
+ if (ownComment.indexOf("@inheritdoc") != -1)
+ reporter.warning(sym.pos, "The comment for " + sym +
+ " contains @inheritdoc, but no parent comment is available to inherit from.")
+ ownComment.replaceAllLiterally("@inheritdoc", "<invalid inheritdoc annotation>")
+ case Some(sc) =>
+ if (ownComment == "") sc
+ else expandInheritdoc(sc, merge(sc, ownComment, sym), sym)
+ }
+ cookedDocComments += (sym -> comment)
+ comment
}
/** The cooked doc comment of symbol `sym` after variable expansion, or "" if missing.
@@ -99,10 +109,18 @@ trait DocComments { self: Global =>
*/
def useCases(sym: Symbol, site: Symbol): List[(Symbol, String, Position)] = {
def getUseCases(dc: DocComment) = {
- for (uc <- dc.useCases; defn <- uc.expandedDefs(sym, site)) yield
- (defn,
- expandVariables(merge(cookedDocComment(sym), uc.comment.raw, defn), sym, site),
- uc.pos)
+ val fullSigComment = cookedDocComment(sym)
+ for (uc <- dc.useCases; defn <- uc.expandedDefs(sym, site)) yield {
+ // use cases comments go through a series of transformations:
+ // 1 - filling in missing sections from the full signature
+ // 2 - expanding explicit inheritance @inheritdoc tags
+ // 3 - expanding variables like $COLL
+ val useCaseCommentRaw = uc.comment.raw
+ val useCaseCommentMerged = merge(fullSigComment, useCaseCommentRaw, defn)
+ val useCaseCommentInheritdoc = expandInheritdoc(fullSigComment, useCaseCommentMerged, sym)
+ val useCaseCommentVariables = expandVariables(useCaseCommentInheritdoc, sym, site)
+ (defn, useCaseCommentVariables, uc.pos)
+ }
}
getDocComment(sym) map getUseCases getOrElse List()
}
@@ -201,6 +219,80 @@ trait DocComments { self: Global =>
}
}
+ /**
+ * Expand inheritdoc tags
+ * - for the main comment we transform the inheritdoc into the super variable,
+ * and the variable expansion can expand it further
+ * - for the param, tparam and throws sections we must replace comments on the spot
+ *
+ * This is done separately, for two reasons:
+ * 1. It takes longer to run compared to merge
+ * 2. The inheritdoc annotation should not be used very often, as building the comment from pieces severely
+ * impacts performance
+ */
+ def expandInheritdoc(src: String, dst: String, sym: Symbol): String =
+ if (dst.indexOf("@inheritdoc") == -1)
+ dst
+ else {
+ val srcSections = tagIndex(src)
+ val dstSections = tagIndex(dst)
+ val srcTagMap = sectionTagMap(src, srcSections)
+ val srcNamedParams = Map() +
+ ("@param" -> paramDocs(src, "@param", srcSections)) +
+ ("@tparam" -> paramDocs(src, "@tparam", srcSections)) +
+ ("@throws" -> paramDocs(src, "@throws", srcSections))
+
+ val out = new StringBuilder
+
+ def replaceInheritdoc(src: String, dst: String) =
+ if (dst.indexOf("@inheritdoc") == -1)
+ dst
+ else
+ dst.replaceAllLiterally("@inheritdoc", src)
+
+ def getSourceSection(section: (Int, Int)): String = {
+
+ def getSectionHeader = extractSectionTag(dst, section) match {
+ case param@("@param"|"@tparam"|"@throws") => param + " " + extractSectionParam(dst, section)
+ case other => other
+ }
+
+ def sectionString(param: String, paramMap: Map[String, (Int, Int)]): String =
+ paramMap.get(param) match {
+ case Some(section) =>
+ // Cleanup the section tag and parameter
+ val sectionTextBounds = extractSectionText(src, section)
+ cleanupSectionText(src.substring(sectionTextBounds._1, sectionTextBounds._2))
+ case None =>
+ reporter.info(sym.pos, "The \"" + getSectionHeader + "\" annotation of the " + sym +
+ " comment contains @inheritdoc, but the corresponding section in the parent is not defined.", true)
+ "<invalid inheritdoc annotation>"
+ }
+
+ dst.substring(section._1, section._1 + 7) match {
+ case param@("@param "|"@tparam"|"@throws") => sectionString(extractSectionParam(dst, section), srcNamedParams(param.trim))
+ case _ => sectionString(extractSectionTag(dst, section), srcTagMap)
+ }
+ }
+
+ def mainComment(str: String, sections: List[(Int, Int)]): String =
+ if (str.trim.length > 3)
+ str.trim.substring(3, startTag(str, sections))
+ else
+ ""
+
+ // Append main comment
+ out.append("/**")
+ out.append(replaceInheritdoc(mainComment(src, srcSections), mainComment(dst, dstSections)))
+
+ // Append sections
+ for (section <- dstSections)
+ out.append(replaceInheritdoc(getSourceSection(section), dst.substring(section._1, section._2)))
+
+ out.append("*/")
+ out.toString
+ }
+
/** Maps symbols to the variable -> replacement maps that are defined
* in their doc comments
*/
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index a1d3846557..43c231cf2d 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -16,6 +16,47 @@ import scala.reflect.internal.Flags.TRAIT
trait Trees extends reflect.internal.Trees { self: Global =>
+ def treeLine(t: Tree): String =
+ if (t.pos.isDefined && t.pos.isRange) t.pos.lineContent.drop(t.pos.column - 1).take(t.pos.end - t.pos.start + 1)
+ else t.summaryString
+
+ def treeStatus(t: Tree, enclosingTree: Tree = null) = {
+ val parent = if (enclosingTree eq null) " " else " P#%5s".format(enclosingTree.id)
+
+ "[L%4s%8s] #%-6s %-15s %-10s // %s".format(t.pos.safeLine, parent, t.id, t.pos.show, t.shortClass, treeLine(t))
+ }
+ def treeSymStatus(t: Tree) = {
+ val line = if (t.pos.isDefined) "line %-4s".format(t.pos.safeLine) else " "
+ "#%-5s %s %-10s // %s".format(t.id, line, t.shortClass,
+ if (t.symbol ne NoSymbol) "(" + t.symbol.fullLocationString + ")"
+ else treeLine(t)
+ )
+ }
+
+ class ValidatingPosAssigner extends PosAssigner {
+ var pos: Position = _
+ override def traverse(t: Tree) {
+ if (t eq EmptyTree) ()
+ else if (t.pos == NoPosition) super.traverse(t setPos pos)
+ else if (globalPhase.id <= currentRun.picklerPhase.id) {
+ // When we prune due to encountering a position, traverse the
+ // pruned children so we can warn about those lacking positions.
+ t.children foreach { c =>
+ if ((c eq EmptyTree) || (c eq emptyValDef)) ()
+ else if (c.pos == NoPosition) {
+ reporter.warning(t.pos, " Positioned tree has unpositioned child in phase " + globalPhase)
+ inform("parent: " + treeSymStatus(t))
+ inform(" child: " + treeSymStatus(c) + "\n")
+ }
+ }
+ }
+ }
+ }
+
+ override protected[this] lazy val posAssigner: PosAssigner =
+ if (settings.Yrangepos.value && settings.debug.value || settings.Yposdebug.value) new ValidatingPosAssigner
+ else new DefaultPosAssigner
+
// --- additional cases --------------------------------------------------------
/** Only used during parsing */
case class Parens(args: List[Tree]) extends Tree
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index ab6125df61..ccebcfa54d 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -394,7 +394,7 @@ self =>
// object Main
def moduleName = newTermName(ScriptRunner scriptMain settings)
- def moduleBody = Template(List(scalaAnyRefConstr), emptyValDef, List(emptyInit, mainDef))
+ def moduleBody = Template(List(atPos(o2p(in.offset))(scalaAnyRefConstr)), emptyValDef, List(emptyInit, mainDef))
def moduleDef = ModuleDef(NoMods, moduleName, moduleBody)
// package <empty> { ... }
@@ -2738,7 +2738,7 @@ self =>
def anyrefParents() = {
val caseParents = if (mods.isCase) List(productConstr, serializableConstr) else Nil
parents0 ::: caseParents match {
- case Nil => List(scalaAnyRefConstr)
+ case Nil => List(atPos(o2p(in.offset))(scalaAnyRefConstr))
case ps => ps
}
}
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
index 5e5320ca9a..e35286b281 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/Template.scala
@@ -438,7 +438,9 @@ class Template(tpl: DocTemplateEntity) extends HtmlPage {
if(!comment.throws.isEmpty) {
<dt>Exceptions thrown</dt>
<dd>{
- val exceptionsXml: Iterable[scala.xml.NodeSeq] = (for(exception <- comment.throws ) yield <span class="cmt">{Text(exception._1) ++ bodyToHtml(exception._2)}</span> )
+ val exceptionsXml: Iterable[scala.xml.NodeSeq] =
+ for(exception <- comment.throws.toList.sortBy(_._1) ) yield
+ <span class="cmt">{Text(exception._1) ++ bodyToHtml(exception._2)}</span>
exceptionsXml.reduceLeft(_ ++ Text("") ++ _)
}</dd>
} else NodeSeq.Empty
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
index efa524503c..b088c643cb 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
@@ -38,7 +38,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory =>
val key = (sym, inTpl)
if (commentCache isDefinedAt key)
Some(commentCache(key))
- else { // not reached for use-case comments
+ else {
val c = defineComment(sym, inTpl)
if (c isDefined) commentCache += (sym, inTpl) -> c.get
c
diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
index d1f738a435..d08a363a9d 100644
--- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
@@ -168,7 +168,7 @@ self: scala.tools.nsc.Global =>
/** Position a tree.
* This means: Set position of a node and position all its unpositioned children.
*/
- override def atPos[T <: Tree](pos: Position)(tree: T): T =
+ override def atPos[T <: Tree](pos: Position)(tree: T): T = {
if (pos.isOpaqueRange) {
if (!tree.isEmpty && tree.pos == NoPosition) {
tree.setPos(pos)
@@ -182,6 +182,7 @@ self: scala.tools.nsc.Global =>
} else {
super.atPos(pos)(tree)
}
+ }
// ---------------- Validating positions ----------------------------------
@@ -190,26 +191,33 @@ self: scala.tools.nsc.Global =>
val source = if (tree.pos.isDefined) tree.pos.source else ""
inform("== "+prefix+" tree ["+tree.id+"] of type "+tree.productPrefix+" at "+tree.pos.show+source)
inform("")
- inform(tree.toString)
+ inform(treeStatus(tree))
inform("")
}
def positionError(msg: String)(body : => Unit) {
- inform("======= Bad positions: "+msg)
- inform("")
+ inform("======= Position error\n" + msg)
body
- inform("=== While validating")
- inform("")
- inform(tree.toString)
- inform("")
+ inform("\nWhile validating #" + tree.id)
+ inform(treeStatus(tree))
+ inform("\nChildren:")
+ tree.children map (t => " " + treeStatus(t, tree)) foreach inform
inform("=======")
throw new ValidateException(msg)
}
def validate(tree: Tree, encltree: Tree): Unit = {
+
if (!tree.isEmpty) {
+ if (settings.Yposdebug.value && (settings.verbose.value || settings.Yrangepos.value))
+ println("[%10s] %s".format("validate", treeStatus(tree, encltree)))
+
if (!tree.pos.isDefined)
- positionError("Unpositioned tree ["+tree.id+"]") { reportTree("Unpositioned", tree) }
+ positionError("Unpositioned tree #"+tree.id) {
+ inform("%15s %s".format("unpositioned", treeStatus(tree, encltree)))
+ inform("%15s %s".format("enclosing", treeStatus(encltree)))
+ encltree.children foreach (t => inform("%15s %s".format("sibling", treeStatus(t, encltree))))
+ }
if (tree.pos.isRange) {
if (!encltree.pos.isRange)
positionError("Synthetic tree ["+encltree.id+"] contains nonsynthetic tree ["+tree.id+"]") {
diff --git a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
index e949cb3eb2..5f3c7ec32c 100644
--- a/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
@@ -162,6 +162,7 @@ trait ScalaSettings extends AbsScalaSettings
val Ybuildmanagerdebug =
BooleanSetting ("-Ybuild-manager-debug", "Generate debug information for the Refined Build Manager compiler.")
val Ytyperdebug = BooleanSetting ("-Ytyper-debug", "Trace all type assignments.")
+ val Yposdebug = BooleanSetting ("-Ypos-debug", "Trace position validation.")
val Yinferdebug = BooleanSetting ("-Yinfer-debug", "Trace type inference and implicit search.")
val Ypmatdebug = BooleanSetting ("-Ypmat-debug", "Trace all pattern matcher activity.")
val Yreifycopypaste =
diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
index 555d0700ae..39e2cbe694 100644
--- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
+++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala
@@ -264,11 +264,10 @@ abstract class AddInterfaces extends InfoTransform { self: Erasure =>
else DefDef(clazz.primaryConstructor, Block(List(), Literal(Constant()))) :: stats
private def implTemplate(clazz: Symbol, templ: Template): Template = atPos(templ.pos) {
- val templ1 = atPos(templ.pos) {
- Template(templ.parents, emptyValDef,
- addMixinConstructorDef(clazz, templ.body map implMemberDef))
- .setSymbol(clazz.newLocalDummy(templ.pos))
- }
+ val templ1 = (
+ Template(templ.parents, emptyValDef, addMixinConstructorDef(clazz, templ.body map implMemberDef))
+ setSymbol clazz.newLocalDummy(templ.pos)
+ )
templ1.changeOwner(templ.symbol.owner -> clazz, templ.symbol -> templ1.symbol)
templ1
}
diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
index e6ad7cb922..4c3972519a 100644
--- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
@@ -105,7 +105,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
} else if (currentOwner.isStaticOwner) {
super.transform(tree)
} else tree
- case DefDef(mods, name, tparams, vparamss, tpt, rhs) if tree.symbol.isMethodWithExtension =>
+ case DefDef(_, _, tparams, vparamss, _, rhs) if tree.symbol.isMethodWithExtension =>
val companion = currentOwner.companionModule
val origMeth = tree.symbol
val extensionName = extensionNames(origMeth).head
@@ -132,15 +132,13 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
gen.mkTypeApply(gen.mkAttributedRef(companion), extensionMeth, origTpeParams map (_.tpe)),
List(This(currentOwner)))
val extensionCall = atOwner(origMeth) {
- localTyper.typed {
- atPos(rhs.pos) {
- (extensionCallPrefix /: vparamss) {
- case (fn, params) => Apply(fn, params map (param => Ident(param.symbol)))
- }
+ localTyper.typedPos(rhs.pos) {
+ (extensionCallPrefix /: vparamss) {
+ case (fn, params) => Apply(fn, params map (param => Ident(param.symbol)))
}
}
}
- treeCopy.DefDef(tree, mods, name, tparams, vparamss, tpt, extensionCall)
+ deriveDefDef(tree)(_ => extensionCall)
case _ =>
super.transform(tree)
}
@@ -148,14 +146,12 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] =
super.transformStats(stats, exprOwner) map {
- case stat @ ModuleDef(mods, name, tmpl @ Template(parents, self, body)) =>
- extensionDefs.remove(stat.symbol) match {
- case Some(buf) =>
- val extensionDefs = buf.toList map { mdef => atOwner(stat.symbol) { localTyper.typed(mdef) } }
- treeCopy.ModuleDef(stat, mods, name, treeCopy.Template(tmpl, parents, self, body ++ extensionDefs))
- case None =>
- stat
- }
+ case md @ ModuleDef(_, _, _) if extensionDefs contains md.symbol =>
+ val defns = extensionDefs(md.symbol).toList map (member =>
+ atOwner(md.symbol)(localTyper.typedPos(md.pos.focus)(member))
+ )
+ extensionDefs -= md.symbol
+ deriveModuleDef(md)(tmpl => deriveTemplate(tmpl)(_ ++ defns))
case stat =>
stat
}
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index d1e95e3a27..dfadd8d60e 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -86,6 +86,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
* nor do they have a setter (not if they are vals anyway). The usual
* logic for setting bitmaps does therefor not work for such fields.
* That's why they are excluded.
+ * Note: The `checkinit` option does not check if transient fields are initialized.
*/
private def needsInitFlag(sym: Symbol) = (
settings.checkInit.value
@@ -95,6 +96,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
&& !sym.accessed.hasFlag(PRESUPER)
&& !sym.isOuterAccessor
&& !(sym.owner isSubClass DelayedInitClass)
+ && !(sym.isGetter && (sym.accessed hasAnnotation TransientAttr))
)
/** Maps all parts of this type that refer to implementation classes to
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index 088a56cd7b..f32ad9293c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -69,6 +69,9 @@ trait MethodSynthesis {
import synthesisUtil._
class ClassMethodSynthesis(val clazz: Symbol, localTyper: Typer) {
+ def mkThis = This(clazz) setPos clazz.pos.focus
+ def mkThisSelect(sym: Symbol) = atPos(clazz.pos.focus)(Select(mkThis, sym))
+
private def isOverride(name: TermName) =
clazzMember(name).alternatives exists (sym => !sym.isDeferred && (sym.owner != clazz))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 955d51bf8d..c5fb13a5a9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -456,7 +456,7 @@ trait Namers extends MethodSynthesis {
// The object Foo is still in scope, but because it is not compiled in current run
// it should be ditched and a new one created.
if (m != NoSymbol && currentRun.compiles(m)) m
- else enterSyntheticSym(creator(cdef))
+ else enterSyntheticSym(atPos(cdef.pos.focus)(creator(cdef)))
}
private def checkSelectors(tree: Import): Unit = {
@@ -1270,11 +1270,12 @@ trait Namers extends MethodSynthesis {
if (sym.isModule) annotate(sym.moduleClass)
def getSig = tree match {
- case cdef @ ClassDef(_, _, tparams, impl) =>
+ case cdef @ ClassDef(_, name, tparams, impl) =>
val clazz = tree.symbol
val result = createNamer(tree).classSig(tparams, impl)
clazz setInfo result
if (clazz.isDerivedValueClass) {
+ log("Ensuring companion for derived value class " + name + " at " + cdef.pos.show)
clazz setFlag FINAL
enclosingNamerWithScope(clazz.owner.info.decls).ensureCompanionObject(cdef)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 1e17cb2e3f..ec42d251ff 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1523,16 +1523,11 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
case _ => ()
}
- // verify classes extending AnyVal meet the requirements
- // (whatever those are to be, but at least: @inline annotation)
+ // Verify classes extending AnyVal meet the requirements
private def checkAnyValSubclass(clazz: Symbol) = {
- if ((clazz isSubClass AnyValClass) && (clazz ne AnyValClass) && !isPrimitiveValueClass(clazz)) {
+ if ((clazz isSubClass AnyValClass) && !isPrimitiveValueClass(clazz)) {
if (clazz.isTrait)
unit.error(clazz.pos, "Only classes (not traits) are allowed to extend AnyVal")
- /* [Martin] That one is already taken care of by Typers
- if (clazz.tpe <:< AnyRefClass.tpe)
- unit.error(clazz.pos, "Classes which extend AnyVal may not have an ancestor which inherits AnyRef")
- */
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index f9d41bcc5e..2f4eff30d2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -51,11 +51,9 @@ trait SyntheticMethods extends ast.TreeDSL {
if (clazz0 == AnyValClass || isPrimitiveValueClass(clazz0)) return {
if (clazz0.info member nme.getClass_ isDeferred) {
- val getClassMethod = createMethod(nme.getClass_, getClassReturnType(clazz.tpe)) { sym =>
- // XXX dummy implementation for now
- NULL
- }
- treeCopy.Template(templ, templ.parents, templ.self, templ.body :+ getClassMethod)
+ // XXX dummy implementation for now
+ val getClassMethod = createMethod(nme.getClass_, getClassReturnType(clazz.tpe))(_ => NULL)
+ deriveTemplate(templ)(_ :+ getClassMethod)
}
else templ
}
@@ -89,7 +87,7 @@ trait SyntheticMethods extends ast.TreeDSL {
)
def forwardToRuntime(method: Symbol): Tree =
- forwardMethod(method, getMember(ScalaRunTimeModule, method.name prepend "_"))(This(clazz) :: _)
+ forwardMethod(method, getMember(ScalaRunTimeModule, method.name prepend "_"))(mkThis :: _)
// Any member, including private
def hasConcreteImpl(name: Name) =
@@ -109,7 +107,7 @@ trait SyntheticMethods extends ast.TreeDSL {
}
def productIteratorMethod = {
createMethod(nme.productIterator, iteratorOfType(accessorLub))(_ =>
- gen.mkMethodCall(ScalaRunTimeModule, nme.typedProductIterator, List(accessorLub), List(This(clazz)))
+ gen.mkMethodCall(ScalaRunTimeModule, nme.typedProductIterator, List(accessorLub), List(mkThis))
)
}
def projectionMethod(accessor: Symbol, num: Int) = {
@@ -157,8 +155,8 @@ trait SyntheticMethods extends ast.TreeDSL {
def equalsCore(eqmeth: Symbol, accessors: List[Symbol]) = {
val otherName = context.unit.freshTermName(clazz.name + "$")
val otherSym = eqmeth.newValue(otherName, eqmeth.pos, SYNTHETIC) setInfo clazz.tpe
- val pairwise = accessors map (acc => fn(Select(This(clazz), acc), acc.tpe member nme.EQ, Select(Ident(otherSym), acc)))
- val canEq = gen.mkMethodCall(otherSym, nme.canEqual_, Nil, List(This(clazz)))
+ val pairwise = accessors map (acc => fn(Select(mkThis, acc), acc.tpe member nme.EQ, Select(Ident(otherSym), acc)))
+ val canEq = gen.mkMethodCall(otherSym, nme.canEqual_, Nil, List(mkThis))
val tests = if (clazz.isDerivedValueClass || clazz.isFinal && syntheticCanEqual) pairwise else pairwise :+ canEq
thatTest(eqmeth) AND Block(
@@ -181,9 +179,9 @@ trait SyntheticMethods extends ast.TreeDSL {
def equalsCaseClassMethod: Tree = createMethod(nme.equals_, List(AnyClass.tpe), BooleanClass.tpe) { m =>
if (accessors.isEmpty)
if (clazz.isFinal) thatTest(m)
- else thatTest(m) AND ((thatCast(m) DOT nme.canEqual_)(This(clazz)))
+ else thatTest(m) AND ((thatCast(m) DOT nme.canEqual_)(mkThis))
else
- (This(clazz) ANY_EQ Ident(m.firstParam)) OR equalsCore(m, accessors)
+ (mkThis ANY_EQ Ident(m.firstParam)) OR equalsCore(m, accessors)
}
/** The equality method for value classes
@@ -200,9 +198,7 @@ trait SyntheticMethods extends ast.TreeDSL {
* def hashCode(): Int = this.underlying.hashCode
*/
def hashCodeDerivedValueClassMethod: Tree = createMethod(nme.hashCode_, Nil, IntClass.tpe) { m =>
- Select(
- Select(This(clazz), clazz.firstParamAccessor),
- nme.hashCode_)
+ Select(mkThisSelect(clazz.firstParamAccessor), nme.hashCode_)
}
/** The _1, _2, etc. methods to implement ProductN.
@@ -217,7 +213,7 @@ trait SyntheticMethods extends ast.TreeDSL {
List(
Product_productPrefix -> (() => constantNullary(nme.productPrefix, clazz.name.decode)),
Product_productArity -> (() => constantNullary(nme.productArity, arity)),
- Product_productElement -> (() => perElementMethod(nme.productElement, accessorLub)(Select(This(clazz), _))),
+ Product_productElement -> (() => perElementMethod(nme.productElement, accessorLub)(mkThisSelect)),
Product_iterator -> (() => productIteratorMethod),
Product_canEqual -> (() => canEqualMethod)
// This is disabled pending a reimplementation which doesn't add any
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 9a2ef88821..25f3e7af5c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1295,7 +1295,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
def parentTypes(templ: Template): List[Tree] =
- if (templ.parents.isEmpty) List(TypeTree(AnyRefClass.tpe))
+ if (templ.parents.isEmpty) List(atPos(templ.pos)(TypeTree(AnyRefClass.tpe)))
else try {
val clazz = context.owner
// Normalize supertype and mixins so that supertype is always a class, not a trait.
@@ -1723,7 +1723,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
* @param rhs ...
*/
def computeParamAliases(clazz: Symbol, vparamss: List[List[ValDef]], rhs: Tree) {
- debuglog("computing param aliases for "+clazz+":"+clazz.primaryConstructor.tpe+":"+rhs)//debug
+ log("computing param aliases for "+clazz+":"+clazz.primaryConstructor.tpe+":"+rhs)//debug
def decompose(call: Tree): (Tree, List[Tree]) = call match {
case Apply(fn, args) =>
val (superConstr, args1) = decompose(fn)
@@ -1902,11 +1902,12 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
transformedOrTyped(ddef.rhs, EXPRmode, tpt1.tpe)
}
- if (meth.isPrimaryConstructor && meth.isClassConstructor && !isPastTyper && !reporter.hasErrors && !meth.owner.isSubClass(AnyValClass)) {
- // At this point in AnyVal there is no supercall, which will blow up
- // in computeParamAliases; there's nothing to be computed for Anyval anyway.
- computeParamAliases(meth.owner, vparamss1, rhs1)
- }
+ if (meth.isPrimaryConstructor && meth.isClassConstructor && !isPastTyper && !reporter.hasErrors && !meth.owner.isSubClass(AnyValClass)) {
+ // At this point in AnyVal there is no supercall, which will blow up
+ // in computeParamAliases; there's nothing to be computed for Anyval anyway.
+ computeParamAliases(meth.owner, vparamss1, rhs1)
+ }
+
if (tpt1.tpe.typeSymbol != NothingClass && !context.returnsSeen && rhs1.tpe.typeSymbol != NothingClass)
rhs1 = checkDead(rhs1)
@@ -1925,6 +1926,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
if (meth.isStructuralRefinementMember)
checkMethodStructuralCompatible(meth)
+
treeCopy.DefDef(ddef, typedMods, ddef.name, tparams1, vparamss1, tpt1, rhs1) setType NoType
}
@@ -3264,6 +3266,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
def typedAnnotated(ann: Tree, arg1: Tree): Tree = {
+ def mkTypeTree(tpe: Type) = TypeTree(tpe) setOriginal tree setPos tree.pos.focus
/** mode for typing the annotation itself */
val annotMode = mode & ~TYPEmode | EXPRmode
@@ -3309,19 +3312,20 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
arg1 // simply drop erroneous annotations
else {
ann.tpe = atype
- TypeTree(atype) setOriginal tree
+ mkTypeTree(atype)
}
} else {
// the annotation was typechecked before
- TypeTree(ann.tpe) setOriginal tree
+ mkTypeTree(ann.tpe)
}
- } else {
+ }
+ else {
if (ann.tpe == null) {
val annotInfo = typedAnnotation(ann, annotMode)
ann.tpe = arg1.tpe.withAnnotation(annotInfo)
}
val atype = ann.tpe
- Typed(arg1, TypeTree(atype) setOriginal tree setPos tree.pos.focus) setPos tree.pos setType atype
+ Typed(arg1, mkTypeTree(atype)) setPos tree.pos setType atype
}
}
@@ -3626,7 +3630,6 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
val Select(qual, name) = fun
tryTypedArgs(args, forArgMode(fun, mode)) match {
case Some(args1) =>
- assert((args1.length == 0) || !args1.head.tpe.isErroneous, "try typed args is ok")
val qual1 =
if (!pt.isError) adaptToArguments(qual, name, args1, pt, true, true)
else qual
diff --git a/src/compiler/scala/tools/nsc/util/DocStrings.scala b/src/compiler/scala/tools/nsc/util/DocStrings.scala
index fbe92e5d84..f4ce6d6ef1 100755
--- a/src/compiler/scala/tools/nsc/util/DocStrings.scala
+++ b/src/compiler/scala/tools/nsc/util/DocStrings.scala
@@ -26,6 +26,14 @@ object DocStrings {
if (start < str.length && isIdentifierPart(str charAt start)) skipIdent(str, start + 1)
else start
+ /** Returns index of string `str` following `start` skipping
+ * sequence of identifier characters.
+ */
+ def skipTag(str: String, start: Int): Int =
+ if (start < str.length && (str charAt start) == '@') skipIdent(str, start + 1)
+ else start
+
+
/** Returns index of string `str` after `start` skipping longest
* sequence of space and tab characters, possibly also containing
* a single `*` character or the `/``**` sequence.
@@ -68,38 +76,46 @@ object DocStrings {
/** Produces a string index, which is a list of ``sections'', i.e
* pairs of start/end positions of all tagged sections in the string.
- * Every section starts with a `@` and extends to the next `@`, or
- * to the end of the comment string, but excluding the final two
+ * Every section starts with an at sign and extends to the next at sign,
+ * or to the end of the comment string, but excluding the final two
* characters which terminate the comment.
*
* Also take usecases into account - they need to expand until the next
* usecase or the end of the string, as they might include other sections
* of their own
*/
- def tagIndex(str: String, p: Int => Boolean = (idx => true)): List[(Int, Int)] =
- findAll(str, 0) (idx => str(idx) == '@' && p(idx)) match {
+ def tagIndex(str: String, p: Int => Boolean = (idx => true)): List[(Int, Int)] = {
+ var indices = findAll(str, 0) (idx => str(idx) == '@' && p(idx))
+ indices = mergeUsecaseSections(str, indices)
+ indices = mergeInheritdocSections(str, indices)
+
+ indices match {
case List() => List()
- case idxs => {
- val idxs2 = mergeUsecaseSections(str, idxs)
- idxs2 zip (idxs2.tail ::: List(str.length - 2))
- }
+ case idxs => idxs zip (idxs.tail ::: List(str.length - 2))
}
+ }
/**
* Merge sections following an usecase into the usecase comment, so they
* can override the parent symbol's sections
*/
def mergeUsecaseSections(str: String, idxs: List[Int]): List[Int] = {
- idxs.find(str.substring(_).startsWith("@usecase")) match {
- case Some(firstUC) =>
- val commentSections = idxs.take(idxs.indexOf(firstUC))
- val usecaseSections = idxs.drop(idxs.indexOf(firstUC)).filter(str.substring(_).startsWith("@usecase"))
+ idxs.indexWhere(str.substring(_).startsWith("@usecase")) match {
+ case firstUCIndex if firstUCIndex != -1 =>
+ val commentSections = idxs.take(firstUCIndex)
+ val usecaseSections = idxs.drop(firstUCIndex).filter(str.substring(_).startsWith("@usecase"))
commentSections ::: usecaseSections
- case None =>
+ case _ =>
idxs
}
}
+ /**
+ * Merge the inheritdoc sections, as they never make sense on their own
+ */
+ def mergeInheritdocSections(str: String, idxs: List[Int]): List[Int] =
+ idxs.filterNot(str.substring(_).startsWith("@inheritdoc"))
+
/** Does interval `iv` start with given `tag`?
*/
def startsWithTag(str: String, section: (Int, Int), tag: String): Boolean =
@@ -108,12 +124,11 @@ object DocStrings {
def startsWithTag(str: String, start: Int, tag: String): Boolean =
str.startsWith(tag, start) && !isIdentifierPart(str charAt (start + tag.length))
-
/** The first start tag of a list of tag intervals,
* or the end of the whole comment string - 2 if list is empty
*/
def startTag(str: String, sections: List[(Int, Int)]) = sections match {
- case List() => str.length - 2
+ case Nil => str.length - 2
case (start, _) :: _ => start
}
@@ -155,4 +170,46 @@ object DocStrings {
idx
}
}
+
+ /** A map from the section tag to section parameters */
+ def sectionTagMap(str: String, sections: List[(Int, Int)]): Map[String, (Int, Int)] =
+ Map() ++ {
+ for (section <- sections) yield
+ extractSectionTag(str, section) -> section
+ }
+
+ /** Extract the section tag, treating the section tag as an indentifier */
+ def extractSectionTag(str: String, section: (Int, Int)): String =
+ str.substring(section._1, skipTag(str, section._1))
+
+ /** Extract the section parameter */
+ def extractSectionParam(str: String, section: (Int, Int)): String = {
+ assert(str.substring(section._1).startsWith("@param") ||
+ str.substring(section._1).startsWith("@tparam") ||
+ str.substring(section._1).startsWith("@throws"))
+
+ val start = skipWhitespace(str, skipTag(str, section._1))
+ val finish = skipIdent(str, start)
+
+ str.substring(start, finish)
+ }
+
+ /** Extract the section text, except for the tag and comment newlines */
+ def extractSectionText(str: String, section: (Int, Int)): (Int, Int) = {
+ if (str.substring(section._1).startsWith("@param") ||
+ str.substring(section._1).startsWith("@tparam") ||
+ str.substring(section._1).startsWith("@throws"))
+ (skipWhitespace(str, skipIdent(str, skipWhitespace(str, skipTag(str, section._1)))), section._2)
+ else
+ (skipWhitespace(str, skipTag(str, section._1)), section._2)
+ }
+
+ /** Cleanup section text */
+ def cleanupSectionText(str: String) = {
+ var result = str.trim.replaceAll("\n\\s+\\*\\s+", " \n")
+ while (result.endsWith("\n"))
+ result = result.substring(0, str.length - 1)
+ result
+ }
+
}
diff --git a/src/library/scala/collection/mutable/Ctrie.scala b/src/library/scala/collection/mutable/ConcurrentTrieMap.scala
index cbec118aa9..1a44c8e423 100644
--- a/src/library/scala/collection/mutable/Ctrie.scala
+++ b/src/library/scala/collection/mutable/ConcurrentTrieMap.scala
@@ -13,7 +13,7 @@ package mutable
import java.util.concurrent.atomic._
import collection.immutable.{ ListMap => ImmutableListMap }
-import collection.parallel.mutable.ParCtrie
+import collection.parallel.mutable.ParConcurrentTrieMap
import generic._
import annotation.tailrec
import annotation.switch
@@ -31,16 +31,16 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
@inline final def CAS(old: MainNode[K, V], n: MainNode[K, V]) = INodeBase.updater.compareAndSet(this, old, n)
- final def gcasRead(ct: Ctrie[K, V]): MainNode[K, V] = GCAS_READ(ct)
+ final def gcasRead(ct: ConcurrentTrieMap[K, V]): MainNode[K, V] = GCAS_READ(ct)
- @inline final def GCAS_READ(ct: Ctrie[K, V]): MainNode[K, V] = {
+ @inline final def GCAS_READ(ct: ConcurrentTrieMap[K, V]): MainNode[K, V] = {
val m = /*READ*/mainnode
val prevval = /*READ*/m.prev
if (prevval eq null) m
else GCAS_Complete(m, ct)
}
- @tailrec private def GCAS_Complete(m: MainNode[K, V], ct: Ctrie[K, V]): MainNode[K, V] = if (m eq null) null else {
+ @tailrec private def GCAS_Complete(m: MainNode[K, V], ct: ConcurrentTrieMap[K, V]): MainNode[K, V] = if (m eq null) null else {
// complete the GCAS
val prev = /*READ*/m.prev
val ctr = ct.readRoot(true)
@@ -72,7 +72,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
}
}
- @inline final def GCAS(old: MainNode[K, V], n: MainNode[K, V], ct: Ctrie[K, V]): Boolean = {
+ @inline final def GCAS(old: MainNode[K, V], n: MainNode[K, V], ct: ConcurrentTrieMap[K, V]): Boolean = {
n.WRITE_PREV(old)
if (CAS(old, n)) {
GCAS_Complete(n, ct)
@@ -86,7 +86,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
nin
}
- final def copyToGen(ngen: Gen, ct: Ctrie[K, V]) = {
+ final def copyToGen(ngen: Gen, ct: ConcurrentTrieMap[K, V]) = {
val nin = new INode[K, V](ngen)
val main = GCAS_READ(ct)
nin.WRITE(main)
@@ -97,7 +97,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
*
* @return true if successful, false otherwise
*/
- @tailrec final def rec_insert(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: Ctrie[K, V]): Boolean = {
+ @tailrec final def rec_insert(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): Boolean = {
val m = GCAS_READ(ct) // use -Yinline!
m match {
@@ -143,7 +143,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
* @param cond null - don't care if the key was there; KEY_ABSENT - key wasn't there; KEY_PRESENT - key was there; other value `v` - key must be bound to `v`
* @return null if unsuccessful, Option[V] otherwise (indicating previous value bound to the key)
*/
- @tailrec final def rec_insertif(k: K, v: V, hc: Int, cond: AnyRef, lev: Int, parent: INode[K, V], startgen: Gen, ct: Ctrie[K, V]): Option[V] = {
+ @tailrec final def rec_insertif(k: K, v: V, hc: Int, cond: AnyRef, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): Option[V] = {
val m = GCAS_READ(ct) // use -Yinline!
m match {
@@ -233,7 +233,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
*
* @return null if no value has been found, RESTART if the operation wasn't successful, or any other value otherwise
*/
- @tailrec final def rec_lookup(k: K, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: Ctrie[K, V]): AnyRef = {
+ @tailrec final def rec_lookup(k: K, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): AnyRef = {
val m = GCAS_READ(ct) // use -Yinline!
m match {
@@ -276,7 +276,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
* @param v if null, will remove the key irregardless of the value; otherwise removes only if binding contains that exact key and value
* @return null if not successful, an Option[V] indicating the previous value otherwise
*/
- final def rec_remove(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: Ctrie[K, V]): Option[V] = {
+ final def rec_remove(k: K, v: V, hc: Int, lev: Int, parent: INode[K, V], startgen: Gen, ct: ConcurrentTrieMap[K, V]): Option[V] = {
val m = GCAS_READ(ct) // use -Yinline!
m match {
@@ -352,7 +352,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
}
}
- private def clean(nd: INode[K, V], ct: Ctrie[K, V], lev: Int) {
+ private def clean(nd: INode[K, V], ct: ConcurrentTrieMap[K, V], lev: Int) {
val m = nd.GCAS_READ(ct)
m match {
case cn: CNode[K, V] => nd.GCAS(cn, cn.toCompressed(ct, lev, gen), ct)
@@ -360,9 +360,9 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
}
}
- final def isNullInode(ct: Ctrie[K, V]) = GCAS_READ(ct) eq null
+ final def isNullInode(ct: ConcurrentTrieMap[K, V]) = GCAS_READ(ct) eq null
- final def cachedSize(ct: Ctrie[K, V]): Int = {
+ final def cachedSize(ct: ConcurrentTrieMap[K, V]): Int = {
val m = GCAS_READ(ct)
m.cachedSize(ct)
}
@@ -438,7 +438,7 @@ extends MainNode[K, V] {
if (updmap.size > 1) new LNode(updmap)
else {
val (k, v) = updmap.iterator.next
- new TNode(k, v, Ctrie.computeHash(k)) // create it tombed so that it gets compressed on subsequent accesses
+ new TNode(k, v, ConcurrentTrieMap.computeHash(k)) // create it tombed so that it gets compressed on subsequent accesses
}
}
def get(k: K) = listmap.get(k)
@@ -455,7 +455,7 @@ extends CNodeBase[K, V] {
val currsz = READ_SIZE()
if (currsz != -1) currsz
else {
- val sz = computeSize(ct.asInstanceOf[Ctrie[K, V]])
+ val sz = computeSize(ct.asInstanceOf[ConcurrentTrieMap[K, V]])
while (READ_SIZE() == -1) CAS_SIZE(-1, sz)
READ_SIZE()
}
@@ -466,7 +466,7 @@ extends CNodeBase[K, V] {
// => if there are concurrent size computations, they start
// at different positions, so they are more likely to
// to be independent
- private def computeSize(ct: Ctrie[K, V]): Int = {
+ private def computeSize(ct: ConcurrentTrieMap[K, V]): Int = {
var i = 0
var sz = 0
val offset = math.abs(util.Random.nextInt()) % array.length
@@ -511,7 +511,7 @@ extends CNodeBase[K, V] {
/** Returns a copy of this cnode such that all the i-nodes below it are copied
* to the specified generation `ngen`.
*/
- final def renewed(ngen: Gen, ct: Ctrie[K, V]) = {
+ final def renewed(ngen: Gen, ct: ConcurrentTrieMap[K, V]) = {
var i = 0
val arr = array
val len = arr.length
@@ -542,7 +542,7 @@ extends CNodeBase[K, V] {
// returns the version of this node with at least some null-inodes
// removed (those existing when the op began)
// - if there are only null-i-nodes below, returns null
- final def toCompressed(ct: Ctrie[K, V], lev: Int, gen: Gen) = {
+ final def toCompressed(ct: ConcurrentTrieMap[K, V], lev: Int, gen: Gen) = {
var bmp = bitmap
var i = 0
val arr = array
@@ -594,7 +594,7 @@ private[mutable] object CNode {
val yidx = (yhc >>> lev) & 0x1f
val bmp = (1 << xidx) | (1 << yidx)
if (xidx == yidx) {
- val subinode = new INode[K, V](gen)//(Ctrie.inodeupdater)
+ val subinode = new INode[K, V](gen)//(ConcurrentTrieMap.inodeupdater)
subinode.mainnode = dual(x, xhc, y, yhc, lev + 5, gen)
new CNode(bmp, Array(subinode), gen)
} else {
@@ -613,7 +613,7 @@ private[mutable] case class RDCSS_Descriptor[K, V](old: INode[K, V], expectedmai
}
-/** A concurrent hash-trie or Ctrie is a concurrent thread-safe lock-free
+/** A concurrent hash-trie or ConcurrentTrieMap is a concurrent thread-safe lock-free
* implementation of a hash array mapped trie. It is used to implement the
* concurrent map abstraction. It has particularly scalable concurrent insert
* and remove operations and is memory-efficient. It supports O(1), atomic,
@@ -627,20 +627,20 @@ private[mutable] case class RDCSS_Descriptor[K, V](old: INode[K, V], expectedmai
* @since 2.10
*/
@SerialVersionUID(0L - 6402774413839597105L)
-final class Ctrie[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater[Ctrie[K, V], AnyRef])
+final class ConcurrentTrieMap[K, V] private (r: AnyRef, rtupd: AtomicReferenceFieldUpdater[ConcurrentTrieMap[K, V], AnyRef])
extends ConcurrentMap[K, V]
- with MapLike[K, V, Ctrie[K, V]]
- with CustomParallelizable[(K, V), ParCtrie[K, V]]
+ with MapLike[K, V, ConcurrentTrieMap[K, V]]
+ with CustomParallelizable[(K, V), ParConcurrentTrieMap[K, V]]
with Serializable
{
- import Ctrie.computeHash
+ import ConcurrentTrieMap.computeHash
private var rootupdater = rtupd
@volatile var root = r
def this() = this(
INode.newRootNode,
- AtomicReferenceFieldUpdater.newUpdater(classOf[Ctrie[K, V]], classOf[AnyRef], "root")
+ AtomicReferenceFieldUpdater.newUpdater(classOf[ConcurrentTrieMap[K, V]], classOf[AnyRef], "root")
)
/* internal methods */
@@ -652,22 +652,22 @@ extends ConcurrentMap[K, V]
out.writeObject(k)
out.writeObject(v)
}
- out.writeObject(CtrieSerializationEnd)
+ out.writeObject(ConcurrentTrieMapSerializationEnd)
}
private def readObject(in: java.io.ObjectInputStream) {
root = INode.newRootNode
- rootupdater = AtomicReferenceFieldUpdater.newUpdater(classOf[Ctrie[K, V]], classOf[AnyRef], "root")
+ rootupdater = AtomicReferenceFieldUpdater.newUpdater(classOf[ConcurrentTrieMap[K, V]], classOf[AnyRef], "root")
var obj: AnyRef = null
do {
obj = in.readObject()
- if (obj != CtrieSerializationEnd) {
+ if (obj != ConcurrentTrieMapSerializationEnd) {
val k = obj.asInstanceOf[K]
val v = in.readObject().asInstanceOf[V]
update(k, v)
}
- } while (obj != CtrieSerializationEnd)
+ } while (obj != ConcurrentTrieMapSerializationEnd)
}
@inline final def CAS_ROOT(ov: AnyRef, nv: AnyRef) = rootupdater.compareAndSet(this, ov, nv)
@@ -760,37 +760,37 @@ extends ConcurrentMap[K, V]
override def seq = this
- override def par = new ParCtrie(this)
+ override def par = new ParConcurrentTrieMap(this)
- override def empty: Ctrie[K, V] = new Ctrie[K, V]
+ override def empty: ConcurrentTrieMap[K, V] = new ConcurrentTrieMap[K, V]
final def isReadOnly = rootupdater eq null
final def nonReadOnly = rootupdater ne null
- /** Returns a snapshot of this Ctrie.
+ /** Returns a snapshot of this ConcurrentTrieMap.
* This operation is lock-free and linearizable.
*
* The snapshot is lazily updated - the first time some branch
- * in the snapshot or this Ctrie are accessed, they are rewritten.
+ * in the snapshot or this ConcurrentTrieMap are accessed, they are rewritten.
* This means that the work of rebuilding both the snapshot and this
- * Ctrie is distributed across all the threads doing updates or accesses
+ * ConcurrentTrieMap is distributed across all the threads doing updates or accesses
* subsequent to the snapshot creation.
*/
- @tailrec final def snapshot(): Ctrie[K, V] = {
+ @tailrec final def snapshot(): ConcurrentTrieMap[K, V] = {
val r = RDCSS_READ_ROOT()
val expmain = r.gcasRead(this)
- if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new Ctrie(r.copyToGen(new Gen, this), rootupdater)
+ if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new ConcurrentTrieMap(r.copyToGen(new Gen, this), rootupdater)
else snapshot()
}
- /** Returns a read-only snapshot of this Ctrie.
+ /** Returns a read-only snapshot of this ConcurrentTrieMap.
* This operation is lock-free and linearizable.
*
* The snapshot is lazily updated - the first time some branch
- * of this Ctrie are accessed, it is rewritten. The work of creating
+ * of this ConcurrentTrieMap are accessed, it is rewritten. The work of creating
* the snapshot is thus distributed across subsequent updates
- * and accesses on this Ctrie by all threads.
+ * and accesses on this ConcurrentTrieMap by all threads.
* Note that the snapshot itself is never rewritten unlike when calling
* the `snapshot` method, but the obtained snapshot cannot be modified.
*
@@ -799,7 +799,7 @@ extends ConcurrentMap[K, V]
@tailrec final def readOnlySnapshot(): collection.Map[K, V] = {
val r = RDCSS_READ_ROOT()
val expmain = r.gcasRead(this)
- if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new Ctrie(r, null)
+ if (RDCSS_ROOT(r, expmain, r.copyToGen(new Gen, this))) new ConcurrentTrieMap(r, null)
else readOnlySnapshot()
}
@@ -872,7 +872,7 @@ extends ConcurrentMap[K, V]
def iterator: Iterator[(K, V)] =
if (nonReadOnly) readOnlySnapshot().iterator
- else new CtrieIterator(0, this)
+ else new ConcurrentTrieMapIterator(0, this)
private def cachedSize() = {
val r = RDCSS_READ_ROOT()
@@ -883,17 +883,17 @@ extends ConcurrentMap[K, V]
if (nonReadOnly) readOnlySnapshot().size
else cachedSize()
- override def stringPrefix = "Ctrie"
+ override def stringPrefix = "ConcurrentTrieMap"
}
-object Ctrie extends MutableMapFactory[Ctrie] {
+object ConcurrentTrieMap extends MutableMapFactory[ConcurrentTrieMap] {
val inodeupdater = AtomicReferenceFieldUpdater.newUpdater(classOf[INodeBase[_, _]], classOf[MainNode[_, _]], "mainnode")
- implicit def canBuildFrom[K, V]: CanBuildFrom[Coll, (K, V), Ctrie[K, V]] = new MapCanBuildFrom[K, V]
+ implicit def canBuildFrom[K, V]: CanBuildFrom[Coll, (K, V), ConcurrentTrieMap[K, V]] = new MapCanBuildFrom[K, V]
- def empty[K, V]: Ctrie[K, V] = new Ctrie[K, V]
+ def empty[K, V]: ConcurrentTrieMap[K, V] = new ConcurrentTrieMap[K, V]
@inline final def computeHash[K](k: K): Int = {
var hcode = k.hashCode
@@ -905,7 +905,7 @@ object Ctrie extends MutableMapFactory[Ctrie] {
}
-private[collection] class CtrieIterator[K, V](var level: Int, private var ct: Ctrie[K, V], mustInit: Boolean = true) extends Iterator[(K, V)] {
+private[collection] class ConcurrentTrieMapIterator[K, V](var level: Int, private var ct: ConcurrentTrieMap[K, V], mustInit: Boolean = true) extends Iterator[(K, V)] {
var stack = new Array[Array[BasicNode]](7)
var stackpos = new Array[Int](7)
var depth = -1
@@ -971,9 +971,9 @@ private[collection] class CtrieIterator[K, V](var level: Int, private var ct: Ct
}
} else current = null
- protected def newIterator(_lev: Int, _ct: Ctrie[K, V], _mustInit: Boolean) = new CtrieIterator[K, V](_lev, _ct, _mustInit)
+ protected def newIterator(_lev: Int, _ct: ConcurrentTrieMap[K, V], _mustInit: Boolean) = new ConcurrentTrieMapIterator[K, V](_lev, _ct, _mustInit)
- protected def dupTo(it: CtrieIterator[K, V]) = {
+ protected def dupTo(it: ConcurrentTrieMapIterator[K, V]) = {
it.level = this.level
it.ct = this.ct
it.depth = this.depth
@@ -993,7 +993,7 @@ private[collection] class CtrieIterator[K, V](var level: Int, private var ct: Ct
}
/** Returns a sequence of iterators over subsets of this iterator.
- * It's used to ease the implementation of splitters for a parallel version of the Ctrie.
+ * It's used to ease the implementation of splitters for a parallel version of the ConcurrentTrieMap.
*/
protected def subdivide(): Seq[Iterator[(K, V)]] = if (subiter ne null) {
// the case where an LNode is being iterated
@@ -1043,7 +1043,7 @@ private[mutable] object RestartException extends util.control.ControlThrowable
/** Only used for ctrie serialization. */
@SerialVersionUID(0L - 7237891413820527142L)
-private[mutable] case object CtrieSerializationEnd
+private[mutable] case object ConcurrentTrieMapSerializationEnd
private[mutable] object Debug {
diff --git a/src/library/scala/collection/parallel/immutable/ParHashMap.scala b/src/library/scala/collection/parallel/immutable/ParHashMap.scala
index 52d6531f9e..49b00bebdb 100644
--- a/src/library/scala/collection/parallel/immutable/ParHashMap.scala
+++ b/src/library/scala/collection/parallel/immutable/ParHashMap.scala
@@ -117,18 +117,6 @@ self =>
override def toString = "HashTrieIterator(" + sz + ")"
}
- /* serialization */
-
- private def writeObject(out: java.io.ObjectOutputStream) {
- out.defaultWriteObject
- }
-
- private def readObject(in: java.io.ObjectInputStream) {
- in.defaultReadObject
-
- initTaskSupport()
- }
-
/* debug */
private[parallel] def printDebugInfo() {
diff --git a/src/library/scala/collection/parallel/immutable/ParHashSet.scala b/src/library/scala/collection/parallel/immutable/ParHashSet.scala
index 0a19afc426..11d92a27c9 100644
--- a/src/library/scala/collection/parallel/immutable/ParHashSet.scala
+++ b/src/library/scala/collection/parallel/immutable/ParHashSet.scala
@@ -112,18 +112,6 @@ self =>
def remaining = sz - i
}
- /* serialization */
-
- private def writeObject(out: java.io.ObjectOutputStream) {
- out.defaultWriteObject
- }
-
- private def readObject(in: java.io.ObjectInputStream) {
- in.defaultReadObject
-
- initTaskSupport()
- }
-
}
diff --git a/src/library/scala/collection/parallel/immutable/ParRange.scala b/src/library/scala/collection/parallel/immutable/ParRange.scala
index 364175fe41..9cac433460 100644
--- a/src/library/scala/collection/parallel/immutable/ParRange.scala
+++ b/src/library/scala/collection/parallel/immutable/ParRange.scala
@@ -106,18 +106,6 @@ self =>
}
}
- /* serialization */
-
- private def writeObject(out: java.io.ObjectOutputStream) {
- out.defaultWriteObject
- }
-
- private def readObject(in: java.io.ObjectInputStream) {
- in.defaultReadObject
-
- initTaskSupport()
- }
-
}
object ParRange {
diff --git a/src/library/scala/collection/parallel/immutable/ParVector.scala b/src/library/scala/collection/parallel/immutable/ParVector.scala
index 310b09a016..5d9c431bc1 100644
--- a/src/library/scala/collection/parallel/immutable/ParVector.scala
+++ b/src/library/scala/collection/parallel/immutable/ParVector.scala
@@ -78,18 +78,6 @@ extends ParSeq[T]
splitted.map(v => new ParVector(v).splitter.asInstanceOf[ParVectorIterator])
}
}
-
- /* serialization */
-
- private def writeObject(out: java.io.ObjectOutputStream) {
- out.defaultWriteObject
- }
-
- private def readObject(in: java.io.ObjectInputStream) {
- in.defaultReadObject
-
- initTaskSupport()
- }
}
diff --git a/src/library/scala/collection/parallel/mutable/ParArray.scala b/src/library/scala/collection/parallel/mutable/ParArray.scala
index 683b7eaa9a..c33495bd39 100644
--- a/src/library/scala/collection/parallel/mutable/ParArray.scala
+++ b/src/library/scala/collection/parallel/mutable/ParArray.scala
@@ -675,8 +675,6 @@ self =>
// get raw array from arrayseq
array = arrayseq.array.asInstanceOf[Array[Any]]
-
- initTaskSupport()
}
}
diff --git a/src/library/scala/collection/parallel/mutable/ParCtrie.scala b/src/library/scala/collection/parallel/mutable/ParConcurrentTrieMap.scala
index b4dc8beb2a..a6495161ea 100644
--- a/src/library/scala/collection/parallel/mutable/ParCtrie.scala
+++ b/src/library/scala/collection/parallel/mutable/ParConcurrentTrieMap.scala
@@ -20,12 +20,12 @@ import scala.collection.mutable.LNode
import scala.collection.mutable.CNode
import scala.collection.mutable.SNode
import scala.collection.mutable.INode
-import scala.collection.mutable.Ctrie
-import scala.collection.mutable.CtrieIterator
+import scala.collection.mutable.ConcurrentTrieMap
+import scala.collection.mutable.ConcurrentTrieMapIterator
-/** Parallel Ctrie collection.
+/** Parallel ConcurrentTrieMap collection.
*
* It has its bulk operations parallelized, but uses the snapshot operation
* to create the splitter. This means that parallel bulk operations can be
@@ -34,24 +34,24 @@ import scala.collection.mutable.CtrieIterator
* @author Aleksandar Prokopec
* @since 2.10
*/
-final class ParCtrie[K, V] private[collection] (private val ctrie: Ctrie[K, V])
+final class ParConcurrentTrieMap[K, V] private[collection] (private val ctrie: ConcurrentTrieMap[K, V])
extends ParMap[K, V]
- with GenericParMapTemplate[K, V, ParCtrie]
- with ParMapLike[K, V, ParCtrie[K, V], Ctrie[K, V]]
- with ParCtrieCombiner[K, V]
+ with GenericParMapTemplate[K, V, ParConcurrentTrieMap]
+ with ParMapLike[K, V, ParConcurrentTrieMap[K, V], ConcurrentTrieMap[K, V]]
+ with ParConcurrentTrieMapCombiner[K, V]
with Serializable
{
- def this() = this(new Ctrie)
+ def this() = this(new ConcurrentTrieMap)
- override def mapCompanion: GenericParMapCompanion[ParCtrie] = ParCtrie
+ override def mapCompanion: GenericParMapCompanion[ParConcurrentTrieMap] = ParConcurrentTrieMap
- override def empty: ParCtrie[K, V] = ParCtrie.empty
+ override def empty: ParConcurrentTrieMap[K, V] = ParConcurrentTrieMap.empty
- protected[this] override def newCombiner = ParCtrie.newCombiner
+ protected[this] override def newCombiner = ParConcurrentTrieMap.newCombiner
override def seq = ctrie
- def splitter = new ParCtrieSplitter(0, ctrie.readOnlySnapshot().asInstanceOf[Ctrie[K, V]], true)
+ def splitter = new ParConcurrentTrieMapSplitter(0, ctrie.readOnlySnapshot().asInstanceOf[ConcurrentTrieMap[K, V]], true)
override def clear() = ctrie.clear()
@@ -87,11 +87,11 @@ extends ParMap[K, V]
}
}
- override def stringPrefix = "ParCtrie"
+ override def stringPrefix = "ParConcurrentTrieMap"
/* tasks */
- /** Computes Ctrie size in parallel. */
+ /** Computes ConcurrentTrieMap size in parallel. */
class Size(offset: Int, howmany: Int, array: Array[BasicNode]) extends Task[Int, Size] {
var result = -1
def leaf(prev: Option[Int]) = {
@@ -115,30 +115,18 @@ extends ParMap[K, V]
override def merge(that: Size) = result = result + that.result
}
- /* serialization */
-
- private def writeObject(out: java.io.ObjectOutputStream) {
- out.defaultWriteObject
- }
-
- private def readObject(in: java.io.ObjectInputStream) {
- in.defaultReadObject
-
- initTaskSupport()
- }
-
}
-private[collection] class ParCtrieSplitter[K, V](lev: Int, ct: Ctrie[K, V], mustInit: Boolean)
-extends CtrieIterator[K, V](lev, ct, mustInit)
+private[collection] class ParConcurrentTrieMapSplitter[K, V](lev: Int, ct: ConcurrentTrieMap[K, V], mustInit: Boolean)
+extends ConcurrentTrieMapIterator[K, V](lev, ct, mustInit)
with IterableSplitter[(K, V)]
{
// only evaluated if `remaining` is invoked (which is not used by most tasks)
lazy val totalsize = ct.par.size
var iterated = 0
- protected override def newIterator(_lev: Int, _ct: Ctrie[K, V], _mustInit: Boolean) = new ParCtrieSplitter[K, V](_lev, _ct, _mustInit)
+ protected override def newIterator(_lev: Int, _ct: ConcurrentTrieMap[K, V], _mustInit: Boolean) = new ParConcurrentTrieMapSplitter[K, V](_lev, _ct, _mustInit)
override def shouldSplitFurther[S](coll: collection.parallel.ParIterable[S], parallelismLevel: Int) = {
val maxsplits = 3 + Integer.highestOneBit(parallelismLevel)
@@ -165,15 +153,15 @@ extends CtrieIterator[K, V](lev, ct, mustInit)
}
-/** Only used within the `ParCtrie`. */
-private[mutable] trait ParCtrieCombiner[K, V] extends Combiner[(K, V), ParCtrie[K, V]] {
+/** Only used within the `ParConcurrentTrieMap`. */
+private[mutable] trait ParConcurrentTrieMapCombiner[K, V] extends Combiner[(K, V), ParConcurrentTrieMap[K, V]] {
- def combine[N <: (K, V), NewTo >: ParCtrie[K, V]](other: Combiner[N, NewTo]): Combiner[N, NewTo] = if (this eq other) this else {
+ def combine[N <: (K, V), NewTo >: ParConcurrentTrieMap[K, V]](other: Combiner[N, NewTo]): Combiner[N, NewTo] = if (this eq other) this else {
throw new UnsupportedOperationException("This shouldn't have been called in the first place.")
- val thiz = this.asInstanceOf[ParCtrie[K, V]]
- val that = other.asInstanceOf[ParCtrie[K, V]]
- val result = new ParCtrie[K, V]
+ val thiz = this.asInstanceOf[ParConcurrentTrieMap[K, V]]
+ val that = other.asInstanceOf[ParConcurrentTrieMap[K, V]]
+ val result = new ParConcurrentTrieMap[K, V]
result ++= thiz.iterator
result ++= that.iterator
@@ -186,13 +174,13 @@ private[mutable] trait ParCtrieCombiner[K, V] extends Combiner[(K, V), ParCtrie[
}
-object ParCtrie extends ParMapFactory[ParCtrie] {
+object ParConcurrentTrieMap extends ParMapFactory[ParConcurrentTrieMap] {
- def empty[K, V]: ParCtrie[K, V] = new ParCtrie[K, V]
+ def empty[K, V]: ParConcurrentTrieMap[K, V] = new ParConcurrentTrieMap[K, V]
- def newCombiner[K, V]: Combiner[(K, V), ParCtrie[K, V]] = new ParCtrie[K, V]
+ def newCombiner[K, V]: Combiner[(K, V), ParConcurrentTrieMap[K, V]] = new ParConcurrentTrieMap[K, V]
- implicit def canBuildFrom[K, V]: CanCombineFrom[Coll, (K, V), ParCtrie[K, V]] = new CanCombineFromMap[K, V]
+ implicit def canBuildFrom[K, V]: CanCombineFrom[Coll, (K, V), ParConcurrentTrieMap[K, V]] = new CanCombineFromMap[K, V]
}
diff --git a/src/library/scala/collection/parallel/mutable/ParHashMap.scala b/src/library/scala/collection/parallel/mutable/ParHashMap.scala
index 72526aadb1..6ce6c45460 100644
--- a/src/library/scala/collection/parallel/mutable/ParHashMap.scala
+++ b/src/library/scala/collection/parallel/mutable/ParHashMap.scala
@@ -106,8 +106,6 @@ self =>
private def readObject(in: java.io.ObjectInputStream) {
init[V](in, new Entry(_, _))
-
- initTaskSupport()
}
private[parallel] override def brokenInvariants = {
diff --git a/src/library/scala/collection/parallel/mutable/ParHashSet.scala b/src/library/scala/collection/parallel/mutable/ParHashSet.scala
index 84b7c4e42c..e0a2ab03df 100644
--- a/src/library/scala/collection/parallel/mutable/ParHashSet.scala
+++ b/src/library/scala/collection/parallel/mutable/ParHashSet.scala
@@ -84,8 +84,6 @@ extends ParSet[T]
private def readObject(in: java.io.ObjectInputStream) {
init(in, x => x)
-
- initTaskSupport()
}
import collection.DebugUtils._
diff --git a/src/library/scala/reflect/api/Trees.scala b/src/library/scala/reflect/api/Trees.scala
index 181ce85dac..a355207ff0 100644
--- a/src/library/scala/reflect/api/Trees.scala
+++ b/src/library/scala/reflect/api/Trees.scala
@@ -309,7 +309,7 @@ trait Trees { self: Universe =>
* quite frequently called modules to reduce ambiguity.
*/
case class ModuleDef(mods: Modifiers, name: TermName, impl: Template)
- extends ImplDef
+ extends ImplDef
/** A common base class for ValDefs and DefDefs.
*/
@@ -319,8 +319,13 @@ trait Trees { self: Universe =>
def rhs: Tree
}
- /** A value definition (this includes vars as well, which differ from
- * vals only in having the MUTABLE flag set in their Modifiers.)
+ /** Broadly speaking, a value definition. All these are encoded as ValDefs:
+ *
+ * - immutable values, e.g. "val x"
+ * - mutable values, e.g. "var x" - the MUTABLE flag set in mods
+ * - lazy values, e.g. "lazy val x" - the LAZY flag set in mods
+ * - method parameters, see vparamss in DefDef - the PARAM flag is set in mods
+ * - explicit self-types, e.g. class A { self: Bar => } - !!! not sure what is set.
*/
case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef
@@ -390,7 +395,6 @@ trait Trees { self: Universe =>
// {
// def bar // owner is local dummy
// }
- // System.err.println("TEMPLATE: " + parents)
}
/** Block of expressions (semicolon separated expressions) */
@@ -741,6 +745,12 @@ trait Trees { self: Universe =>
case t =>
sys.error("Not a ClassDef: " + t + "/" + t.getClass)
}
+ def deriveModuleDef(mdef: Tree)(applyToImpl: Template => Template): ModuleDef = mdef match {
+ case ModuleDef(mods0, name0, impl0) =>
+ treeCopy.ModuleDef(mdef, mods0, name0, applyToImpl(impl0))
+ case t =>
+ sys.error("Not a ModuleDef: " + t + "/" + t.getClass)
+ }
def deriveCaseDef(cdef: Tree)(applyToBody: Tree => Tree): CaseDef = cdef match {
case CaseDef(pat0, guard0, body0) =>
treeCopy.CaseDef(cdef, pat0, guard0, applyToBody(body0))
diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala
index 0c7772cd07..38ca89b98b 100644
--- a/src/library/scala/util/Properties.scala
+++ b/src/library/scala/util/Properties.scala
@@ -72,10 +72,11 @@ private[scala] trait PropertiesTrait {
* it is an RC, Beta, etc. or was built from source, or if the version
* cannot be read.
*/
- val releaseVersion = scalaPropOrNone("version.number") flatMap { s =>
- val segments = s split '.'
- if (segments.size == 4 && segments.last == "final") Some(segments take 3 mkString ".") else None
- }
+ val releaseVersion =
+ for {
+ v <- scalaPropOrNone("maven.version.number")
+ if !(v endsWith "-SNAPSHOT")
+ } yield v
/** The development Scala version, if this is not a final release.
* The precise contents are not guaranteed, but it aims to provide a
@@ -85,15 +86,12 @@ private[scala] trait PropertiesTrait {
* @return Some(version) if this is a non-final version, None if this
* is a final release or the version cannot be read.
*/
- val developmentVersion = scalaPropOrNone("version.number") flatMap { s =>
- val segments = s split '.'
- if (segments.isEmpty || segments.last == "final")
- None
- else if (segments.last startsWith "r")
- Some(s takeWhile (ch => ch != '-')) // Cutting e.g. 2.10.0.r24774-b20110417125606 to 2.10.0.r24774
- else
- Some(s)
- }
+ val developmentVersion =
+ for {
+ v <- scalaPropOrNone("maven.version.number")
+ if v endsWith "-SNAPSHOT"
+ ov <- scalaPropOrNone("version.number")
+ } yield ov
/** Either the development or release version if known, otherwise
* the empty string.