summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/CompileServer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala9
-rw-r--r--src/compiler/scala/tools/nsc/PhaseAssembly.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala64
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala45
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala8
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala10
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala3
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/analysis/package.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/BoxUnbox.scala6
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala6
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala2
-rw-r--r--src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala2
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala69
-rw-r--r--src/compiler/scala/tools/nsc/settings/Warnings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Delambdafy.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Fields.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/SampleTransform.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/Logic.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Duplicators.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala56
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala3
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala23
-rw-r--r--src/compiler/scala/tools/nsc/util/package.scala2
-rw-r--r--src/library/rootdoc.txt3
-rw-r--r--src/library/scala/annotation/showAsInfix.scala27
-rw-r--r--src/library/scala/collection/GenTraversableLike.scala24
-rw-r--r--src/library/scala/collection/IterableLike.scala12
-rw-r--r--src/library/scala/collection/Iterator.scala59
-rw-r--r--src/library/scala/collection/concurrent/TrieMap.scala27
-rw-r--r--src/library/scala/collection/convert/DecorateAsJava.scala34
-rw-r--r--src/library/scala/collection/convert/DecorateAsScala.scala24
-rw-r--r--src/library/scala/collection/convert/ImplicitConversions.scala92
-rw-r--r--src/library/scala/collection/immutable/HashMap.scala50
-rw-r--r--src/library/scala/collection/immutable/Queue.scala9
-rw-r--r--src/library/scala/collection/immutable/Stream.scala4
-rw-r--r--src/library/scala/collection/mutable/ArrayOps.scala40
-rw-r--r--src/library/scala/deprecated.scala18
-rw-r--r--src/reflect/scala/reflect/internal/AnnotationInfos.scala5
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala6
-rw-r--r--src/reflect/scala/reflect/internal/Positions.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala2
-rw-r--r--src/reflect/scala/reflect/internal/ReificationSupport.scala15
-rw-r--r--src/reflect/scala/reflect/internal/Scopes.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala36
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala2
-rw-r--r--src/reflect/scala/reflect/internal/tpe/GlbLubs.scala2
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeComparers.scala2
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala2
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeMaps.scala6
-rw-r--r--src/reflect/scala/reflect/internal/transform/Erasure.scala2
-rw-r--r--src/reflect/scala/reflect/internal/util/Statistics.scala2
-rw-r--r--src/reflect/scala/reflect/internal/util/StringOps.scala21
-rw-r--r--src/reflect/scala/reflect/io/Path.scala13
-rw-r--r--src/reflect/scala/reflect/macros/blackbox/Context.scala2
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala1
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ILoop.scala119
-rw-r--r--src/repl/scala/tools/nsc/interpreter/IMain.scala2
-rw-r--r--src/repl/scala/tools/nsc/interpreter/LoopCommands.scala84
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala5
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala2
78 files changed, 719 insertions, 416 deletions
diff --git a/src/compiler/scala/tools/nsc/CompileServer.scala b/src/compiler/scala/tools/nsc/CompileServer.scala
index 9cac497a85..ffe95ba9dc 100644
--- a/src/compiler/scala/tools/nsc/CompileServer.scala
+++ b/src/compiler/scala/tools/nsc/CompileServer.scala
@@ -47,7 +47,7 @@ class StandardCompileServer(fixPort: Int = 0) extends SocketServer(fixPort) {
}
def printMemoryStats() {
- def mb(bytes: Long) = "%dMB".format(bytes / 1000000)
+ def mb(bytes: Long) = "%10.2fMB".format(bytes / 1048576.0)
info("New session: total memory = %s, max memory = %s, free memory = %s".format(
mb(totalMemory), mb(maxMemory), mb(freeMemory)))
}
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 873a5947ed..c1b0733895 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -989,7 +989,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
)
private def formatExplain(pairs: (String, Any)*): String = (
- pairs.toList collect { case (k, v) if v != null => "%20s: %s".format(k, v) } mkString "\n"
+ pairs collect { case (k, v) if v != null => f"$k%20s: $v" } mkString "\n"
)
/** Don't want to introduce new errors trying to report errors,
@@ -1002,9 +1002,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
val site = lastSeenContext.enclClassOrMethod.owner
val pos_s = if (tree.pos.isDefined) s"line ${tree.pos.line} of ${tree.pos.source.file}" else "<unknown>"
val context_s = try {
+ import scala.reflect.io.{File => SFile}
// Taking 3 before, 3 after the fingered line.
- val start = 0 max (tree.pos.line - 3)
- val xs = scala.reflect.io.File(tree.pos.source.file.file).lines drop start take 7
+ val start = 1 max (tree.pos.line - 3)
+ val xs = SFile(tree.pos.source.file.file).lines.drop(start-1).take(7)
val strs = xs.zipWithIndex map { case (line, idx) => f"${start + idx}%6d $line" }
strs.mkString("== Source file context for tree position ==\n\n", "\n", "")
}
@@ -1197,7 +1198,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
first
}
- // --------------- Miscellania -------------------------------
+ // --------------- Miscellanea -------------------------------
/** Progress tracking. Measured in "progress units" which are 1 per
* compilation unit per phase completed.
diff --git a/src/compiler/scala/tools/nsc/PhaseAssembly.scala b/src/compiler/scala/tools/nsc/PhaseAssembly.scala
index ef9818c62d..df72c37e53 100644
--- a/src/compiler/scala/tools/nsc/PhaseAssembly.scala
+++ b/src/compiler/scala/tools/nsc/PhaseAssembly.scala
@@ -17,7 +17,7 @@ trait PhaseAssembly {
self: Global =>
/**
- * Aux datastructure for solving the constraint system
+ * Aux data structure for solving the constraint system
* The dependency graph container with helper methods for node and edge creation
*/
private class DependencyGraph {
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index cf66e0a7dc..0cdba861a5 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1263,8 +1263,8 @@ self =>
case CHARLIT => in.charVal
case INTLIT => in.intVal(isNegated).toInt
case LONGLIT => in.intVal(isNegated)
- case FLOATLIT => in.floatVal(isNegated).toFloat
- case DOUBLELIT => in.floatVal(isNegated)
+ case FLOATLIT => in.floatVal(isNegated)
+ case DOUBLELIT => in.doubleVal(isNegated)
case STRINGLIT | STRINGPART => in.strVal.intern()
case TRUE => true
case FALSE => false
@@ -2236,31 +2236,57 @@ self =>
* }}}
*/
def paramClauses(owner: Name, contextBounds: List[Tree], ofCaseClass: Boolean): List[List[ValDef]] = {
- var implicitmod = 0
- var caseParam = ofCaseClass
- def paramClause(): List[ValDef] = {
- if (in.token == RPAREN)
- return Nil
-
- if (in.token == IMPLICIT) {
- in.nextToken()
- implicitmod = Flags.IMPLICIT
- }
- commaSeparated(param(owner, implicitmod, caseParam ))
- }
- val vds = new ListBuffer[List[ValDef]]
+ var implicitSection = -1
+ var implicitOffset = -1
+ var warnAt = -1
+ var caseParam = ofCaseClass
+ val vds = new ListBuffer[List[ValDef]]
val start = in.offset
+ def paramClause(): List[ValDef] = if (in.token == RPAREN) Nil else {
+ val implicitmod =
+ if (in.token == IMPLICIT) {
+ if (implicitOffset == -1) { implicitOffset = in.offset ; implicitSection = vds.length }
+ else if (warnAt == -1) warnAt = in.offset
+ in.nextToken()
+ Flags.IMPLICIT
+ } else 0
+ commaSeparated(param(owner, implicitmod, caseParam))
+ }
newLineOptWhenFollowedBy(LPAREN)
- if (ofCaseClass && in.token != LPAREN)
- syntaxError(in.lastOffset, "case classes without a parameter list are not allowed;\n"+
- "use either case objects or case classes with an explicit `()' as a parameter list.")
- while (implicitmod == 0 && in.token == LPAREN) {
+ while (in.token == LPAREN) {
in.nextToken()
vds += paramClause()
accept(RPAREN)
caseParam = false
newLineOptWhenFollowedBy(LPAREN)
}
+ if (ofCaseClass) {
+ if (vds.isEmpty)
+ syntaxError(start, s"case classes must have a parameter list; try 'case class ${owner.encoded
+ }()' or 'case object ${owner.encoded}'")
+ else if (vds.head.nonEmpty && vds.head.head.mods.isImplicit) {
+ if (settings.isScala213)
+ syntaxError(start, s"case classes must have a non-implicit parameter list; try 'case class ${
+ owner.encoded}()${ vds.map(vs => "(...)").mkString }'")
+ else {
+ deprecationWarning(start, s"case classes should have a non-implicit parameter list; adapting to 'case class ${
+ owner.encoded}()${ vds.map(vs => "(...)").mkString }'", "2.12.2")
+ vds.insert(0, List.empty[ValDef])
+ vds(1) = vds(1).map(vd => copyValDef(vd)(mods = vd.mods & ~Flags.CASEACCESSOR))
+ if (implicitSection != -1) implicitSection += 1
+ }
+ }
+ }
+ if (implicitSection != -1 && implicitSection != vds.length - 1)
+ syntaxError(implicitOffset, "an implicit parameter section must be last")
+ if (warnAt != -1)
+ syntaxError(warnAt, "multiple implicit parameter sections are not allowed")
+ else if (settings.warnExtraImplicit) {
+ // guard against anomalous class C(private implicit val x: Int)(implicit s: String)
+ val ttl = vds.count { case ValDef(mods, _, _, _) :: _ => mods.isImplicit ; case _ => false }
+ if (ttl > 1)
+ warning(in.offset, s"$ttl parameter sections are effectively implicit")
+ }
val result = vds.toList
if (owner == nme.CONSTRUCTOR && (result.isEmpty || (result.head take 1 exists (_.mods.isImplicit)))) {
in.token match {
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index a8cc7f91c2..226c49ec07 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -386,6 +386,17 @@ trait Scanners extends ScannersCommon {
next copyFrom this
this copyFrom prev
}
+ } else if (token == COMMA) {
+ // SIP-27 Trailing Comma (multi-line only) support
+ // If a comma is followed by a new line & then a closing paren, bracket or brace
+ // then it is a trailing comma and is ignored
+ val saved = new ScannerData {} copyFrom this
+ fetchToken()
+ if (afterLineEnd() && (token == RPAREN || token == RBRACKET || token == RBRACE)) {
+ /* skip the trailing comma */
+ } else if (token == EOF) { // e.g. when the REPL is parsing "val List(x, y, _*,"
+ /* skip the trailing comma */
+ } else this copyFrom saved
}
// print("["+this+"]")
@@ -972,23 +983,45 @@ trait Scanners extends ScannersCommon {
def intVal: Long = intVal(negated = false)
- /** Convert current strVal, base to double value
+ /** Convert current strVal, base to float value.
*/
- def floatVal(negated: Boolean): Double = {
- val limit: Double = if (token == DOUBLELIT) Double.MaxValue else Float.MaxValue
+ def floatVal(negated: Boolean): Float = {
try {
- val value: Double = java.lang.Double.valueOf(strVal).doubleValue()
- if (value > limit)
+ val value: Float = java.lang.Float.parseFloat(strVal)
+ if (value > Float.MaxValue)
syntaxError("floating point number too large")
+ val zeroly = "0.fF"
+ if (value == 0.0f && strVal.exists(c => !zeroly.contains(c)))
+ syntaxError("floating point number too small")
if (negated) -value else value
} catch {
case _: NumberFormatException =>
syntaxError("malformed floating point number")
+ 0.0f
+ }
+ }
+
+ def floatVal: Float = floatVal(negated = false)
+
+ /** Convert current strVal, base to double value.
+ */
+ def doubleVal(negated: Boolean): Double = {
+ try {
+ val value: Double = java.lang.Double.parseDouble(strVal)
+ if (value > Double.MaxValue)
+ syntaxError("double precision floating point number too large")
+ val zeroly = "0.dD"
+ if (value == 0.0d && strVal.exists(c => !zeroly.contains(c)))
+ syntaxError("double precision floating point number too small")
+ if (negated) -value else value
+ } catch {
+ case _: NumberFormatException =>
+ syntaxError("malformed double precision floating point number")
0.0
}
}
- def floatVal: Double = floatVal(negated = false)
+ def doubleVal: Double = doubleVal(negated = false)
def checkNoLetter(): Unit = {
if (isIdentifierPart(ch) && ch >= ' ')
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala
index 1982c7f643..402dc66a7f 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/AsmUtils.scala
@@ -33,7 +33,7 @@ object AsmUtils {
final val traceClassPattern = ""
/**
- * Print the bytedcode of classes as they are serialized by the ASM library. The serialization
+ * Print the bytecode of classes as they are serialized by the ASM library. The serialization
* performed by `asm.ClassWriter` can change the code generated by GenBCode. For example, it
* introduces stack map frames, it computes the maximal stack sizes, and it replaces dead
* code by NOPs (see also https://github.com/scala/scala/pull/3726#issuecomment-42861780).
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
index c7952ffe94..76d042ce3b 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
@@ -918,7 +918,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
(args zip params) filterNot isTrivial
}
- // first push *all* arguments. This makes sure muliple uses of the same labelDef-var will all denote the (previous) value.
+ // first push *all* arguments. This makes sure multiple uses of the same labelDef-var will all denote the (previous) value.
aps foreach { case (arg, param) => genLoad(arg, locals(param).tk) } // `locals` is known to contain `param` because `genDefDef()` visited `labelDefsAtOrUnder`
// second assign one by one to the LabelDef's variables.
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
index 18e7500172..a74c70a684 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeHelpers.scala
@@ -188,7 +188,7 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
* Data for emitting an EnclosingMethod attribute. None if `classSym` is a member class (not
* an anonymous or local class). See doc in BTypes.
*
- * The class is parametrized by two functions to obtain a bytecode class descriptor for a class
+ * The class is parameterized by two functions to obtain a bytecode class descriptor for a class
* symbol, and to obtain a method signature descriptor fro a method symbol. These function depend
* on the implementation of GenASM / GenBCode, so they need to be passed in.
*/
@@ -332,7 +332,7 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
failNoForwarder("companion contains its own main method (implementation restriction: no main is allowed, regardless of signature)")
else if (companion.isTrait)
failNoForwarder("companion is a trait")
- // Now either succeeed, or issue some additional warnings for things which look like
+ // Now either succeed, or issue some additional warnings for things which look like
// attempts to be java main methods.
else (possibles exists definitions.isJavaMainMethod) || {
possibles exists { m =>
@@ -541,9 +541,9 @@ abstract class BCodeHelpers extends BCodeIdiomatic with BytecodeWriters {
* symbol (sym.annotations) or type (as an AnnotatedType, eliminated by erasure).
*
* For Scala annotations this is OK: they are stored in the pickle and ignored by the backend.
- * Java annoations on the other hand are additionally emitted to the classfile in Java's format.
+ * Java annotations on the other hand are additionally emitted to the classfile in Java's format.
*
- * This means that [[Type]] instances within an AnnotaionInfo reach the backend non-erased. Examples:
+ * This means that [[Type]] instances within an AnnotationInfo reach the backend non-erased. Examples:
* - @(javax.annotation.Resource @annotation.meta.getter) val x = 0
* Here, annotationInfo.atp is an AnnotatedType.
* - @SomeAnnotation[T] val x = 0
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
index 121091fe4f..3e3229d2c3 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BTypes.scala
@@ -83,7 +83,7 @@ abstract class BTypes {
val callsitePositions: concurrent.Map[MethodInsnNode, Position] = recordPerRunCache(TrieMap.empty)
/**
- * Stores callsite instructions of invocatinos annotated `f(): @inline/noinline`.
+ * Stores callsite instructions of invocations annotated `f(): @inline/noinline`.
* Instructions are added during code generation (BCodeBodyBuilder). The maps are then queried
* when building the CallGraph, every Callsite object has an annotated(No)Inline field.
*/
@@ -287,7 +287,7 @@ abstract class BTypes {
}
// The InlineInfo is built from the classfile (not from the symbol) for all classes that are NOT
- // being compiled. For those classes, the info is only needed if the inliner is enabled, othewise
+ // being compiled. For those classes, the info is only needed if the inliner is enabled, otherwise
// we can save the memory.
if (!compilerSettings.optInlinerEnabled) BTypes.EmptyInlineInfo
else fromClassfileAttribute getOrElse fromClassfileWithoutAttribute
@@ -653,7 +653,7 @@ abstract class BTypes {
* Fields in the InnerClass entries:
* - inner class: the (nested) class C we are talking about
* - outer class: the class of which C is a member. Has to be null for non-members, i.e. for
- * local and anonymous classes. NOTE: this co-incides with the presence of an
+ * local and anonymous classes. NOTE: this coincides with the presence of an
* EnclosingMethod attribute (see below)
* - inner name: A string with the simple name of the inner class. Null for anonymous classes.
* - flags: access property flags, details in JVMS, table in 4.7.6. Static flag: see
@@ -702,7 +702,7 @@ abstract class BTypes {
* local and anonymous classes, no matter if there is an enclosing method or not. Accordingly, the
* "class" field (see below) must be always defined, while the "method" field may be null.
*
- * NOTE: When an EnclosingMethod attribute is requried (local and anonymous classes), the "outer"
+ * NOTE: When an EnclosingMethod attribute is required (local and anonymous classes), the "outer"
* field in the InnerClass table must be null.
*
* Fields:
@@ -1144,7 +1144,7 @@ object BTypes {
/**
* Metadata about a ClassBType, used by the inliner.
*
- * More information may be added in the future to enable more elaborate inlinine heuristics.
+ * More information may be added in the future to enable more elaborate inline heuristics.
* Note that this class should contain information that can only be obtained from the ClassSymbol.
* Information that can be computed from the ClassNode should be added to the call graph instead.
*
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
index 84f6d87c5c..2cf5cfcb8d 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BytecodeWriters.scala
@@ -78,7 +78,7 @@ trait BytecodeWriters {
}
/*
- * The ASM textual representation for bytecode overcomes disadvantages of javap ouput in three areas:
+ * The ASM textual representation for bytecode overcomes disadvantages of javap output in three areas:
* (a) pickle dingbats undecipherable to the naked eye;
* (b) two constant pools, while having identical contents, are displayed differently due to physical layout.
* (c) stack maps (classfile version 50 and up) are displayed in encoded form by javap,
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala
index e25b55e7ab..90da570f01 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/BackendUtils.scala
@@ -382,7 +382,8 @@ class BackendUtils[BT <: BTypes](val btypes: BT) {
* but not for writing in the classfile. We let the ClassWriter recompute max's.
*
* NOTE 2: the maxStack value computed here may be larger than the smallest correct value
- * that would allow running an analyzer, see `InstructionStackEffect.forAsmAnalysisConservative`.
+ * that would allow running an analyzer, see `InstructionStackEffect.forAsmAnalysis` and
+ * `InstructionStackEffect.maxStackGrowth`.
*
* NOTE 3: the implementation doesn't look at instructions that cannot be reached, it computes
* the max local / stack size in the reachable code. These max's work just fine for running an
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/analysis/package.scala b/src/compiler/scala/tools/nsc/backend/jvm/analysis/package.scala
index ef961941a0..999c686aac 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/analysis/package.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/analysis/package.scala
@@ -110,7 +110,7 @@ package scala.tools.nsc.backend.jvm
* - Use YourKit for finding hotspots (cpu profiling). when it comes to drilling down into the details
* of a hotspot, don't pay too much attention to the percentages / time counts.
* - Should also try other profilers.
- * - Use timers. When a method showed up as a hotspot, i added a timer around that method, and a
+ * - Use timers. When a method showed up as a hotspot, I added a timer around that method, and a
* second one within the method to measure specific parts. The timers slow things down, but the
* relative numbers show what parts of a method are slow.
*
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/BoxUnbox.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/BoxUnbox.scala
index a4cd8fce1e..78fc7e1ecf 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/BoxUnbox.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/BoxUnbox.scala
@@ -69,7 +69,7 @@ class BoxUnbox[BT <: BTypes](val btypes: BT) {
* E1: M1 only works if there's a single boxing operation.
* def e1(b: Boolean) = {
* val i: Integer = box(10) // 10 is stored into a new local, box operation and i removed
- * val j: Integer = box(20) // 20 is stored into a new local, box operation adn j removed
+ * val j: Integer = box(20) // 20 is stored into a new local, box operation and j removed
* val r = if (b) i else j // loads and stores of the box are eliminated, r no longer exists
* unbox(r) // cannot rewrite: we don't know which local to load
* }
@@ -138,7 +138,7 @@ class BoxUnbox[BT <: BTypes](val btypes: BT) {
* - note that the MatchError creation is dead code: local2 is never null. However, our nullness
* analysis cannot identify this: it does not track nullness through tuple stores and loads.
* - if we re-write the non-escaping consumers of the outer tuple, but keep the tuple allocation
- * and the escaping consumer, we get the follwoing:
+ * and the escaping consumer, we get the following:
*
* load 1, load 2
* val newLocal1 = new Tuple2; load newLocal1 // stack: Tuple2
@@ -188,7 +188,7 @@ class BoxUnbox[BT <: BTypes](val btypes: BT) {
var maxStackGrowth = 0
- /** Mehtod M1 for eliminating box-unbox pairs (see doc comment in the beginning of this file) */
+ /** Method M1 for eliminating box-unbox pairs (see doc comment in the beginning of this file) */
def replaceBoxOperationsSingleCreation(creation: BoxCreation, finalCons: Set[BoxConsumer], boxKind: BoxKind, keepBox: Boolean): Unit = {
/**
* If the box is eliminated, all copy operations (loads, stores, others) of the box need to
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala
index 78acd72dba..f2ff73c44d 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/ByteCodeRepository.scala
@@ -167,7 +167,7 @@ class ByteCodeRepository[BT <: BTypes](val classPath: ClassPath, val btypes: BT)
* the users (e.g. the inliner) have to be aware of method selection.
*
* Note that the returned method may be abstract (ACC_ABSTRACT), native (ACC_NATIVE) or signature
- * polymorphic (methods `invoke` and `invokeExact` in class `MehtodHandles`).
+ * polymorphic (methods `invoke` and `invokeExact` in class `MethodHandles`).
*
* @return The [[MethodNode]] of the requested method and the [[InternalName]] of its declaring
* class, or an error message if the method could not be found. An error message is also
@@ -204,8 +204,8 @@ class ByteCodeRepository[BT <: BTypes](val classPath: ClassPath, val btypes: BT)
visited += i
// abstract and static methods are excluded, see jvms-5.4.3.3
for (m <- findMethod(c) if !isPrivateMethod(m) && !isStaticMethod(m)) found += ((m, c))
- val recusionResult = findIn(c)
- if (recusionResult.isDefined) return recusionResult
+ val recursionResult = findIn(c)
+ if (recursionResult.isDefined) return recursionResult
}
None
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
index 9c0dfb0ee2..a740ca525c 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CallGraph.scala
@@ -285,7 +285,7 @@ class CallGraph[BT <: BTypes](val btypes: BT) {
// final case class :: / final case object Nil
// (l: List).map // can be inlined
// we need to know that
- // - the recevier is sealed
+ // - the receiver is sealed
// - what are the children of the receiver
// - all children are final
// - none of the children overrides map
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala
index b05669ce89..518646812e 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/CopyProp.scala
@@ -273,7 +273,7 @@ class CopyProp[BT <: BTypes](val btypes: BT) {
}
/**
- * Eliminate the `numArgs` inputs of the instruction `prod` (which was eliminated). Fo
+ * Eliminate the `numArgs` inputs of the instruction `prod` (which was eliminated). For
* each input value
* - if the `prod` instruction is the single consumer, enqueue the producers of the input
* - otherwise, insert a POP instruction to POP the input value
@@ -465,7 +465,7 @@ class CopyProp[BT <: BTypes](val btypes: BT) {
}
/**
- * Remove `xSTORE n; xLOAD n` paris if
+ * Remove `xSTORE n; xLOAD n` pairs if
* - the local variable n is not used anywhere else in the method (1), and
* - there are no executable instructions and no live labels (jump targets) between the two (2)
*
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala
index 16ed9da0e4..7bc4ea2392 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlineInfoAttribute.scala
@@ -82,7 +82,7 @@ case class InlineInfoAttribute(inlineInfo: InlineInfo) extends Attribute(InlineI
}
/**
- * De-serialize the attribute into an InlineInfo. The attribute starts at cr.b(off), but we don't
+ * Deserialize the attribute into an InlineInfo. The attribute starts at cr.b(off), but we don't
* need to access that array directly, we can use the `read` methods provided by the ClassReader.
*
* `buf` is a pre-allocated character array that is guaranteed to be long enough to hold any
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
index b9f593a4d8..0ae8347dc5 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/Inliner.scala
@@ -683,7 +683,7 @@ class Inliner[BT <: BTypes](val btypes: BT) {
* (A2) C and D are members of the same run-time package
*/
def classIsAccessible(accessed: BType, from: ClassBType): Either[OptimizerWarning, Boolean] = (accessed: @unchecked) match {
- // TODO: A2 requires "same run-time package", which seems to be package + classloader (JMVS 5.3.). is the below ok?
+ // TODO: A2 requires "same run-time package", which seems to be package + classloader (JVMS 5.3.). is the below ok?
case c: ClassBType => c.isPublic.map(_ || c.packageInternalName == from.packageInternalName)
case a: ArrayBType => classIsAccessible(a.elementType, from)
case _: PrimitiveBType => Right(true)
@@ -725,7 +725,7 @@ class Inliner[BT <: BTypes](val btypes: BT) {
* type from there (https://github.com/scala-opt/scala/issues/13).
*/
def memberIsAccessible(memberFlags: Int, memberDeclClass: ClassBType, memberRefClass: ClassBType, from: ClassBType): Either[OptimizerWarning, Boolean] = {
- // TODO: B3 requires "same run-time package", which seems to be package + classloader (JMVS 5.3.). is the below ok?
+ // TODO: B3 requires "same run-time package", which seems to be package + classloader (JVMS 5.3.). is the below ok?
def samePackageAsDestination = memberDeclClass.packageInternalName == from.packageInternalName
def targetObjectConformsToDestinationClass = false // needs type propagation analysis, see above
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala
index 4744cb9ab1..63360e17ff 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/InlinerHeuristics.scala
@@ -125,7 +125,7 @@ class InlinerHeuristics[BT <: BTypes](val bTypes: BT) {
if (callsite.isInlineAnnotated && callee.canInlineFromSource) {
// By default, we only emit inliner warnings for methods annotated @inline. However, we don't
// want to be unnecessarily noisy with `-opt-warnings:_`: for example, the inliner heuristic
- // would attempty to inline `Function1.apply$sp$II`, as it's higher-order (the receiver is
+ // would attempt to inline `Function1.apply$sp$II`, as it's higher-order (the receiver is
// a function), and it's concrete (forwards to `apply`). But because it's non-final, it cannot
// be inlined. So we only create warnings here for methods annotated @inline.
Some(Left(CalleeNotFinal(
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala b/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
index 65d1e20d69..9c22b09cdd 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/opt/LocalOpt.scala
@@ -61,7 +61,7 @@ import scala.tools.nsc.backend.jvm.opt.BytecodeUtils._
* - empty local variable descriptors (local variables that were holding the box may become unused)
*
* copy propagation (replaces LOAD n to the LOAD m for the smallest m that is an alias of n)
- * + enables downstrem:
+ * + enables downstream:
* - stale stores (a stored value may not be loaded anymore)
* - store-load pairs (a load n may now be right after a store n)
* + NOTE: copy propagation is only executed once, in the first fixpoint loop iteration. none of
diff --git a/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala b/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala
index 133a656206..1ea152b29c 100644
--- a/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala
+++ b/src/compiler/scala/tools/nsc/classpath/DirectoryClassPath.scala
@@ -106,7 +106,7 @@ trait JFileDirectoryLookup[FileEntryType <: ClassRepresentation] extends Directo
// as the type of `case class C(); case class D(); List(C(), D()).head`, rather than the opposite order.
// On Mac, the HFS performs this sorting transparently, but on Linux the order is unspecified.
//
- // Note this behaviour can be enabled with in javac with `javac -XDsortfiles`, but that's only
+ // Note this behaviour can be enabled in javac with `javac -XDsortfiles`, but that's only
// intended to improve determinism of the compiler for compiler hackers.
util.Arrays.sort(listing, (o1: File, o2: File) => o1.getName.compareTo(o2.getName))
listing
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index 947af55724..3ef75679ee 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -276,7 +276,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
// SelectFromTypeTree otherwise. See #3567.
// Select nodes can be later
// converted in the typechecker to SelectFromTypeTree if the class
- // turns out to be an instance ionner class instead of a static inner class.
+ // turns out to be an instance inner class instead of a static inner class.
def typeSelect(t: Tree, name: Name) = t match {
case Ident(_) | Select(_, _) => Select(t, name)
case _ => SelectFromTypeTree(t, name.toTypeName)
diff --git a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
index 342031b601..99263bf834 100644
--- a/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
+++ b/src/compiler/scala/tools/nsc/reporters/ConsoleReporter.scala
@@ -7,9 +7,10 @@ package scala
package tools.nsc
package reporters
-import java.io.{ BufferedReader, PrintWriter }
-import scala.reflect.internal.util._
-import StringOps._
+import java.io.{BufferedReader, PrintWriter}
+import scala.reflect.internal.util.{Position, StringOps}
+import Position.formatMessage
+import StringOps.{countElementsAsString => countAs, trimAllTrailingSpace => trimTrailing}
/** This class implements a Reporter that displays messages on a text console.
*/
@@ -26,47 +27,35 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr
private def label(severity: Severity): String = severity match {
case ERROR => "error"
case WARNING => "warning"
- case INFO => null
+ case INFO => ""
}
- protected def clabel(severity: Severity): String = {
- val label0 = label(severity)
- if (label0 eq null) "" else label0 + ": "
+ protected def clabel(severity: Severity): String = label(severity) match {
+ case "" => ""
+ case s => s"$s: "
}
- /** Returns the number of errors issued totally as a string.
- */
- private def getCountString(severity: Severity): String =
- StringOps.countElementsAsString((severity).count, label(severity))
-
/** Prints the message. */
- def printMessage(msg: String) {
- writer print trimAllTrailingSpace(msg) + "\n"
+ def printMessage(msg: String): Unit = {
+ writer.println(trimTrailing(msg))
writer.flush()
}
/** Prints the message with the given position indication. */
- def printMessage(posIn: Position, msg: String) {
- printMessage(Position.formatMessage(posIn, msg, shortname))
- }
- def print(pos: Position, msg: String, severity: Severity) {
- printMessage(pos, clabel(severity) + msg)
- }
+ def printMessage(posIn: Position, msg: String): Unit = printMessage(formatMessage(posIn, msg, shortname))
- /** Prints the column marker of the given position.
- */
- def printColumnMarker(pos: Position) =
- if (pos.isDefined) { printMessage(" " * (pos.column - 1) + "^") }
+ def print(pos: Position, msg: String, severity: Severity): Unit = printMessage(pos, s"${clabel(severity)}${msg}")
- /** Prints the number of errors and warnings if their are non-zero. */
- def printSummary() {
- if (WARNING.count > 0) printMessage(getCountString(WARNING) + " found")
- if ( ERROR.count > 0) printMessage(getCountString(ERROR ) + " found")
- }
+ /** Prints the column marker of the given position. */
+ def printColumnMarker(pos: Position): Unit = if (pos.isDefined) printMessage(" " * (pos.column - 1) + "^")
+
+ /** Prints the number of warnings and errors if there are any. */
+ def printSummary(): Unit =
+ for (k <- List(WARNING, ERROR) if k.count > 0) printMessage(s"${countAs(k.count, label(k))} found")
def display(pos: Position, msg: String, severity: Severity): Unit = {
val ok = severity match {
- case ERROR => ERROR.count <= settings.maxerrs.value
+ case ERROR => ERROR.count <= settings.maxerrs.value
case WARNING => WARNING.count <= settings.maxwarns.value
case _ => true
}
@@ -74,17 +63,19 @@ class ConsoleReporter(val settings: Settings, reader: BufferedReader, writer: Pr
}
def displayPrompt(): Unit = {
- writer.print("\na)bort, s)tack, r)esume: ")
+ writer.println()
+ writer.print("a)bort, s)tack, r)esume: ")
writer.flush()
if (reader != null) {
- val response = reader.read().asInstanceOf[Char].toLower
- if (response == 'a' || response == 's') {
- (new Exception).printStackTrace()
- if (response == 'a')
- sys exit 1
-
- writer.print("\n")
- writer.flush()
+ reader.read match {
+ case 'a' | 'A' =>
+ new Throwable().printStackTrace()
+ System.exit(1)
+ case 's' | 'S' =>
+ new Throwable().printStackTrace()
+ writer.println()
+ writer.flush()
+ case _ =>
}
}
}
diff --git a/src/compiler/scala/tools/nsc/settings/Warnings.scala b/src/compiler/scala/tools/nsc/settings/Warnings.scala
index 839e734abc..87534656f9 100644
--- a/src/compiler/scala/tools/nsc/settings/Warnings.scala
+++ b/src/compiler/scala/tools/nsc/settings/Warnings.scala
@@ -25,6 +25,8 @@ trait Warnings {
// currently considered too noisy for general use
val warnUnusedImport = BooleanSetting("-Ywarn-unused-import", "Warn when imports are unused.")
+ val warnExtraImplicit = BooleanSetting("-Ywarn-extra-implicit", "Warn when more than one implicit parameter section is defined.")
+
// Experimental lint warnings that are turned off, but which could be turned on programmatically.
// They are not activated by -Xlint and can't be enabled on the command line because they are not
// created using the standard factory methods.
diff --git a/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala b/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala
index a0bba46398..e027b065ac 100644
--- a/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/transform/AccessorSynthesis.scala
@@ -99,7 +99,7 @@ trait AccessorSynthesis extends Transform with ast.TreeDSL {
}
- // TODO: better way to communicate from info transform to tree transfor?
+ // TODO: better way to communicate from info transform to tree transform?
private[this] val _bitmapInfo = perRunCaches.newMap[Symbol, BitmapInfo]
private[this] val _slowPathFor = perRunCaches.newMap[Symbol, Symbol]()
diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
index 855e53710b..2e7ab8a887 100644
--- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
+++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
@@ -152,7 +152,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
val resTpOk = (
samResultType =:= UnitTpe
|| functionResultType =:= samResultType
- || (isReferenceType(samResultType) && isReferenceType(functionResultType))) // yes, this is what the spec says -- no further correspondance required
+ || (isReferenceType(samResultType) && isReferenceType(functionResultType))) // yes, this is what the spec says -- no further correspondence required
if (resTpOk && (samParamTypes corresponds functionParamTypes){ (samParamTp, funParamTp) =>
funParamTp =:= samParamTp || (isReferenceType(funParamTp) && isReferenceType(samParamTp) && funParamTp <:< samParamTp) }) target
else {
@@ -165,7 +165,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
// whenever a type in the sam's signature is (erases to) a primitive type, we must pick the sam's version,
// as we don't implement the logic regarding widening that's performed by LMF -- we require =:= for primitives
//
- // We use the sam's type for the check whether we're dealin with a reference type, as it could be a generic type,
+ // We use the sam's type for the check whether we're dealing with a reference type, as it could be a generic type,
// which means the function's parameter -- even if it expects a value class -- will need to be
// boxed on the generic call to the sam method.
diff --git a/src/compiler/scala/tools/nsc/transform/Fields.scala b/src/compiler/scala/tools/nsc/transform/Fields.scala
index fbf1e8cec1..b2bf9fad3f 100644
--- a/src/compiler/scala/tools/nsc/transform/Fields.scala
+++ b/src/compiler/scala/tools/nsc/transform/Fields.scala
@@ -58,7 +58,7 @@ import symtab.Flags._
*
* In the even longer term (Scala 3?), I agree with @DarkDimius that it would make sense
* to hide the difference between strict and lazy vals. All vals are lazy,
- * but the memoization overhead is removed when we statically know they are forced during initialiation.
+ * but the memoization overhead is removed when we statically know they are forced during initialization.
* We could still expose the low-level field semantics through `private[this] val`s.
*
* In any case, the current behavior of overriding vals is pretty surprising.
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index 798cfcd072..169fe7588e 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -113,7 +113,7 @@ abstract class LambdaLift extends InfoTransform {
*
* For DelayedInit subclasses, constructor statements end up in the synthetic init method
* instead of the constructor itself, so the access should go to the field. This method changes
- * `logicallyEnclosingMember` in this case to return a temprorary symbol corresponding to that
+ * `logicallyEnclosingMember` in this case to return a temporary symbol corresponding to that
* method.
*/
private def logicallyEnclosingMember(sym: Symbol): Symbol = {
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index de0db51b6c..96e2135c52 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -32,7 +32,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL with AccessorSynthes
* we cannot emit PROTECTED methods in interfaces on the JVM,
* but knowing that these trait methods are protected means we won't emit static forwarders.
*
- * JVMLS: "Methods of interfaces may have any of the flags in Table 4.6-A set
+ * JVMS: "Methods of interfaces may have any of the flags in Table 4.6-A set
* except ACC_PROTECTED, ACC_FINAL, ACC_SYNCHRONIZED, and ACC_NATIVE (JLS §9.4)."
*
* TODO: can we just set the right flags from the start??
@@ -137,7 +137,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL with AccessorSynthes
*/
def addMember(clazz: Symbol, member: Symbol): Symbol = {
debuglog(s"mixing into $clazz: ${member.defString}")
- // This attachment is used to instruct the backend about which methids in traits require
+ // This attachment is used to instruct the backend about which methods in traits require
// a static trait impl method. We remove this from the new symbol created for the method
// mixed into the subclass.
member.removeAttachment[NeedStaticImpl.type]
diff --git a/src/compiler/scala/tools/nsc/transform/SampleTransform.scala b/src/compiler/scala/tools/nsc/transform/SampleTransform.scala
index ba303f7c2b..4c1705e386 100644
--- a/src/compiler/scala/tools/nsc/transform/SampleTransform.scala
+++ b/src/compiler/scala/tools/nsc/transform/SampleTransform.scala
@@ -35,7 +35,7 @@ abstract class SampleTransform extends Transform {
atPos(tree1.pos)( // `atPos` fills in position of its tree argument
Select( // The `Select` factory method is defined in class `Trees`
sup,
- currentOwner.newValue( // creates a new term symbol owned by `currentowner`
+ currentOwner.newValue( // creates a new term symbol owned by `currentOwner`
newTermName("sample"), // The standard term name creator
tree1.pos)))))
case _ =>
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 84f47c1caa..9161786d76 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -1992,7 +1992,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
else exitingSpecialize(specializeCalls(unit).transform(tree))
// Remove the final modifier and @inline annotation from anything in the
- // original class (since it's being overridden in at least onesubclass).
+ // original class (since it's being overridden in at least one subclass).
//
// We do this here so that the specialized subclasses will correctly copy
// final and @inline.
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 096b6b9263..dcffd7a6ab 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -363,7 +363,7 @@ abstract class UnCurry extends InfoTransform
* mark the method symbol SYNCHRONIZED for bytecode generation.
*
* Delambdafy targets are deemed ineligible as the Delambdafy phase will
- * replace `this.synchronized` with `$this.synchronzed` now that it emits
+ * replace `this.synchronized` with `$this.synchronized` now that it emits
* all lambda impl methods as static.
*/
private def translateSynchronized(tree: Tree) = tree match {
@@ -705,7 +705,7 @@ abstract class UnCurry extends InfoTransform
//
// So what we need to do is to use the pre-uncurry type when creating `l$1`, which is `c.Tree` and is
// correct. Now, there are two additional problems:
- // 1. when varargs and byname params are involved, the uncurry transformation desugares these special
+ // 1. when varargs and byname params are involved, the uncurry transformation desugars these special
// cases to actual typerefs, eg:
// ```
// T* ~> Seq[T] (Scala-defined varargs)
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
index cb3759e5fa..db6eac34cb 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/Logic.scala
@@ -184,8 +184,8 @@ trait Logic extends Debugging {
// push negation inside formula
def negationNormalFormNot(p: Prop): Prop = p match {
- case And(ops) => Or(ops.map(negationNormalFormNot)) // De'Morgan
- case Or(ops) => And(ops.map(negationNormalFormNot)) // De'Morgan
+ case And(ops) => Or(ops.map(negationNormalFormNot)) // De Morgan
+ case Or(ops) => And(ops.map(negationNormalFormNot)) // De Morgan
case Not(p) => negationNormalForm(p)
case True => False
case False => True
diff --git a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala
index 89c793ec94..794d3d442a 100644
--- a/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala
+++ b/src/compiler/scala/tools/nsc/transform/patmat/MatchTreeMaking.scala
@@ -564,11 +564,11 @@ trait MatchTreeMaking extends MatchCodeGen with Debugging {
else scrut match {
case Typed(tree, tpt) =>
val suppressExhaustive = tpt.tpe hasAnnotation UncheckedClass
- val supressUnreachable = tree match {
+ val suppressUnreachable = tree match {
case Ident(name) if name startsWith nme.CHECK_IF_REFUTABLE_STRING => true // SI-7183 don't warn for withFilter's that turn out to be irrefutable.
case _ => false
}
- val suppression = Suppression(suppressExhaustive, supressUnreachable)
+ val suppression = Suppression(suppressExhaustive, suppressUnreachable)
val hasSwitchAnnotation = treeInfo.isSwitchAnnotation(tpt.tpe)
// matches with two or fewer cases need not apply for switchiness (if-then-else will do)
// `case 1 | 2` is considered as two cases.
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index 2d8d591b6d..0910dca445 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -1211,7 +1211,7 @@ trait ContextErrors {
"pass-by-name arguments not allowed for case class parameters"
case AbstractVar =>
- "only classes can have declared but undefined members" + abstractVarMessage(sym)
+ "only traits and abstract classes can have declared but undefined members" + abstractVarMessage(sym)
}
issueSymbolTypeError(sym, msg)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index fde2f7bb03..d349597b14 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -1194,7 +1194,8 @@ trait Contexts { self: Analyzer =>
}
final def lookupCompanionOf(original: Symbol): Symbol = {
- lookupScopeEntry(original) match {
+ if (original.isModuleClass) original.sourceModule
+ else lookupScopeEntry(original) match {
case null => NoSymbol
case entry => entry.owner.lookupCompanion(original)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
index df014b5161..ea82739504 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Duplicators.scala
@@ -240,10 +240,6 @@ abstract class Duplicators extends Analyzer {
result.symbol.updateAttachment(DelambdafyTarget)
result
- case fun: Function =>
- debuglog("Clearing the type and retyping Function: " + fun)
- super.typed(fun.clearType, mode, pt)
-
case vdef @ ValDef(mods, name, tpt, rhs) =>
// log("vdef fixing tpe: " + tree.tpe + " with sym: " + tree.tpe.typeSymbol + " and " + invalidSyms)
//if (mods.hasFlag(Flags.LAZY)) vdef.symbol.resetFlag(Flags.MUTABLE) // Martin to Iulian: lazy vars can now appear because they are no longer boxed; Please check that deleting this statement is OK.
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index e8147dbf3a..9dd260b274 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -495,21 +495,22 @@ trait Infer extends Checkable {
}
/** Return inferred type arguments, given type parameters, formal parameters,
- * argument types, result type and expected result type.
- * If this is not possible, throw a `NoInstance` exception.
- * Undetermined type arguments are represented by `definitions.NothingTpe`.
- * No check that inferred parameters conform to their bounds is made here.
- *
- * @param tparams the type parameters of the method
- * @param formals the value parameter types of the method
- * @param restpe the result type of the method
- * @param argtpes the argument types of the application
- * @param pt the expected return type of the application
- * @return @see adjustTypeArgs
- *
- * @throws NoInstance
- */
- def methTypeArgs(tparams: List[Symbol], formals: List[Type], restpe: Type,
+ * argument types, result type and expected result type.
+ * If this is not possible, throw a `NoInstance` exception.
+ * Undetermined type arguments are represented by `definitions.NothingTpe`.
+ * No check that inferred parameters conform to their bounds is made here.
+ *
+ * @param fn the function for reporting, may be empty
+ * @param tparams the type parameters of the method
+ * @param formals the value parameter types of the method
+ * @param restpe the result type of the method
+ * @param argtpes the argument types of the application
+ * @param pt the expected return type of the application
+ * @return @see adjustTypeArgs
+ *
+ * @throws NoInstance
+ */
+ def methTypeArgs(fn: Tree, tparams: List[Symbol], formals: List[Type], restpe: Type,
argtpes: List[Type], pt: Type): AdjustedTypeArgs.Result = {
val tvars = tparams map freshVar
if (!sameLength(formals, argtpes))
@@ -559,21 +560,12 @@ trait Infer extends Checkable {
val hasAny = pt :: restpe :: formals ::: argtpes ::: loBounds exists (_.dealiasWidenChain exists containsAny)
!hasAny
}
- def argumentPosition(idx: Int): Position = context.tree match {
- case x: ValOrDefDef => x.rhs match {
- case Apply(fn, args) if idx < args.size => args(idx).pos
- case _ => context.tree.pos
- }
- case _ => context.tree.pos
- }
- if (settings.warnInferAny && context.reportErrors && canWarnAboutAny) {
- foreachWithIndex(targs) ((targ, idx) =>
- targ.typeSymbol match {
- case sym @ (AnyClass | AnyValClass) =>
- reporter.warning(argumentPosition(idx), s"a type was inferred to be `${sym.name}`; this may indicate a programming error.")
- case _ =>
- }
- )
+ if (settings.warnInferAny && context.reportErrors && !fn.isEmpty && canWarnAboutAny) {
+ targs.foreach(_.typeSymbol match {
+ case sym @ (AnyClass | AnyValClass) =>
+ reporter.warning(fn.pos, s"a type was inferred to be `${sym.name}`; this may indicate a programming error.")
+ case _ =>
+ })
}
adjustTypeArgs(tparams, tvars, targs, restpe)
}
@@ -735,7 +727,7 @@ trait Infer extends Checkable {
)
def tryInstantiating(args: List[Type]) = falseIfNoInstance {
val restpe = mt resultType args
- val AdjustedTypeArgs.Undets(okparams, okargs, leftUndet) = methTypeArgs(undetparams, formals, restpe, args, pt)
+ val AdjustedTypeArgs.Undets(okparams, okargs, leftUndet) = methTypeArgs(EmptyTree, undetparams, formals, restpe, args, pt)
val restpeInst = restpe.instantiateTypeParams(okparams, okargs)
// #2665: must use weak conformance, not regular one (follow the monomorphic case above)
exprTypeArgs(leftUndet, restpeInst, pt, useWeaklyCompatible = true) match {
@@ -989,7 +981,7 @@ trait Infer extends Checkable {
val restpe = fn.tpe.resultType(argtpes)
val AdjustedTypeArgs.AllArgsAndUndets(okparams, okargs, allargs, leftUndet) =
- methTypeArgs(undetparams, formals, restpe, argtpes, pt)
+ methTypeArgs(fn, undetparams, formals, restpe, argtpes, pt)
if (checkBounds(fn, NoPrefix, NoSymbol, undetparams, allargs, "inferred ")) {
val treeSubst = new TreeTypeSubstituter(okparams, okargs)
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 296d9c6bca..a787a7bc12 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1130,7 +1130,7 @@ abstract class RefChecks extends Transform {
}
/** Sensibility check examines flavors of equals. */
def checkSensible(pos: Position, fn: Tree, args: List[Tree]) = fn match {
- case Select(qual, name @ (nme.EQ | nme.NE | nme.eq | nme.ne)) if args.length == 1 && isObjectOrAnyComparisonMethod(fn.symbol) && !currentOwner.isSynthetic =>
+ case Select(qual, name @ (nme.EQ | nme.NE | nme.eq | nme.ne)) if args.length == 1 && isObjectOrAnyComparisonMethod(fn.symbol) && (!currentOwner.isSynthetic || currentOwner.isAnonymousFunction) =>
checkSensibleEquals(pos, qual, name, fn.symbol, args.head)
case _ =>
}
@@ -1158,6 +1158,7 @@ abstract class RefChecks extends Transform {
}
}
checkUndesiredProperties(rtpe.typeSymbol, tree.pos)
+ checkUndesiredProperties(rtpe.typeSymbol.primaryConstructor, tree.pos)
tree
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 58a44d3ac0..837ccf7e06 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -864,11 +864,24 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
case _ =>
}
debuglog(s"fallback on implicits: ${tree}/$resetTree")
- val tree1 = typed(resetTree, mode)
- // Q: `typed` already calls `pluginsTyped` and `adapt`. the only difference here is that
- // we pass `EmptyTree` as the `original`. intended? added in 2009 (53d98e7d42) by martin.
- tree1 setType pluginsTyped(tree1.tpe, this, tree1, mode, pt)
- if (tree1.isEmpty) tree1 else adapt(tree1, mode, pt, EmptyTree)
+ // SO-10066 Need to patch the enclosing tree in the context to make translation of Dynamic
+ // work during fallback typechecking below.
+ val resetContext: Context = {
+ object substResetForOriginal extends Transformer {
+ override def transform(tree: Tree): Tree = {
+ if (tree eq original) resetTree
+ else super.transform(tree)
+ }
+ }
+ context.make(substResetForOriginal.transform(context.tree))
+ }
+ typerWithLocalContext(resetContext) { typer1 =>
+ val tree1 = typer1.typed(resetTree, mode)
+ // Q: `typed` already calls `pluginsTyped` and `adapt`. the only difference here is that
+ // we pass `EmptyTree` as the `original`. intended? added in 2009 (53d98e7d42) by martin.
+ tree1 setType pluginsTyped(tree1.tpe, typer1, tree1, mode, pt)
+ if (tree1.isEmpty) tree1 else typer1.adapt(tree1, mode, pt, EmptyTree)
+ }
}
)
else
diff --git a/src/compiler/scala/tools/nsc/util/package.scala b/src/compiler/scala/tools/nsc/util/package.scala
index bd95fdbb50..80e82c85d8 100644
--- a/src/compiler/scala/tools/nsc/util/package.scala
+++ b/src/compiler/scala/tools/nsc/util/package.scala
@@ -89,7 +89,7 @@ package object util {
implicit class StackTraceOps(private val e: Throwable) extends AnyVal with StackTracing {
/** Format the stack trace, returning the prefix consisting of frames that satisfy
* a given predicate.
- * The format is similar to the typical case described in the JavaDoc
+ * The format is similar to the typical case described in the Javadoc
* for [[java.lang.Throwable#printStackTrace]].
* If a stack trace is truncated, it will be followed by a line of the form
* `... 3 elided`, by analogy to the lines `... 3 more` which indicate
diff --git a/src/library/rootdoc.txt b/src/library/rootdoc.txt
index d78df01046..0aef41c4da 100644
--- a/src/library/rootdoc.txt
+++ b/src/library/rootdoc.txt
@@ -44,8 +44,7 @@ Additional parts of the standard library are shipped as separate libraries. Thes
- [[scala.reflect `scala.reflect`]] - Scala's reflection API (scala-reflect.jar)
- [[scala.xml `scala.xml`]] - XML parsing, manipulation, and serialization (scala-xml.jar)
- [[scala.swing `scala.swing`]] - A convenient wrapper around Java's GUI framework called Swing (scala-swing.jar)
- - [[scala.util.parsing `scala.util.parsing`]] - [[scala.util.parsing.combinator Parser combinators]], including an
- example implementation of a [[scala.util.parsing.json JSON parser]] (scala-parser-combinators.jar)
+ - [[scala.util.parsing `scala.util.parsing`]] - Parser combinators (scala-parser-combinators.jar)
== Automatic imports ==
diff --git a/src/library/scala/annotation/showAsInfix.scala b/src/library/scala/annotation/showAsInfix.scala
new file mode 100644
index 0000000000..6c25e08efa
--- /dev/null
+++ b/src/library/scala/annotation/showAsInfix.scala
@@ -0,0 +1,27 @@
+package scala.annotation
+
+/**
+ * This annotation configures how Scala prints two-parameter generic types.
+ *
+ * By default, types with symbolic names are printed infix; while types without
+ * them are printed using the regular generic type syntax.
+ *
+ * Example of usage:
+ {{{
+ scala> class Map[T, U]
+ defined class Map
+
+ scala> def foo: Int Map Int = ???
+ foo: Map[Int,Int]
+
+ scala> @showAsInfix class Map[T, U]
+ defined class Map
+
+ scala> def foo: Int Map Int = ???
+ foo: Int Map Int
+ }}}
+ *
+ * @param enabled whether to show this type as an infix type operator.
+ * @since 2.12.2
+ */
+class showAsInfix(enabled: Boolean = true) extends annotation.StaticAnnotation \ No newline at end of file
diff --git a/src/library/scala/collection/GenTraversableLike.scala b/src/library/scala/collection/GenTraversableLike.scala
index 1cd126f94f..0ee5542e30 100644
--- a/src/library/scala/collection/GenTraversableLike.scala
+++ b/src/library/scala/collection/GenTraversableLike.scala
@@ -249,30 +249,6 @@ trait GenTraversableLike[+A, +Repr] extends Any with GenTraversableOnce[A] with
* @param bf $bfinfo
* @return a new collection of type `That` which contains all elements
* of this $coll followed by all elements of `that`.
- *
- * @usecase def ++[B](that: GenTraversableOnce[B]): $Coll[B]
- * @inheritdoc
- *
- * Example:
- * {{{
- * scala> val a = List(1)
- * a: List[Int] = List(1)
- *
- * scala> val b = List(2)
- * b: List[Int] = List(2)
- *
- * scala> val c = a ++ b
- * c: List[Int] = List(1, 2)
- *
- * scala> val d = List('a')
- * d: List[Char] = List(a)
- *
- * scala> val e = c ++ d
- * e: List[AnyVal] = List(1, 2, a)
- * }}}
- *
- * @return a new $coll which contains all elements of this $coll
- * followed by all elements of `that`.
*/
def ++[B >: A, That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[Repr, B, That]): That
diff --git a/src/library/scala/collection/IterableLike.scala b/src/library/scala/collection/IterableLike.scala
index b89720da78..419206c226 100644
--- a/src/library/scala/collection/IterableLike.scala
+++ b/src/library/scala/collection/IterableLike.scala
@@ -177,14 +177,14 @@ self =>
}
/** Groups elements in fixed size blocks by passing a "sliding window"
- * over them (as opposed to partitioning them, as is done in grouped.)
- * "Sliding window" step is 1 by default.
+ * over them (as opposed to partitioning them, as is done in `grouped`.)
+ * The "sliding window" step is set to one.
* @see [[scala.collection.Iterator]], method `sliding`
*
* @param size the number of elements per group
* @return An iterator producing ${coll}s of size `size`, except the
- * last and the only element will be truncated if there are
- * fewer elements than size.
+ * last element (which may be the only element) will be truncated
+ * if there are fewer than `size` elements remaining to be grouped.
*/
def sliding(size: Int): Iterator[Repr] = sliding(size, 1)
@@ -196,8 +196,8 @@ self =>
* @param step the distance between the first elements of successive
* groups
* @return An iterator producing ${coll}s of size `size`, except the
- * last and the only element will be truncated if there are
- * fewer elements than size.
+ * last element (which may be the only element) will be truncated
+ * if there are fewer than `size` elements remaining to be grouped.
*/
def sliding(size: Int, step: Int): Iterator[Repr] =
for (xs <- iterator.sliding(size, step)) yield {
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index d000d22f72..809e851494 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -1091,7 +1091,7 @@ trait Iterator[+A] extends TraversableOnce[A] {
extends AbstractIterator[Seq[B]]
with Iterator[Seq[B]] {
- require(size >= 1 && step >= 1, "size=%d and step=%d, but both must be positive".format(size, step))
+ require(size >= 1 && step >= 1, f"size=$size%d and step=$step%d, but both must be positive")
private[this] var buffer: ArrayBuffer[B] = ArrayBuffer() // the buffer
private[this] var filled = false // whether the buffer is "hot"
@@ -1099,30 +1099,30 @@ trait Iterator[+A] extends TraversableOnce[A] {
private[this] var pad: Option[() => B] = None // what to pad short sequences with
/** Public functions which can be used to configure the iterator before use.
- *
- * Pads the last segment if necessary so that all segments will
- * have the same size.
- *
- * @param x The element that will be appended to the last segment, if necessary.
- * @return The same iterator, and ''not'' a new iterator.
- * @note This method mutates the iterator it is called on, which can be safely used afterwards.
- * @note This method is mutually exclusive with `withPartial(true)`.
- */
+ *
+ * Pads the last segment if necessary so that all segments will
+ * have the same size.
+ *
+ * @param x The element that will be appended to the last segment, if necessary.
+ * @return The same iterator, and ''not'' a new iterator.
+ * @note This method mutates the iterator it is called on, which can be safely used afterwards.
+ * @note This method is mutually exclusive with `withPartial(true)`.
+ */
def withPadding(x: => B): this.type = {
pad = Some(() => x)
this
}
- /** Public functions which can be used to configure the iterator before use.
- *
- * Select whether the last segment may be returned with less than `size`
- * elements. If not, some elements of the original iterator may not be
- * returned at all.
- *
- * @param x `true` if partial segments may be returned, `false` otherwise.
- * @return The same iterator, and ''not'' a new iterator.
- * @note This method mutates the iterator it is called on, which can be safely used afterwards.
- * @note This method is mutually exclusive with `withPadding`.
- */
+ /** Public functions which can be used to configure the iterator before use.
+ *
+ * Select whether the last segment may be returned with less than `size`
+ * elements. If not, some elements of the original iterator may not be
+ * returned at all.
+ *
+ * @param x `true` if partial segments may be returned, `false` otherwise.
+ * @return The same iterator, and ''not'' a new iterator.
+ * @note This method mutates the iterator it is called on, which can be safely used afterwards.
+ * @note This method is mutually exclusive with `withPadding`.
+ */
def withPartial(x: Boolean): this.type = {
_partial = x
if (_partial == true) // reset pad since otherwise it will take precedence
@@ -1231,9 +1231,15 @@ trait Iterator[+A] extends TraversableOnce[A] {
new GroupedIterator[B](self, size, size)
/** Returns an iterator which presents a "sliding window" view of
- * another iterator. The first argument is the window size, and
- * the second is how far to advance the window on each iteration;
- * defaults to `1`. Example usages:
+ * this iterator. The first argument is the window size, and
+ * the second argument `step` is how far to advance the window
+ * on each iteration. The `step` defaults to `1`.
+ *
+ * The default `GroupedIterator` can be configured to either
+ * pad a partial result to size `size` or suppress the partial
+ * result entirely.
+ *
+ * Example usages:
* {{{
* // Returns List(List(1, 2, 3), List(2, 3, 4), List(3, 4, 5))
* (1 to 5).iterator.sliding(3).toList
@@ -1247,6 +1253,11 @@ trait Iterator[+A] extends TraversableOnce[A] {
* (1 to 5).iterator.sliding(4, 3).withPadding(it2.next).toList
* }}}
*
+ * @return An iterator producing `Seq[B]`s of size `size`, except the
+ * last element (which may be the only element) will be truncated
+ * if there are fewer than `size` elements remaining to be grouped.
+ * This behavior can be configured.
+ *
* @note Reuse: $consumesAndProducesIterator
*/
def sliding[B >: A](size: Int, step: Int = 1): GroupedIterator[B] =
diff --git a/src/library/scala/collection/concurrent/TrieMap.scala b/src/library/scala/collection/concurrent/TrieMap.scala
index 769d7b0dac..fe0b5c4f0e 100644
--- a/src/library/scala/collection/concurrent/TrieMap.scala
+++ b/src/library/scala/collection/concurrent/TrieMap.scala
@@ -932,6 +932,33 @@ extends scala.collection.concurrent.Map[K, V]
if (nonReadOnly) readOnlySnapshot().iterator
else new TrieMapIterator(0, this)
+ ////////////////////////////////////////////////////////////////////////////
+ //
+ // SI-10177 These methods need overrides as the inherited implementations
+ // call `.iterator` more than once, which doesn't guarantee a coherent
+ // view of the data if there is a concurrent writer
+ // Note that the we don't need overrides for keysIterator or valuesIterator
+ // TrieMapTest validates the behaviour.
+ override def values: Iterable[V] = {
+ if (nonReadOnly) readOnlySnapshot().values
+ else super.values
+ }
+ override def keySet: Set[K] = {
+ if (nonReadOnly) readOnlySnapshot().keySet
+ else super.keySet
+ }
+ override def filterKeys(p: K => Boolean): collection.Map[K, V] = {
+ if (nonReadOnly) readOnlySnapshot().filterKeys(p)
+ else super.filterKeys(p)
+ }
+ override def mapValues[W](f: V => W): collection.Map[K, W] = {
+ if (nonReadOnly) readOnlySnapshot().mapValues(f)
+ else super.mapValues(f)
+ }
+ // END extra overrides
+ ///////////////////////////////////////////////////////////////////
+
+
private def cachedSize() = {
val r = RDCSS_READ_ROOT()
r.cachedSize(this)
diff --git a/src/library/scala/collection/convert/DecorateAsJava.scala b/src/library/scala/collection/convert/DecorateAsJava.scala
index 8371804b91..83fffa5940 100644
--- a/src/library/scala/collection/convert/DecorateAsJava.scala
+++ b/src/library/scala/collection/convert/DecorateAsJava.scala
@@ -18,91 +18,91 @@ import scala.language.implicitConversions
trait DecorateAsJava extends AsJavaConverters {
/**
* Adds an `asJava` method that implicitly converts a Scala `Iterator` to a Java `Iterator`.
- * See [[asJavaIterator]].
+ * @see [[asJavaIterator]]
*/
implicit def asJavaIteratorConverter[A](i : Iterator[A]): AsJava[ju.Iterator[A]] =
new AsJava(asJavaIterator(i))
/**
- * Adds an `asJavaEnumeration` method that implicitly converts a Scala `Iterator` to a Java
- * `Enumeration`. See [[asJavaEnumeration]].
+ * Adds an `asJavaEnumeration` method that implicitly converts a Scala `Iterator` to a Java `Enumeration`.
+ * @see [[asJavaEnumeration]]
*/
implicit def asJavaEnumerationConverter[A](i : Iterator[A]): AsJavaEnumeration[A] =
new AsJavaEnumeration(i)
/**
* Adds an `asJava` method that implicitly converts a Scala `Iterable` to a Java `Iterable`.
- * See [[asJavaIterable]].
+ * @see [[asJavaIterable]]
*/
implicit def asJavaIterableConverter[A](i : Iterable[A]): AsJava[jl.Iterable[A]] =
new AsJava(asJavaIterable(i))
/**
- * Adds an `asJavaCollection` method that implicitly converts a Scala `Iterable` to an immutable
- * Java `Collection`. See [[asJavaCollection]].
+ * Adds an `asJavaCollection` method that implicitly converts a Scala `Iterable` to an immutable Java `Collection`.
+ * @see [[asJavaCollection]]
*/
implicit def asJavaCollectionConverter[A](i : Iterable[A]): AsJavaCollection[A] =
new AsJavaCollection(i)
/**
* Adds an `asJava` method that implicitly converts a Scala mutable `Buffer` to a Java `List`.
- * See [[bufferAsJavaList]].
+ * @see [[bufferAsJavaList]]
*/
implicit def bufferAsJavaListConverter[A](b : mutable.Buffer[A]): AsJava[ju.List[A]] =
new AsJava(bufferAsJavaList(b))
/**
* Adds an `asJava` method that implicitly converts a Scala mutable `Seq` to a Java `List`.
- * See [[mutableSeqAsJavaList]].
+ * @see [[mutableSeqAsJavaList]]
*/
implicit def mutableSeqAsJavaListConverter[A](b : mutable.Seq[A]): AsJava[ju.List[A]] =
new AsJava(mutableSeqAsJavaList(b))
/**
* Adds an `asJava` method that implicitly converts a Scala `Seq` to a Java `List`.
- * See [[seqAsJavaList]].
+ * @see [[seqAsJavaList]]
*/
implicit def seqAsJavaListConverter[A](b : Seq[A]): AsJava[ju.List[A]] =
new AsJava(seqAsJavaList(b))
/**
* Adds an `asJava` method that implicitly converts a Scala mutable `Set` to a Java `Set`.
- * See [[mutableSetAsJavaSet]].
+ * @see [[mutableSetAsJavaSet]]
*/
implicit def mutableSetAsJavaSetConverter[A](s : mutable.Set[A]): AsJava[ju.Set[A]] =
new AsJava(mutableSetAsJavaSet(s))
/**
* Adds an `asJava` method that implicitly converts a Scala `Set` to a Java `Set`.
- * See [[setAsJavaSet]].
+ * @see [[setAsJavaSet]]
*/
implicit def setAsJavaSetConverter[A](s : Set[A]): AsJava[ju.Set[A]] =
new AsJava(setAsJavaSet(s))
/**
* Adds an `asJava` method that implicitly converts a Scala mutable `Map` to a Java `Map`.
- * See [[mutableMapAsJavaMap]].
+ * @see [[mutableMapAsJavaMap]]
*/
implicit def mutableMapAsJavaMapConverter[A, B](m : mutable.Map[A, B]): AsJava[ju.Map[A, B]] =
new AsJava(mutableMapAsJavaMap(m))
/**
- * Adds an `asJavaDictionary` method that implicitly converts a Scala mutable `Map` to a Java
- * `Dictionary`. See [[asJavaDictionary]].
+ * Adds an `asJavaDictionary` method that implicitly converts a Scala mutable `Map` to a Java `Dictionary`.
+ * @see [[asJavaDictionary]]
*/
implicit def asJavaDictionaryConverter[A, B](m : mutable.Map[A, B]): AsJavaDictionary[A, B] =
new AsJavaDictionary(m)
/**
* Adds an `asJava` method that implicitly converts a Scala `Map` to a Java `Map`.
- * See [[mapAsJavaMap]].
+ * @see [[mapAsJavaMap]]
*/
implicit def mapAsJavaMapConverter[A, B](m : Map[A, B]): AsJava[ju.Map[A, B]] =
new AsJava(mapAsJavaMap(m))
/**
- * Adds an `asJava` method that implicitly converts a Scala mutable `concurrent.Map` to a Java
- * `ConcurrentMap`. See [[mapAsJavaConcurrentMap]].
+ * Adds an `asJava` method that implicitly converts a Scala mutable `concurrent.Map` to a Java `ConcurrentMap`.
+ * @see [[mapAsJavaConcurrentMap]].
*/
implicit def mapAsJavaConcurrentMapConverter[A, B](m: concurrent.Map[A, B]): AsJava[juc.ConcurrentMap[A, B]] =
new AsJava(mapAsJavaConcurrentMap(m))
diff --git a/src/library/scala/collection/convert/DecorateAsScala.scala b/src/library/scala/collection/convert/DecorateAsScala.scala
index b74a06ece5..f680aa5267 100644
--- a/src/library/scala/collection/convert/DecorateAsScala.scala
+++ b/src/library/scala/collection/convert/DecorateAsScala.scala
@@ -18,70 +18,70 @@ import scala.language.implicitConversions
trait DecorateAsScala extends AsScalaConverters {
/**
* Adds an `asScala` method that implicitly converts a Java `Iterator` to a Scala `Iterator`.
- * See [[asScalaIterator]].
+ * @see [[asScalaIterator]]
*/
implicit def asScalaIteratorConverter[A](i : ju.Iterator[A]): AsScala[Iterator[A]] =
new AsScala(asScalaIterator(i))
/**
* Adds an `asScala` method that implicitly converts a Java `Enumeration` to a Scala `Iterator`.
- * See [[enumerationAsScalaIterator]].
+ * @see [[enumerationAsScalaIterator]]
*/
implicit def enumerationAsScalaIteratorConverter[A](i : ju.Enumeration[A]): AsScala[Iterator[A]] =
new AsScala(enumerationAsScalaIterator(i))
/**
* Adds an `asScala` method that implicitly converts a Java `Iterable` to a Scala `Iterable`.
- * See [[iterableAsScalaIterable]].
+ * @see [[iterableAsScalaIterable]]
*/
implicit def iterableAsScalaIterableConverter[A](i : jl.Iterable[A]): AsScala[Iterable[A]] =
new AsScala(iterableAsScalaIterable(i))
/**
* Adds an `asScala` method that implicitly converts a Java `Collection` to an Scala `Iterable`.
- * See [[collectionAsScalaIterable]].
+ * @see [[collectionAsScalaIterable]]
*/
implicit def collectionAsScalaIterableConverter[A](i : ju.Collection[A]): AsScala[Iterable[A]] =
new AsScala(collectionAsScalaIterable(i))
/**
* Adds an `asScala` method that implicitly converts a Java `List` to a Scala mutable `Buffer`.
- * See [[asScalaBuffer]].
+ * @see [[asScalaBuffer]]
*/
implicit def asScalaBufferConverter[A](l : ju.List[A]): AsScala[mutable.Buffer[A]] =
new AsScala(asScalaBuffer(l))
/**
* Adds an `asScala` method that implicitly converts a Java `Set` to a Scala mutable `Set`.
- * See [[asScalaSet]].
+ * @see [[asScalaSet]]
*/
implicit def asScalaSetConverter[A](s : ju.Set[A]): AsScala[mutable.Set[A]] =
new AsScala(asScalaSet(s))
/**
* Adds an `asScala` method that implicitly converts a Java `Map` to a Scala mutable `Map`.
- * See [[mapAsScalaMap]].
+ * @see [[mapAsScalaMap]]
*/
implicit def mapAsScalaMapConverter[A, B](m : ju.Map[A, B]): AsScala[mutable.Map[A, B]] =
new AsScala(mapAsScalaMap(m))
/**
- * Adds an `asScala` method that implicitly converts a Java `ConcurrentMap` to a Scala mutable
- * `concurrent.Map`. See [[mapAsScalaConcurrentMap]].
+ * Adds an `asScala` method that implicitly converts a Java `ConcurrentMap` to a Scala mutable `concurrent.Map`.
+ * @see [[mapAsScalaConcurrentMap]]
*/
implicit def mapAsScalaConcurrentMapConverter[A, B](m: juc.ConcurrentMap[A, B]): AsScala[concurrent.Map[A, B]] =
new AsScala(mapAsScalaConcurrentMap(m))
/**
* Adds an `asScala` method that implicitly converts a Java `Dictionary` to a Scala mutable `Map`.
- * See [[dictionaryAsScalaMap]].
+ * @see [[dictionaryAsScalaMap]]
*/
implicit def dictionaryAsScalaMapConverter[A, B](p: ju.Dictionary[A, B]): AsScala[mutable.Map[A, B]] =
new AsScala(dictionaryAsScalaMap(p))
/**
- * Adds an `asScala` method that implicitly converts a Java `Properties` to a Scala mutable
- * `Map[String, String]`. See [[propertiesAsScalaMap]].
+ * Adds an `asScala` method that implicitly converts a Java `Properties` to a Scala mutable `Map[String, String]`.
+ * @see [[propertiesAsScalaMap]]
*/
implicit def propertiesAsScalaMapConverter(p: ju.Properties): AsScala[mutable.Map[String, String]] =
new AsScala(propertiesAsScalaMap(p))
diff --git a/src/library/scala/collection/convert/ImplicitConversions.scala b/src/library/scala/collection/convert/ImplicitConversions.scala
index 747e0606c8..35e6ce1616 100644
--- a/src/library/scala/collection/convert/ImplicitConversions.scala
+++ b/src/library/scala/collection/convert/ImplicitConversions.scala
@@ -17,76 +17,122 @@ import JavaConverters._
/** Defines implicit converter methods from Java to Scala collections. */
trait ToScalaImplicits {
- /** Implicitly converts a Java `Iterator` to a Scala `Iterator`. See [[asScalaIterator]]. */
+ /** Implicitly converts a Java `Iterator` to a Scala `Iterator`.
+ * @see [[AsScalaConverters.asScalaIterator]]
+ */
implicit def `iterator asScala`[A](it: ju.Iterator[A]): Iterator[A] = asScalaIterator(it)
- /** Implicitly converts a Java `Enumeration` to a Scala `Iterator`. See [[enumerationAsScalaIterator]]. */
+ /** Implicitly converts a Java `Enumeration` to a Scala `Iterator`.
+ * @see [[AsScalaConverters.enumerationAsScalaIterator]]
+ */
implicit def `enumeration AsScalaIterator`[A](i: ju.Enumeration[A]): Iterator[A] = enumerationAsScalaIterator(i)
- /** Implicitly converts a Java `Iterable` to a Scala `Iterable`. See [[iterableAsScalaIterable]]. */
+ /** Implicitly converts a Java `Iterable` to a Scala `Iterable`.
+ * @see [[AsScalaConverters.iterableAsScalaIterable]]
+ */
implicit def `iterable AsScalaIterable`[A](i: jl.Iterable[A]): Iterable[A] = iterableAsScalaIterable(i)
- /** Implicitly converts a Java `Collection` to an Scala `Iterable`. See [[collectionAsScalaIterable]]. */
+ /** Implicitly converts a Java `Collection` to an Scala `Iterable`.
+ * @see [[AsScalaConverters.collectionAsScalaIterable]]
+ */
implicit def `collection AsScalaIterable`[A](i: ju.Collection[A]): Iterable[A] = collectionAsScalaIterable(i)
- /** Implicitly converts a Java `List` to a Scala mutable `Buffer`. See [[asScalaBuffer]]. */
+ /** Implicitly converts a Java `List` to a Scala mutable `Buffer`.
+ * @see [[AsScalaConverters.asScalaBuffer]]
+ */
implicit def `list asScalaBuffer`[A](l: ju.List[A]): mutable.Buffer[A] = asScalaBuffer(l)
- /** Implicitly converts a Java `Set` to a Scala mutable `Set`. See [[asScalaSet]]. */
+ /** Implicitly converts a Java `Set` to a Scala mutable `Set`.
+ * @see [[AsScalaConverters.asScalaSet]]
+ */
implicit def `set asScala`[A](s: ju.Set[A]): mutable.Set[A] = asScalaSet(s)
- /** Implicitly converts a Java `Map` to a Scala mutable `Map`. See [[mapAsScalaMap]]. */
+ /** Implicitly converts a Java `Map` to a Scala mutable `Map`.
+ * @see [[AsScalaConverters.mapAsScalaMap]]
+ */
implicit def `map AsScala`[A, B](m: ju.Map[A, B]): mutable.Map[A, B] = mapAsScalaMap(m)
- /** Implicitly converts a Java `ConcurrentMap` to a Scala mutable `ConcurrentMap`. See [[mapAsScalaConcurrentMap]]. */
+ /** Implicitly converts a Java `ConcurrentMap` to a Scala mutable `ConcurrentMap`.
+ * @see [[AsScalaConverters.mapAsScalaConcurrentMap]]
+ */
implicit def `map AsScalaConcurrentMap`[A, B](m: juc.ConcurrentMap[A, B]): concurrent.Map[A, B] = mapAsScalaConcurrentMap(m)
- /** Implicitly converts a Java `Dictionary` to a Scala mutable `Map`. See [[dictionaryAsScalaMap]]. */
+ /** Implicitly converts a Java `Dictionary` to a Scala mutable `Map`.
+ * @see [[AsScalaConverters.dictionaryAsScalaMap]]
+ */
implicit def `dictionary AsScalaMap`[A, B](p: ju.Dictionary[A, B]): mutable.Map[A, B] = dictionaryAsScalaMap(p)
- /** Implicitly converts a Java `Properties` to a Scala `mutable Map[String, String]`. See [[propertiesAsScalaMap]]. */
+ /** Implicitly converts a Java `Properties` to a Scala `mutable Map[String, String]`.
+ * @see [[AsScalaConverters.propertiesAsScalaMap]]
+ */
implicit def `properties AsScalaMap`(p: ju.Properties): mutable.Map[String, String] = propertiesAsScalaMap(p)
}
/** Defines implicit conversions from Scala to Java collections. */
trait ToJavaImplicits {
- /** Implicitly converts a Scala `Iterator` to a Java `Iterator`. See [[asJavaIterator]]. */
+ /** Implicitly converts a Scala `Iterator` to a Java `Iterator`.
+ * @see [[AsJavaConverters.asJavaIterator]]
+ */
implicit def `iterator asJava`[A](it: Iterator[A]): ju.Iterator[A] = asJavaIterator(it)
- /** Implicitly converts a Scala `Iterator` to a Java `Enumeration`. See [[asJavaEnumeration]]. */
+ /** Implicitly converts a Scala `Iterator` to a Java `Enumeration`.
+ * @see [[AsJavaConverters.asJavaEnumeration]]
+ */
implicit def `enumeration asJava`[A](it: Iterator[A]): ju.Enumeration[A] = asJavaEnumeration(it)
- /** Implicitly converts a Scala `Iterable` to a Java `Iterable`. See [[asJavaIterable]]. */
+ /** Implicitly converts a Scala `Iterable` to a Java `Iterable`.
+ * @see [[AsJavaConverters.asJavaIterable]]
+ */
implicit def `iterable asJava`[A](i: Iterable[A]): jl.Iterable[A] = asJavaIterable(i)
- /** Implicitly converts a Scala `Iterable` to an immutable Java `Collection`. See [[asJavaCollection]]. */
+ /** Implicitly converts a Scala `Iterable` to an immutable Java `Collection`.
+ * @see [[AsJavaConverters.asJavaCollection]]
+ */
implicit def `collection asJava`[A](it: Iterable[A]): ju.Collection[A] = asJavaCollection(it)
- /** Implicitly converts a Scala mutable `Buffer` to a Java `List`. See [[bufferAsJavaList]]. */
+ /** Implicitly converts a Scala mutable `Buffer` to a Java `List`.
+ * @see [[AsJavaConverters.bufferAsJavaList]]
+ */
implicit def `buffer AsJavaList`[A](b: mutable.Buffer[A]): ju.List[A] = bufferAsJavaList(b)
- /** Implicitly converts a Scala mutable `Seq` to a Java `List`. See [[mutableSeqAsJavaList]]. */
+ /** Implicitly converts a Scala mutable `Seq` to a Java `List`.
+ * @see [[AsJavaConverters.mutableSeqAsJavaList]]
+ */
implicit def `mutableSeq AsJavaList`[A](seq: mutable.Seq[A]): ju.List[A] = mutableSeqAsJavaList(seq)
- /** Implicitly converts a Scala `Seq` to a Java `List`. See [[seqAsJavaList]]. */
+ /** Implicitly converts a Scala `Seq` to a Java `List`.
+ * @see [[AsJavaConverters.seqAsJavaList]]
+ */
implicit def `seq AsJavaList`[A](seq: Seq[A]): ju.List[A] = seqAsJavaList(seq)
- /** Implicitly converts a Scala mutable `Set` to a Java `Set`. See [[mutableSetAsJavaSet]]. */
+ /** Implicitly converts a Scala mutable `Set` to a Java `Set`.
+ * @see [[AsJavaConverters.mutableSetAsJavaSet]]
+ */
implicit def `mutableSet AsJavaSet`[A](s: mutable.Set[A]): ju.Set[A] = mutableSetAsJavaSet(s)
- /** Implicitly converts a Scala `Set` to a Java `Set`. See [[setAsJavaSet]]. */
+ /** Implicitly converts a Scala `Set` to a Java `Set`.
+ * @see [[AsJavaConverters.setAsJavaSet]]
+ */
implicit def `set AsJavaSet`[A](s: Set[A]): ju.Set[A] = setAsJavaSet(s)
- /** Implicitly converts a Scala mutable `Map` to a Java `Map`. See [[mutableMapAsJavaMap]]. */
+ /** Implicitly converts a Scala mutable `Map` to a Java `Map`.
+ * @see [[AsJavaConverters.mutableMapAsJavaMap]]
+ */
implicit def `mutableMap AsJavaMap`[A, B](m: mutable.Map[A, B]): ju.Map[A, B] = mutableMapAsJavaMap(m)
- /** Implicitly converts a Scala mutable `Map` to a Java `Dictionary`. See [[asJavaDictionary]]. */
+ /** Implicitly converts a Scala mutable `Map` to a Java `Dictionary`.
+ * @see [[AsJavaConverters.asJavaDictionary]]
+ */
implicit def `dictionary asJava`[A, B](m: mutable.Map[A, B]): ju.Dictionary[A, B] = asJavaDictionary(m)
- /** Implicitly converts a Scala `Map` to a Java `Map`. See [[mapAsJavaMap]]. */
+ /** Implicitly converts a Scala `Map` to a Java `Map`.
+ * @see [[AsJavaConverters.mapAsJavaMap]]
+ */
implicit def `map AsJavaMap`[A, B](m: Map[A, B]): ju.Map[A, B] = mapAsJavaMap(m)
- /** Implicitly converts a Scala mutable `concurrent.Map` to a Java `ConcurrentMap`. See [[mapAsJavaConcurrentMap]]. */
+ /** Implicitly converts a Scala mutable `concurrent.Map` to a Java `ConcurrentMap`.
+ * @see [[AsJavaConverters.mapAsJavaConcurrentMap]]
+ */
implicit def `map AsJavaConcurrentMap`[A, B](m: concurrent.Map[A, B]): juc.ConcurrentMap[A, B] = mapAsJavaConcurrentMap(m)
}
diff --git a/src/library/scala/collection/immutable/HashMap.scala b/src/library/scala/collection/immutable/HashMap.scala
index 6b29b084aa..627f723cb0 100644
--- a/src/library/scala/collection/immutable/HashMap.scala
+++ b/src/library/scala/collection/immutable/HashMap.scala
@@ -52,6 +52,9 @@ sealed class HashMap[A, +B] extends AbstractMap[A, B]
def get(key: A): Option[B] =
get0(key, computeHash(key), 0)
+ override final def contains(key: A): Boolean =
+ contains0(key, computeHash(key), 0)
+
override def updated [B1 >: B] (key: A, value: B1): HashMap[A, B1] =
updated0(key, computeHash(key), 0, value, null, null)
@@ -92,7 +95,7 @@ sealed class HashMap[A, +B] extends AbstractMap[A, B]
import HashMap.{Merger, MergeFunction, liftMerger}
private[collection] def get0(key: A, hash: Int, level: Int): Option[B] = None
-
+ protected def contains0(key: A, hash: Int, level: Int): Boolean = false
private[collection] def updated0[B1 >: B](key: A, hash: Int, level: Int, value: B1, kv: (A, B1), merger: Merger[A, B1]): HashMap[A, B1] =
new HashMap.HashMap1(key, hash, value, kv)
@@ -185,6 +188,7 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
}
}
+ @deprecatedInheritance("This class will be made final in a future release.", "2.12.2")
class HashMap1[A,+B](private[collection] val key: A, private[collection] val hash: Int, private[collection] val value: (B @uV), private[collection] var kv: (A,B @uV)) extends HashMap[A,B] {
override def size = 1
@@ -195,6 +199,8 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
override def get0(key: A, hash: Int, level: Int): Option[B] =
if (hash == this.hash && key == this.key) Some(value) else None
+ override protected def contains0(key: A, hash: Int, level: Int): Boolean =
+ hash == this.hash && key == this.key
private[collection] override def updated0[B1 >: B](key: A, hash: Int, level: Int, value: B1, kv: (A, B1), merger: Merger[A, B1]): HashMap[A, B1] =
if (hash == this.hash && key == this.key ) {
if (merger eq null) {
@@ -239,6 +245,9 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
override def get0(key: A, hash: Int, level: Int): Option[B] =
if (hash == this.hash) kvs.get(key) else None
+ override protected def contains0(key: A, hash: Int, level: Int): Boolean =
+ hash == this.hash && kvs.contains(key)
+
private[collection] override def updated0[B1 >: B](key: A, hash: Int, level: Int, value: B1, kv: (A, B1), merger: Merger[A, B1]): HashMap[A, B1] =
if (hash == this.hash) {
if ((merger eq null) || !kvs.contains(key)) new HashMapCollision1(hash, kvs.updated(key, value))
@@ -294,6 +303,7 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
}
}
+ @deprecatedInheritance("This class will be made final in a future release.", "2.12.2")
class HashTrieMap[A, +B](
private[collection] val bitmap: Int,
private[collection] val elems: Array[HashMap[A, B @uV]],
@@ -306,21 +316,41 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
override def size = size0
override def get0(key: A, hash: Int, level: Int): Option[B] = {
+ // Note: this code is duplicated with `contains0`
+ val index = (hash >>> level) & 0x1f
+ if (bitmap == - 1) {
+ elems(index).get0(key, hash, level + 5)
+ } else {
+ val mask = (1 << index)
+ if ((bitmap & mask) != 0) {
+ val offset = Integer.bitCount(bitmap & (mask - 1))
+ elems(offset).get0(key, hash, level + 5)
+ } else {
+ None
+ }
+ }
+ }
+
+ override protected def contains0(key: A, hash: Int, level: Int): Boolean = {
+ // Note: this code is duplicated from `get0`
val index = (hash >>> level) & 0x1f
- val mask = (1 << index)
if (bitmap == - 1) {
- elems(index & 0x1f).get0(key, hash, level + 5)
- } else if ((bitmap & mask) != 0) {
- val offset = Integer.bitCount(bitmap & (mask-1))
- elems(offset).get0(key, hash, level + 5)
- } else
- None
+ elems(index).contains0(key, hash, level + 5)
+ } else {
+ val mask = (1 << index)
+ if ((bitmap & mask) != 0) {
+ val offset = Integer.bitCount(bitmap & (mask - 1))
+ elems(offset).contains0(key, hash, level + 5)
+ } else {
+ false
+ }
+ }
}
private[collection] override def updated0[B1 >: B](key: A, hash: Int, level: Int, value: B1, kv: (A, B1), merger: Merger[A, B1]): HashMap[A, B1] = {
val index = (hash >>> level) & 0x1f
val mask = (1 << index)
- val offset = Integer.bitCount(bitmap & (mask-1))
+ val offset = Integer.bitCount(bitmap & (mask - 1))
if ((bitmap & mask) != 0) {
val sub = elems(offset)
val subNew = sub.updated0(key, hash, level + 5, value, kv, merger)
@@ -342,7 +372,7 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
override def removed0(key: A, hash: Int, level: Int): HashMap[A, B] = {
val index = (hash >>> level) & 0x1f
val mask = (1 << index)
- val offset = Integer.bitCount(bitmap & (mask-1))
+ val offset = Integer.bitCount(bitmap & (mask - 1))
if ((bitmap & mask) != 0) {
val sub = elems(offset)
val subNew = sub.removed0(key, hash, level + 5)
diff --git a/src/library/scala/collection/immutable/Queue.scala b/src/library/scala/collection/immutable/Queue.scala
index 1dd0d7683a..240b5c899e 100644
--- a/src/library/scala/collection/immutable/Queue.scala
+++ b/src/library/scala/collection/immutable/Queue.scala
@@ -106,6 +106,15 @@ sealed class Queue[+A] protected(protected val in: List[A], protected val out: L
case _ => super.:+(elem)(bf)
}
+ override def ++[B >: A, That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[Queue[A], B, That]): That = {
+ if (bf eq Queue.ReusableCBF) {
+ val thatQueue = that.asInstanceOf[Queue[B]]
+ new Queue[B](thatQueue.in ++ (thatQueue.out reverse_::: this.in), this.out).asInstanceOf[That]
+ } else {
+ super.++(that)(bf)
+ }
+ }
+
/** Creates a new queue with element added at the end
* of the old queue.
*
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala
index 3d4e32971c..8f26de153a 100644
--- a/src/library/scala/collection/immutable/Stream.scala
+++ b/src/library/scala/collection/immutable/Stream.scala
@@ -1119,11 +1119,11 @@ object Stream extends SeqFactory[Stream] {
/** Construct a stream consisting of a given first element followed by elements
* from a lazily evaluated Stream.
*/
- def #::(hd: A): Stream[A] = cons(hd, tl)
+ def #::[B >: A](hd: B): Stream[B] = cons(hd, tl)
/** Construct a stream consisting of the concatenation of the given stream and
* a lazily evaluated Stream.
*/
- def #:::(prefix: Stream[A]): Stream[A] = prefix append tl
+ def #:::[B >: A](prefix: Stream[B]): Stream[B] = prefix append tl
}
/** A wrapper method that adds `#::` for cons and `#:::` for concat as operations
diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala
index 3329e35042..29382134aa 100644
--- a/src/library/scala/collection/mutable/ArrayOps.scala
+++ b/src/library/scala/collection/mutable/ArrayOps.scala
@@ -177,9 +177,7 @@ sealed trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomPara
(a1, a2, a3)
}
-
def seq = thisCollection
-
}
/**
@@ -189,7 +187,7 @@ sealed trait ArrayOps[T] extends Any with ArrayLike[T, Array[T]] with CustomPara
*/
object ArrayOps {
- /** A class of `ArrayOps` for arrays containing reference types. */
+ /** A subclass of `ArrayOps` for arrays containing reference types. */
final class ofRef[T <: AnyRef](override val repr: Array[T]) extends AnyVal with ArrayOps[T] with ArrayLike[T, Array[T]] {
override protected[this] def thisCollection: WrappedArray[T] = new WrappedArray.ofRef[T](repr)
@@ -201,8 +199,8 @@ object ArrayOps {
def update(index: Int, elem: T) { repr(index) = elem }
}
- /** A class of `ArrayOps` for arrays containing `byte`s. */
-final class ofByte(override val repr: Array[Byte]) extends AnyVal with ArrayOps[Byte] with ArrayLike[Byte, Array[Byte]] {
+ /** A subclass of `ArrayOps` for arrays containing `Byte`s. */
+ final class ofByte(override val repr: Array[Byte]) extends AnyVal with ArrayOps[Byte] with ArrayLike[Byte, Array[Byte]] {
override protected[this] def thisCollection: WrappedArray[Byte] = new WrappedArray.ofByte(repr)
override protected[this] def toCollection(repr: Array[Byte]): WrappedArray[Byte] = new WrappedArray.ofByte(repr)
@@ -213,8 +211,8 @@ final class ofByte(override val repr: Array[Byte]) extends AnyVal with ArrayOps[
def update(index: Int, elem: Byte) { repr(index) = elem }
}
- /** A class of `ArrayOps` for arrays containing `short`s. */
-final class ofShort(override val repr: Array[Short]) extends AnyVal with ArrayOps[Short] with ArrayLike[Short, Array[Short]] {
+ /** A subclass of `ArrayOps` for arrays containing `Short`s. */
+ final class ofShort(override val repr: Array[Short]) extends AnyVal with ArrayOps[Short] with ArrayLike[Short, Array[Short]] {
override protected[this] def thisCollection: WrappedArray[Short] = new WrappedArray.ofShort(repr)
override protected[this] def toCollection(repr: Array[Short]): WrappedArray[Short] = new WrappedArray.ofShort(repr)
@@ -225,8 +223,8 @@ final class ofShort(override val repr: Array[Short]) extends AnyVal with ArrayOp
def update(index: Int, elem: Short) { repr(index) = elem }
}
- /** A class of `ArrayOps` for arrays containing `char`s. */
-final class ofChar(override val repr: Array[Char]) extends AnyVal with ArrayOps[Char] with ArrayLike[Char, Array[Char]] {
+ /** A subclass of `ArrayOps` for arrays containing `Char`s. */
+ final class ofChar(override val repr: Array[Char]) extends AnyVal with ArrayOps[Char] with ArrayLike[Char, Array[Char]] {
override protected[this] def thisCollection: WrappedArray[Char] = new WrappedArray.ofChar(repr)
override protected[this] def toCollection(repr: Array[Char]): WrappedArray[Char] = new WrappedArray.ofChar(repr)
@@ -237,8 +235,8 @@ final class ofChar(override val repr: Array[Char]) extends AnyVal with ArrayOps[
def update(index: Int, elem: Char) { repr(index) = elem }
}
- /** A class of `ArrayOps` for arrays containing `int`s. */
-final class ofInt(override val repr: Array[Int]) extends AnyVal with ArrayOps[Int] with ArrayLike[Int, Array[Int]] {
+ /** A subclass of `ArrayOps` for arrays containing `Int`s. */
+ final class ofInt(override val repr: Array[Int]) extends AnyVal with ArrayOps[Int] with ArrayLike[Int, Array[Int]] {
override protected[this] def thisCollection: WrappedArray[Int] = new WrappedArray.ofInt(repr)
override protected[this] def toCollection(repr: Array[Int]): WrappedArray[Int] = new WrappedArray.ofInt(repr)
@@ -249,8 +247,8 @@ final class ofInt(override val repr: Array[Int]) extends AnyVal with ArrayOps[In
def update(index: Int, elem: Int) { repr(index) = elem }
}
- /** A class of `ArrayOps` for arrays containing `long`s. */
-final class ofLong(override val repr: Array[Long]) extends AnyVal with ArrayOps[Long] with ArrayLike[Long, Array[Long]] {
+ /** A subclass of `ArrayOps` for arrays containing `Long`s. */
+ final class ofLong(override val repr: Array[Long]) extends AnyVal with ArrayOps[Long] with ArrayLike[Long, Array[Long]] {
override protected[this] def thisCollection: WrappedArray[Long] = new WrappedArray.ofLong(repr)
override protected[this] def toCollection(repr: Array[Long]): WrappedArray[Long] = new WrappedArray.ofLong(repr)
@@ -261,8 +259,8 @@ final class ofLong(override val repr: Array[Long]) extends AnyVal with ArrayOps[
def update(index: Int, elem: Long) { repr(index) = elem }
}
- /** A class of `ArrayOps` for arrays containing `float`s. */
-final class ofFloat(override val repr: Array[Float]) extends AnyVal with ArrayOps[Float] with ArrayLike[Float, Array[Float]] {
+ /** A subclass of `ArrayOps` for arrays containing `Float`s. */
+ final class ofFloat(override val repr: Array[Float]) extends AnyVal with ArrayOps[Float] with ArrayLike[Float, Array[Float]] {
override protected[this] def thisCollection: WrappedArray[Float] = new WrappedArray.ofFloat(repr)
override protected[this] def toCollection(repr: Array[Float]): WrappedArray[Float] = new WrappedArray.ofFloat(repr)
@@ -273,8 +271,8 @@ final class ofFloat(override val repr: Array[Float]) extends AnyVal with ArrayOp
def update(index: Int, elem: Float) { repr(index) = elem }
}
- /** A class of `ArrayOps` for arrays containing `double`s. */
-final class ofDouble(override val repr: Array[Double]) extends AnyVal with ArrayOps[Double] with ArrayLike[Double, Array[Double]] {
+ /** A subclass of `ArrayOps` for arrays containing `Double`s. */
+ final class ofDouble(override val repr: Array[Double]) extends AnyVal with ArrayOps[Double] with ArrayLike[Double, Array[Double]] {
override protected[this] def thisCollection: WrappedArray[Double] = new WrappedArray.ofDouble(repr)
override protected[this] def toCollection(repr: Array[Double]): WrappedArray[Double] = new WrappedArray.ofDouble(repr)
@@ -285,8 +283,8 @@ final class ofDouble(override val repr: Array[Double]) extends AnyVal with Array
def update(index: Int, elem: Double) { repr(index) = elem }
}
- /** A class of `ArrayOps` for arrays containing `boolean`s. */
-final class ofBoolean(override val repr: Array[Boolean]) extends AnyVal with ArrayOps[Boolean] with ArrayLike[Boolean, Array[Boolean]] {
+ /** A subclass of `ArrayOps` for arrays containing `Boolean`s. */
+ final class ofBoolean(override val repr: Array[Boolean]) extends AnyVal with ArrayOps[Boolean] with ArrayLike[Boolean, Array[Boolean]] {
override protected[this] def thisCollection: WrappedArray[Boolean] = new WrappedArray.ofBoolean(repr)
override protected[this] def toCollection(repr: Array[Boolean]): WrappedArray[Boolean] = new WrappedArray.ofBoolean(repr)
@@ -297,8 +295,8 @@ final class ofBoolean(override val repr: Array[Boolean]) extends AnyVal with Arr
def update(index: Int, elem: Boolean) { repr(index) = elem }
}
- /** A class of `ArrayOps` for arrays of `Unit` types. */
-final class ofUnit(override val repr: Array[Unit]) extends AnyVal with ArrayOps[Unit] with ArrayLike[Unit, Array[Unit]] {
+ /** A subclass of `ArrayOps` for arrays of `Unit` types. */
+ final class ofUnit(override val repr: Array[Unit]) extends AnyVal with ArrayOps[Unit] with ArrayLike[Unit, Array[Unit]] {
override protected[this] def thisCollection: WrappedArray[Unit] = new WrappedArray.ofUnit(repr)
override protected[this] def toCollection(repr: Array[Unit]): WrappedArray[Unit] = new WrappedArray.ofUnit(repr)
diff --git a/src/library/scala/deprecated.scala b/src/library/scala/deprecated.scala
index 60f0857550..a57745dbea 100644
--- a/src/library/scala/deprecated.scala
+++ b/src/library/scala/deprecated.scala
@@ -39,20 +39,18 @@ import scala.annotation.meta._
* '''`@deprecated` in the Scala language and its standard library'''<br/>
*
* A deprecated element of the Scala language or a definition in the Scala standard library will
- * be preserved or at least another major version.
+ * be preserved at least for the current major version.
*
- * This means that an element deprecated since 2.12 will be preserved in 2.13, but will very likely
- * not be part of 2.14. Sometimes a deprecated element might be kept for more than a major
- * release to ease migration and upgrades from older Scala versions.<br/>
- * Developers should not rely on this.
+ * This means that an element deprecated in some 2.12.x release will be preserved in
+ * all 2.12.x releases, but may be removed in 2.13. (A deprecated element
+ * might be kept longer to ease migration. Developers should not rely on this.)
*
* '''Special deprecation policy for Scala 2.12'''<br>
- * The Scala team has decided to enact a special deprecation policy for the 2.12 release:<br/>
+ * The Scala team has decided to enact a special deprecation policy for Scala 2.12:<br/>
*
- * As an upgrade from Scala 2.11 to Scala 2.12 also requires upgrading from Java 6 to Java 8,
- * no deprecated elements will be removed in this release to ease migration and upgrades
- * from older Scala versions. This means that elements deprecated since 2.11 (or earlier)
- * will not be removed in Scala 2.12.
+ * As an upgrade from 2.11 to 2.12 also requires upgrading from Java 6 to Java 8,
+ * deprecated elements will not normally be removed in this release, to ease migration
+ * and cross-building.
*
* @see The official documentation on [[http://www.scala-lang.org/news/2.11.0/#binary-compatibility binary compatibility]].
* @param message the message to print during compilation if the definition is accessed
diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
index a6e584424b..8ba3e62ac2 100644
--- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
@@ -316,8 +316,9 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
/** Check whether any of the arguments mention a symbol */
def refsSymbol(sym: Symbol) = hasArgWhich(_.symbol == sym)
- def stringArg(index: Int) = constantAtIndex(index) map (_.stringValue)
- def intArg(index: Int) = constantAtIndex(index) map (_.intValue)
+ def stringArg(index: Int) = constantAtIndex(index) map (_.stringValue)
+ def intArg(index: Int) = constantAtIndex(index) map (_.intValue)
+ def booleanArg(index: Int) = constantAtIndex(index) map (_.booleanValue)
def symbolArg(index: Int) = argAtIndex(index) collect {
case Apply(fun, Literal(str) :: Nil) if fun.symbol == definitions.Symbol_apply =>
newTermName(str.stringValue)
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 19460af27f..78a75c63d6 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -975,10 +975,10 @@ trait Definitions extends api.StandardDefinitions {
}
/** Given a class symbol C with type parameters T1, T2, ... Tn
- * which have upper/lower bounds LB1/UB1, LB1/UB2, ..., LBn/UBn,
+ * which have upper/lower bounds LB1/UB1, LB2/UB2, ..., LBn/UBn,
* returns an existential type of the form
*
- * C[E1, ..., En] forSome { E1 >: LB1 <: UB1 ... en >: LBn <: UBn }.
+ * C[E1, ..., En] forSome { E1 >: LB1 <: UB1 ... En >: LBn <: UBn }.
*/
// TODO Review the way this is used. I see two potential problems:
// 1. `existentialAbstraction` here doesn't create fresh existential type symbols, it just
@@ -1421,6 +1421,8 @@ trait Definitions extends api.StandardDefinitions {
case _ => false
}
+ lazy val ShowAsInfixAnnotationClass = rootMirror.getClassIfDefined("scala.annotation.showAsInfix")
+
// todo: reconcile with javaSignature!!!
def signature(tp: Type): String = {
def erasure(tp: Type): Type = tp match {
diff --git a/src/reflect/scala/reflect/internal/Positions.scala b/src/reflect/scala/reflect/internal/Positions.scala
index 95b3b7fb14..1a1aa2e721 100644
--- a/src/reflect/scala/reflect/internal/Positions.scala
+++ b/src/reflect/scala/reflect/internal/Positions.scala
@@ -255,7 +255,7 @@ trait Positions extends api.Positions { self: SymbolTable =>
val annTrees = mdef.mods.annotations match {
case Nil if mdef.symbol != null =>
// After typechecking, annotations are moved from the modifiers
- // to the annotation on the symbol of the anotatee.
+ // to the annotation on the symbol of the annotatee.
mdef.symbol.annotations.map(_.original)
case anns => anns
}
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index 9602a2859b..bb352e9d31 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -775,7 +775,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
}
// constructor's params processing (don't print single empty constructor param list)
vparamss match {
- case Nil | List(Nil) if (!mods.isCase && !ctorMods.hasFlag(AccessFlags)) =>
+ case Nil | List(Nil) if !mods.isCase && !ctorMods.hasFlag(AccessFlags) =>
case _ => vparamss foreach printConstrParams
}
parents
diff --git a/src/reflect/scala/reflect/internal/ReificationSupport.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala
index 026438e421..1b2be64654 100644
--- a/src/reflect/scala/reflect/internal/ReificationSupport.scala
+++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala
@@ -266,7 +266,7 @@ trait ReificationSupport { self: SymbolTable =>
}
// undo gen.mkTemplate
- protected object UnMkTemplate {
+ protected class UnMkTemplate(isCaseClass: Boolean) {
def unapply(templ: Template): Option[(List[Tree], ValDef, Modifiers, List[List[ValDef]], List[Tree], List[Tree])] = {
val Template(parents, selfType, _) = templ
val tbody = treeInfo.untypecheckedTemplBody(templ)
@@ -296,8 +296,9 @@ trait ReificationSupport { self: SymbolTable =>
result(ctorMods, Nil, edefs, body)
else {
// undo conversion from (implicit ... ) to ()(implicit ... ) when it's the only parameter section
+ // except that case classes require the explicit leading empty parameter list
val vparamssRestoredImplicits = ctorVparamss match {
- case Nil :: (tail @ ((head :: _) :: _)) if head.mods.isImplicit => tail
+ case Nil :: (tail @ ((head :: _) :: _)) if head.mods.isImplicit && !isCaseClass => tail
case other => other
}
// undo flag modifications by merging flag info from constructor args and fieldDefs
@@ -314,7 +315,9 @@ trait ReificationSupport { self: SymbolTable =>
}
}
}
+ def asCase = new UnMkTemplate(isCaseClass = true)
}
+ protected object UnMkTemplate extends UnMkTemplate(isCaseClass = false)
protected def mkSelfType(tree: Tree) = tree match {
case vd: ValDef =>
@@ -346,9 +349,11 @@ trait ReificationSupport { self: SymbolTable =>
def unapply(tree: Tree): Option[(Modifiers, TypeName, List[TypeDef], Modifiers, List[List[ValDef]],
List[Tree], List[Tree], ValDef, List[Tree])] = tree match {
- case ClassDef(mods, name, tparams, UnMkTemplate(parents, selfType, ctorMods, vparamss, earlyDefs, body))
- if !ctorMods.isTrait && !ctorMods.hasFlag(JAVA) =>
- Some((mods, name, tparams, ctorMods, vparamss, earlyDefs, parents, selfType, body))
+ case ClassDef(mods, name, tparams, impl) =>
+ val X = if (mods.isCase) UnMkTemplate.asCase else UnMkTemplate
+ val X(parents, selfType, ctorMods, vparamss, earlyDefs, body) = impl
+ if (ctorMods.isTrait || ctorMods.hasFlag(JAVA)) None
+ else Some((mods, name, tparams, ctorMods, vparamss, earlyDefs, parents, selfType, body))
case _ =>
None
}
diff --git a/src/reflect/scala/reflect/internal/Scopes.scala b/src/reflect/scala/reflect/internal/Scopes.scala
index 19804fc5f3..51fb31d36d 100644
--- a/src/reflect/scala/reflect/internal/Scopes.scala
+++ b/src/reflect/scala/reflect/internal/Scopes.scala
@@ -298,7 +298,7 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
var e = lookupEntry(original.name.companionName)
while (e != null) {
// 1) Must be owned by the same Scope, to ensure that in
- // `{ class C; { ...; object C } }`, the class is not seen as a comaniopn of the object.
+ // `{ class C; { ...; object C } }`, the class is not seen as a companion of the object.
// 2) Must be a class and module symbol, so that `{ class C; def C }` or `{ type T; object T }` are not companions.
def isClassAndModule(sym1: Symbol, sym2: Symbol) = sym1.isClass && sym2.isModule
if ((e.owner eq entry.owner) && (isClassAndModule(original, e.sym) || isClassAndModule(e.sym, original))) {
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index ad7e3ffe8f..2a0fb5298b 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -309,6 +309,9 @@ trait Types
/** Is this type completed (i.e. not a lazy type)? */
def isComplete: Boolean = true
+ /** Should this be printed as an infix type (@showAsInfix class &&[T, U])? */
+ def isShowAsInfixType: Boolean = false
+
/** If this is a lazy type, assign a new type to `sym`. */
def complete(sym: Symbol) {}
@@ -2102,6 +2105,15 @@ trait Types
trivial = fromBoolean(!sym.isTypeParameter && pre.isTrivial && areTrivialTypes(args))
toBoolean(trivial)
}
+
+ /* It only makes sense to show 2-ary type constructors infix.
+ * By default we do only if it's a symbolic name. */
+ override def isShowAsInfixType: Boolean =
+ hasLength(args, 2) &&
+ sym.getAnnotation(ShowAsInfixAnnotationClass)
+ .map(_ booleanArg 0 getOrElse true)
+ .getOrElse(!Character.isUnicodeIdentifierStart(sym.decodedName.head))
+
private[Types] def invalidateTypeRefCaches(): Unit = {
parentsCache = null
parentsPeriod = NoPeriod
@@ -2327,6 +2339,22 @@ trait Types
case arg :: Nil => s"($arg,)"
case _ => args.mkString("(", ", ", ")")
}
+ private def infixTypeString: String = {
+ /* SLS 3.2.8: all infix types have the same precedence.
+ * In A op B op' C, op and op' need the same associativity.
+ * Therefore, if op is left associative, anything on its right
+ * needs to be parenthesized if it's an infix type, and vice versa. */
+ // we should only get here after `isShowInfixType` says we have 2 args
+ val l :: r :: Nil = args
+
+ val isRightAssoc = typeSymbol.decodedName endsWith ":"
+
+ val lstr = if (isRightAssoc && l.isShowAsInfixType) s"($l)" else l.toString
+
+ val rstr = if (!isRightAssoc && r.isShowAsInfixType) s"($r)" else r.toString
+
+ s"$lstr ${sym.decodedName} $rstr"
+ }
private def customToString = sym match {
case RepeatedParamClass | JavaRepeatedParamClass => args.head + "*"
case ByNameParamClass => "=> " + args.head
@@ -2350,6 +2378,8 @@ trait Types
xs.init.mkString("(", ", ", ")") + " => " + xs.last
}
}
+ else if (isShowAsInfixType)
+ infixTypeString
else if (isTupleTypeDirect(this))
tupleTypeString
else if (sym.isAliasType && prefixChain.exists(_.termSymbol.isSynthetic) && (this ne dealias))
@@ -4152,7 +4182,7 @@ trait Types
* The specification-enumerated non-value types are method types, polymorphic
* method types, and type constructors. Supplements to the specified set of
* non-value types include: types which wrap non-value symbols (packages
- * abd statics), overloaded types. Varargs and by-name types T* and (=>T) are
+ * and statics), overloaded types. Varargs and by-name types T* and (=>T) are
* not designated non-value types because there is code which depends on using
* them as type arguments, but their precise status is unclear.
*/
@@ -4251,7 +4281,7 @@ trait Types
case mt1 @ MethodType(params1, res1) =>
tp2 match {
case mt2 @ MethodType(params2, res2) =>
- // sameLength(params1, params2) was used directly as pre-screening optimization (now done by matchesQuantified -- is that ok, performancewise?)
+ // sameLength(params1, params2) was used directly as pre-screening optimization (now done by matchesQuantified -- is that ok, performance-wise?)
mt1.isImplicit == mt2.isImplicit &&
matchingParams(params1, params2, mt1.isJava, mt2.isJava) &&
matchesQuantified(params1, params2, res1, res2)
@@ -4696,7 +4726,7 @@ trait Types
case _ => Depth(1)
}
- //OPT replaced with tailrecursive function to save on #closures
+ //OPT replaced with tail recursive function to save on #closures
// was:
// var d = 0
// for (tp <- tps) d = d max by(tp) //!!!OPT!!!
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index fe1de91662..08ccac8069 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -385,7 +385,7 @@ abstract class UnPickler {
// We're stuck with the order types are pickled in, but with judicious use
// of named parameters we can recapture a declarative flavor in a few cases.
- // But it's still a rat's nest of adhockery.
+ // But it's still a rat's nest of ad-hockery.
(tag: @switch) match {
case NOtpe => NoType
case NOPREFIXtpe => NoPrefix
diff --git a/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala b/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala
index 108ce45cca..6d9a9d6649 100644
--- a/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala
+++ b/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala
@@ -136,7 +136,7 @@ private[internal] trait GlbLubs {
mergePrefixAndArgs(ts1, Covariant, depth) match {
case NoType => loop(pretypes, tails)
case tp if strictInference && willViolateRecursiveBounds(tp, ts0, ts1) =>
- log(s"Breaking recursion in lublist, advancing frontier and discaring merged prefix/args from $tp")
+ log(s"Breaking recursion in lublist, advancing frontier and discarding merged prefix/args from $tp")
loop(pretypes, tails)
case tp =>
loop(tp :: pretypes, tails)
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
index cf274f24bb..990092b749 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
@@ -404,7 +404,7 @@ trait TypeComparers {
sym2.isClass && {
val base = tr1 baseType sym2
// During bootstrap, `base eq NoType` occurs about 2.5 times as often as `base ne NoType`.
- // The extra check seems like a worthwhile optimization (about 2.5M useless calls to isSubtype saved during that run).
+ // The extra check seems like a worthwhile optimization (about 2.5M useless calls to isSubType saved during that run).
(base ne tr1) && (base ne NoType) && isSubType(base, tr2, depth)
}
||
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala b/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala
index e321a07f51..2697824fd5 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeConstraints.scala
@@ -25,7 +25,7 @@ private[internal] trait TypeConstraints {
// register with the auto-clearing cache manager
perRunCaches.recordCache(this)
- /** Undo all changes to constraints to type variables upto `limit`. */
+ /** Undo all changes to constraints to type variables up to `limit`. */
//OPT this method is public so we can do `manual inlining`
def undoTo(limit: UndoPairs) {
assertCorrectThread()
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
index de065d0b5d..0601067d26 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
@@ -312,7 +312,7 @@ private[internal] trait TypeMaps {
* the corresponding class file might still not be read, so we do not
* know what the type parameters of the type are. Therefore
* the conversion of raw types to existential types might not have taken place
- * in ClassFileparser.sigToType (where it is usually done).
+ * in ClassFileParser.sigToType (where it is usually done).
*/
def rawToExistential = new TypeMap {
private var expanded = immutable.Set[Symbol]()
@@ -404,7 +404,7 @@ private[internal] trait TypeMaps {
case _ => super.mapOver(tp)
}
- // Do not discard the types of existential ident's. The
+ // Do not discard the types of existential idents. The
// symbol of the Ident itself cannot be listed in the
// existential's parameters, so the resulting existential
// type would be ill-formed.
@@ -504,7 +504,7 @@ private[internal] trait TypeMaps {
&& isBaseClassOfEnclosingClass(sym.owner)
)
- private var capturedThisIds= 0
+ private var capturedThisIds = 0
private def nextCapturedThisId() = { capturedThisIds += 1; capturedThisIds }
/** Creates an existential representing a type parameter which appears
* in the prefix of a ThisType.
diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala
index e2f1e74740..24f8aa88e6 100644
--- a/src/reflect/scala/reflect/internal/transform/Erasure.scala
+++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala
@@ -19,7 +19,7 @@ trait Erasure {
/* A Java Array<T> is erased to Array[Object] (T can only be a reference type), where as a Scala Array[T] is
* erased to Object. However, there is only symbol for the Array class. So to make the distinction between
* a Java and a Scala array, we check if the owner of T comes from a Java class.
- * This however caused issue SI-5654. The additional test for EXSITENTIAL fixes it, see the ticket comments.
+ * This however caused issue SI-5654. The additional test for EXISTENTIAL fixes it, see the ticket comments.
* In short, members of an existential type (e.g. `T` in `forSome { type T }`) can have pretty arbitrary
* owners (e.g. when computing lubs, <root> is used). All packageClass symbols have `isJavaDefined == true`.
*/
diff --git a/src/reflect/scala/reflect/internal/util/Statistics.scala b/src/reflect/scala/reflect/internal/util/Statistics.scala
index 905f1bf26e..2d623f3367 100644
--- a/src/reflect/scala/reflect/internal/util/Statistics.scala
+++ b/src/reflect/scala/reflect/internal/util/Statistics.scala
@@ -78,7 +78,7 @@ object Statistics {
/** Create a new stackable that shows as `prefix` and is active
* in the same phases as its base timer. Stackable timers are subtimers
- * that can be stacked ina timerstack, and that print aggregate, as well as specific
+ * that can be stacked in a timerstack, and that print aggregate, as well as specific
* durations.
*/
def newStackableTimer(prefix: String, timer: Timer): StackableTimer = new StackableTimer(prefix, timer)
diff --git a/src/reflect/scala/reflect/internal/util/StringOps.scala b/src/reflect/scala/reflect/internal/util/StringOps.scala
index 79195e6eab..2fee6b0f82 100644
--- a/src/reflect/scala/reflect/internal/util/StringOps.scala
+++ b/src/reflect/scala/reflect/internal/util/StringOps.scala
@@ -11,7 +11,7 @@ package reflect
package internal
package util
-import scala.compat.Platform.EOL
+import java.lang.System.{lineSeparator => EOL}
/** This object provides utility methods to extract elements
* from Strings.
@@ -45,7 +45,7 @@ trait StringOps {
else s.substring(0, end)
}
/** Breaks the string into lines and strips each line before reassembling. */
- def trimAllTrailingSpace(s: String): String = s.lines map trimTrailingSpace mkString EOL
+ def trimAllTrailingSpace(s: String): String = s.lines.map(trimTrailingSpace).mkString(EOL)
def decompose(str: String, sep: Char): List[String] = {
def ws(start: Int): List[String] =
@@ -69,18 +69,17 @@ trait StringOps {
else Some((str take idx, str drop (if (doDropIndex) idx + 1 else idx)))
/** Returns a string meaning "n elements".
+ * Don't try an element such as "index" with irregular plural.
*/
- def countElementsAsString(n: Int, elements: String): String =
+ def countElementsAsString(n: Int, element: String): String =
n match {
- case 0 => s"no ${elements}s"
- case 1 => "one " + elements
- case 2 => "two " + elements + "s"
- case 3 => "three " + elements + "s"
- case 4 => "four " + elements + "s"
- case _ => s"$n ${elements}s"
+ case 0 => s"no ${element}s"
+ case 1 => s"one ${element}"
+ case _ => s"${countAsString(n)} ${element}s"
}
/** Turns a count into a friendly English description if n<=4.
+ * Otherwise, a scary math representation.
*/
def countAsString(n: Int): String =
n match {
@@ -89,8 +88,8 @@ trait StringOps {
case 2 => "two"
case 3 => "three"
case 4 => "four"
- case _ => "" + n
+ case _ => n.toString
}
}
-object StringOps extends StringOps { }
+object StringOps extends StringOps
diff --git a/src/reflect/scala/reflect/io/Path.scala b/src/reflect/scala/reflect/io/Path.scala
index 5f93506015..c5b5ae24ba 100644
--- a/src/reflect/scala/reflect/io/Path.scala
+++ b/src/reflect/scala/reflect/io/Path.scala
@@ -107,19 +107,20 @@ class Path private[io] (val jfile: JFile) {
def /(child: Directory): Directory = /(child: Path).toDirectory
def /(child: File): File = /(child: Path).toFile
- /** If this path is a container, recursively iterate over its contents.
+ /** If this path is a directory, recursively iterate over its contents.
* The supplied condition is a filter which is applied to each element,
- * with that branch of the tree being closed off if it is true. So for
- * example if the condition is true for some subdirectory, nothing
- * under that directory will be in the Iterator; but otherwise each
- * file and subdirectory underneath it will appear.
+ * with that branch of the tree being closed off if it is false.
+ * So for example if the condition is false for some subdirectory, nothing
+ * under that directory will be in the Iterator. If it's true, all files for
+ * which the condition holds and are directly in that subdirectory are in the
+ * Iterator, and all sub-subdirectories are recursively evaluated
*/
def walkFilter(cond: Path => Boolean): Iterator[Path] =
if (isFile) toFile walkFilter cond
else if (isDirectory) toDirectory walkFilter cond
else Iterator.empty
- /** Equivalent to walkFilter(_ => false).
+ /** Equivalent to walkFilter(_ => true).
*/
def walk: Iterator[Path] = walkFilter(_ => true)
diff --git a/src/reflect/scala/reflect/macros/blackbox/Context.scala b/src/reflect/scala/reflect/macros/blackbox/Context.scala
index ce28b5911e..205e3ad1c3 100644
--- a/src/reflect/scala/reflect/macros/blackbox/Context.scala
+++ b/src/reflect/scala/reflect/macros/blackbox/Context.scala
@@ -26,7 +26,7 @@ package blackbox
* Refer to the documentation of top-level traits in this package to learn the details.
*
* If a macro def refers to a macro impl that uses `blackbox.Context`, then this macro def becomes a blackbox macro,
- * which means that its expansion will be upcast to its return type, enforcing faithfullness of that macro to its
+ * which means that its expansion will be upcast to its return type, enforcing faithfulness of that macro to its
* type signature. Whitebox macros, i.e. the ones defined with `whitebox.Context`, aren't bound by this restriction,
* which enables a number of important use cases, but they are also going to enjoy less support than blackbox macros,
* so choose wisely. See the [[http://docs.scala-lang.org/overviews/macros/overview.html Macros Guide]] for more information.
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index 95d6662d14..9138ed3f02 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -429,6 +429,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.hijackedCoreClasses
definitions.symbolsNotPresentInBytecode
definitions.isPossibleSyntheticParent
+ definitions.ShowAsInfixAnnotationClass
definitions.abbrvTag
definitions.numericWeight
definitions.boxedModule
diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
index d1096fda4e..9635f320fe 100644
--- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
@@ -9,6 +9,7 @@ package interpreter
import scala.language.{ implicitConversions, existentials }
import scala.annotation.tailrec
import Predef.{ println => _, _ }
+import PartialFunction.{cond => when}
import interpreter.session._
import StdReplTags._
import scala.tools.asm.ClassReader
@@ -17,7 +18,7 @@ import scala.tools.nsc.util.{ ClassPath, stringFromStream }
import scala.reflect.classTag
import scala.reflect.internal.util.{ BatchSourceFile, ScalaClassLoader, NoPosition }
import ScalaClassLoader._
-import scala.reflect.io.File
+import scala.reflect.io.{Directory, File, Path}
import scala.tools.util._
import io.AbstractFile
import scala.concurrent.{ ExecutionContext, Await, Future }
@@ -26,6 +27,8 @@ import java.io.BufferedReader
import scala.util.{ Try, Success, Failure }
+import Completion._
+
/** The Scala interactive shell. It provides a read-eval-print loop
* around the Interpreter class.
* After instantiation, clients should call the main() method.
@@ -119,37 +122,6 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
intp = new ILoopInterpreter
}
- /** print a friendly help message */
- def helpCommand(line: String): Result = line match {
- case "" => helpSummary()
- case CommandMatch(cmd) => echo(f"%n${cmd.help}")
- case _ => ambiguousError(line)
- }
- private def helpSummary() = {
- val usageWidth = commands map (_.usageMsg.length) max
- val formatStr = s"%-${usageWidth}s %s"
-
- echo("All commands can be abbreviated, e.g., :he instead of :help.")
-
- for (cmd <- commands) echo(formatStr.format(cmd.usageMsg, cmd.help))
- }
- private def ambiguousError(cmd: String): Result = {
- matchingCommands(cmd) match {
- case Nil => echo(cmd + ": no such command. Type :help for help.")
- case xs => echo(cmd + " is ambiguous: did you mean " + xs.map(":" + _.name).mkString(" or ") + "?")
- }
- Result(keepRunning = true, None)
- }
- // this lets us add commands willy-nilly and only requires enough command to disambiguate
- private def matchingCommands(cmd: String) = commands filter (_.name startsWith cmd)
- private object CommandMatch {
- def unapply(name: String): Option[LoopCommand] =
- matchingCommands(name) match {
- case x :: Nil => Some(x)
- case xs => xs find (_.name == name) // accept an exact match
- }
- }
-
/** Show the history */
lazy val historyCommand = new LoopCommand("history", "show the history (optional num is commands to show)") {
override def usage = "[num]"
@@ -214,16 +186,16 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
cmd("implicits", "[-v]", "show the implicits in scope", intp.implicitsCommand),
cmd("javap", "<path|class>", "disassemble a file or class name", javapCommand),
cmd("line", "<id>|<line>", "place line(s) at the end of history", lineCommand),
- cmd("load", "<path>", "interpret lines in a file", loadCommand),
- cmd("paste", "[-raw] [path]", "enter paste mode or paste a file", pasteCommand),
+ cmd("load", "<path>", "interpret lines in a file", loadCommand, fileCompletion),
+ cmd("paste", "[-raw] [path]", "enter paste mode or paste a file", pasteCommand, fileCompletion),
nullary("power", "enable power user mode", powerCmd),
nullary("quit", "exit the interpreter", () => Result(keepRunning = false, None)),
- cmd("replay", "[options]", "reset the repl and replay all previous commands", replayCommand),
+ cmd("replay", "[options]", "reset the repl and replay all previous commands", replayCommand, settingsCompletion),
cmd("require", "<path>", "add a jar to the classpath", require),
- cmd("reset", "[options]", "reset the repl to its initial state, forgetting all session entries", resetCommand),
- cmd("save", "<path>", "save replayable session to a file", saveCommand),
+ cmd("reset", "[options]", "reset the repl to its initial state, forgetting all session entries", resetCommand, settingsCompletion),
+ cmd("save", "<path>", "save replayable session to a file", saveCommand, fileCompletion),
shCommand,
- cmd("settings", "<options>", "update compiler options, if possible; see reset", changeSettings),
+ cmd("settings", "<options>", "update compiler options, if possible; see reset", changeSettings, settingsCompletion),
nullary("silent", "disable/enable automatic printing of results", verbosity),
cmd("type", "[-v] <expr>", "display the type of an expression without evaluating it", typeCommand),
cmd("kind", "[-v] <expr>", "display the kind of expression's type", kindCommand),
@@ -235,6 +207,46 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
cmd("phase", "<phase>", "set the implicit phase for power commands", phaseCommand)
)
+ // complete filename
+ val fileCompletion: Completion = new Completion {
+ def resetVerbosity(): Unit = ()
+ val emptyWord = """(\s+)$""".r.unanchored
+ val directorily = """(\S*/)$""".r.unanchored
+ val trailingWord = """(\S+)$""".r.unanchored
+ def listed(i: Int, dir: Option[Path]) =
+ dir.filter(_.isDirectory).map(d => Candidates(i, d.toDirectory.list.map(_.name).toList)).getOrElse(NoCandidates)
+ def listedIn(dir: Directory, name: String) = dir.list.filter(_.name.startsWith(name)).map(_.name).toList
+ def complete(buffer: String, cursor: Int): Candidates =
+ buffer.substring(0, cursor) match {
+ case emptyWord(s) => listed(cursor, Directory.Current)
+ case directorily(s) => listed(cursor, Option(Path(s)))
+ case trailingWord(s) =>
+ val f = File(s)
+ val (i, maybes) =
+ if (f.isFile) (cursor - s.length, List(f.toAbsolute.path))
+ else if (f.isDirectory) (cursor - s.length, List(s"${f.toAbsolute.path}/"))
+ else if (f.parent.exists) (cursor - f.name.length, listedIn(f.parent.toDirectory, f.name))
+ else (-1, Nil)
+ if (maybes.isEmpty) NoCandidates else Candidates(i, maybes)
+ case _ => NoCandidates
+ }
+ }
+
+ // complete settings name
+ val settingsCompletion: Completion = new Completion {
+ def resetVerbosity(): Unit = ()
+ val trailingWord = """(\S+)$""".r.unanchored
+ def complete(buffer: String, cursor: Int): Candidates = {
+ buffer.substring(0, cursor) match {
+ case trailingWord(s) =>
+ val maybes = settings.visibleSettings.filter(_.name.startsWith(s)).map(_.name)
+ .filterNot(when(_) { case "-"|"-X"|"-Y" => true }).toList.sorted
+ if (maybes.isEmpty) NoCandidates else Candidates(cursor - s.length, maybes)
+ case _ => NoCandidates
+ }
+ }
+ }
+
private def importsCommand(line: String): Result = {
val tokens = words(line)
val handlers = intp.languageWildcardHandlers ++ intp.importHandlers
@@ -681,20 +693,11 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
* (1) whether to keep running, (2) the line to record for replay, if any.
*/
def command(line: String): Result = {
- if (line startsWith ":") colonCommand(line.tail)
+ if (line startsWith ":") colonCommand(line)
else if (intp.global == null) Result(keepRunning = false, None) // Notice failure to create compiler
else Result(keepRunning = true, interpretStartingWith(line))
}
- private val commandish = """(\S+)(?:\s+)?(.*)""".r
-
- private def colonCommand(line: String): Result = line.trim match {
- case "" => helpSummary()
- case commandish(CommandMatch(cmd), rest) => cmd(rest)
- case commandish(name, _) => ambiguousError(name)
- case _ => echo("?")
- }
-
private def readWhile(cond: String => Boolean) = {
Iterator continually in.readLine("") takeWhile (x => x != null && cond(x))
}
@@ -849,6 +852,18 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
}
+ // delegate to command completion or presentation compiler
+ class ReplCompletion(intp: IMain) extends Completion {
+ val pc = new PresentationCompilerCompleter(intp)
+ def resetVerbosity(): Unit = pc.resetVerbosity()
+ def complete(buffer: String, cursor: Int): Completion.Candidates = {
+ if (buffer.startsWith(":"))
+ colonCompletion(buffer, cursor).complete(buffer, cursor)
+ else
+ pc.complete(buffer, cursor)
+ }
+ }
+
/** Tries to create a jline.InteractiveReader, falling back to SimpleReader,
* unless settings or properties are such that it should start with SimpleReader.
* The constructor of the InteractiveReader must take a Completion strategy,
@@ -868,7 +883,7 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
def mkReader(maker: ReaderMaker) = maker { () =>
- if (settings.noCompletion) NoCompletion else new PresentationCompilerCompleter(intp)
+ if (settings.noCompletion) NoCompletion else new ReplCompletion(intp)
}
def internalClass(kind: String) = s"scala.tools.nsc.interpreter.$kind.InteractiveReader"
@@ -1014,6 +1029,7 @@ object ILoop {
// like if you'd just typed it into the repl.
def runForTranscript(code: String, settings: Settings, inSession: Boolean = false): String = {
import java.io.{ BufferedReader, StringReader, OutputStreamWriter }
+ import java.lang.System.{lineSeparator => EOL}
stringFromStream { ostream =>
Console.withOut(ostream) {
@@ -1021,10 +1037,9 @@ object ILoop {
// skip margin prefix for continuation lines, unless preserving session text for test
// should test for repl.paste.ContinueString or replProps.continueText.contains(ch)
override def write(str: String) =
- if (!inSession && (str forall (ch => ch.isWhitespace || ch == '|'))) ()
- else super.write(str)
+ if (inSession || (str.exists(ch => ch != ' ' && ch != '|'))) super.write(str)
}
- val input = new BufferedReader(new StringReader(code.trim + "\n")) {
+ val input = new BufferedReader(new StringReader(s"${code.trim}${EOL}")) {
override def readLine(): String = {
mark(1) // default buffer is 8k
val c = read()
diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala
index 980d12f9b8..a351d2da95 100644
--- a/src/repl/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala
@@ -1105,7 +1105,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
def apply(line: String): Result = debugging(s"""parse("$line")""") {
var isIncomplete = false
- def parse = {
+ def parse = withoutWarnings {
reporter.reset()
val trees = newUnitParser(line, label).parseStats()
if (reporter.hasErrors) Error(trees)
diff --git a/src/repl/scala/tools/nsc/interpreter/LoopCommands.scala b/src/repl/scala/tools/nsc/interpreter/LoopCommands.scala
index 8c3b174513..a2ce63996b 100644
--- a/src/repl/scala/tools/nsc/interpreter/LoopCommands.scala
+++ b/src/repl/scala/tools/nsc/interpreter/LoopCommands.scala
@@ -24,18 +24,21 @@ class ProcessResult(val line: String) {
override def toString = "`%s` (%d lines, exit %d)".format(line, buffer.size, exitCode)
}
-trait LoopCommands {
+trait LoopCommands { self: { def echo(msg: String): Unit } =>
protected def out: JPrintWriter
// So outputs can be suppressed.
- def echoCommandMessage(msg: String): Unit = out println msg
+ def echoCommandMessage(msg: String): Unit = out.println(msg)
+
+ // available commands
+ def commands: List[LoopCommand]
// a single interpreter command
abstract class LoopCommand(val name: String, val help: String) extends (String => Result) {
def usage: String = ""
- def usageMsg: String = ":" + name + (
+ def usageMsg: String = s":$name${
if (usage == "") "" else " " + usage
- )
+ }"
def apply(line: String): Result
// called if no args are given
@@ -43,21 +46,88 @@ trait LoopCommands {
"usage is " + usageMsg
Result(keepRunning = true, None)
}
+
+ // subclasses may provide completions
+ def completion: Completion = NoCompletion
}
object LoopCommand {
def nullary(name: String, help: String, f: () => Result): LoopCommand =
new NullaryCmd(name, help, _ => f())
- def cmd(name: String, usage: String, help: String, f: String => Result): LoopCommand =
+ def cmd(name: String, usage: String, help: String, f: String => Result, completion: Completion = NoCompletion): LoopCommand =
if (usage == "") new NullaryCmd(name, help, f)
- else new LineCmd(name, usage, help, f)
+ else new LineCmd(name, usage, help, f, completion)
+ }
+
+ /** print a friendly help message */
+ def helpCommand(line: String): Result = line match {
+ case "" => helpSummary()
+ case CommandMatch(cmd) => echo(f"%n${cmd.help}")
+ case _ => ambiguousError(line)
+ }
+
+ def helpSummary() = {
+ val usageWidth = commands map (_.usageMsg.length) max
+ val formatStr = s"%-${usageWidth}s %s"
+
+ echo("All commands can be abbreviated, e.g., :he instead of :help.")
+
+ for (cmd <- commands) echo(formatStr.format(cmd.usageMsg, cmd.help))
+ }
+ def ambiguousError(cmd: String): Result = {
+ matchingCommands(cmd) match {
+ case Nil => echo(cmd + ": no such command. Type :help for help.")
+ case xs => echo(cmd + " is ambiguous: did you mean " + xs.map(":" + _.name).mkString(" or ") + "?")
+ }
+ Result(keepRunning = true, None)
+ }
+
+ // all commands with given prefix
+ private def matchingCommands(cmd: String) = commands.filter(_.name.startsWith(cmd.stripPrefix(":")))
+
+ // extract command from partial name, or prefer exact match if multiple matches
+ private object CommandMatch {
+ def unapply(name: String): Option[LoopCommand] =
+ matchingCommands(name) match {
+ case Nil => None
+ case x :: Nil => Some(x)
+ case xs => xs find (_.name == name)
+ }
+ }
+
+ // extract command name and rest of line
+ private val commandish = """(\S+)(?:\s+)?(.*)""".r
+
+ def colonCommand(line: String): Result = line.trim match {
+ case "" => helpSummary()
+ case commandish(CommandMatch(cmd), rest) => cmd(rest)
+ case commandish(name, _) => ambiguousError(name)
+ case _ => echo("?")
+ }
+
+ import Completion.Candidates
+
+ def colonCompletion(line: String, cursor: Int): Completion = line.trim match {
+ case commandish(name @ CommandMatch(cmd), rest) =>
+ if (name.length > cmd.name.length) cmd.completion
+ else
+ new Completion {
+ def resetVerbosity(): Unit = ()
+ def complete(buffer: String, cursor: Int) = Candidates(cursor - name.length + 1, List(cmd.name))
+ }
+ case commandish(name, _) if matchingCommands(name).nonEmpty =>
+ new Completion {
+ def resetVerbosity(): Unit = ()
+ def complete(buffer: String, cursor: Int) = Candidates(cursor - name.length + 1, matchingCommands(name).map(_.name))
+ }
+ case _ => NoCompletion
}
class NullaryCmd(name: String, help: String, f: String => Result) extends LoopCommand(name, help) {
def apply(line: String): Result = f(line)
}
- class LineCmd(name: String, argWord: String, help: String, f: String => Result) extends LoopCommand(name, help) {
+ class LineCmd(name: String, argWord: String, help: String, f: String => Result, override val completion: Completion) extends LoopCommand(name, help) {
override def usage = argWord
def apply(line: String): Result = f(line)
}
diff --git a/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala b/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala
index ac5fec80b3..7f4e52e88d 100644
--- a/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/base/comment/Body.scala
@@ -11,8 +11,9 @@ package comment
import scala.collection._
/** A body of text. A comment has a single body, which is composed of
- * at least one block. Inside every body is exactly one summary (see
- * [[scala.tools.nsc.doc.model.comment.Summary]]). */
+ * at least one block. Inside every body is exactly one summary.
+ * @see [[Summary]]
+ */
final case class Body(blocks: Seq[Block]) {
/** The summary text of the comment body. */
diff --git a/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala b/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala
index 5d0b6782bc..55527e43a1 100644
--- a/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/base/comment/Comment.scala
@@ -12,7 +12,7 @@ import scala.collection._
/** A Scaladoc comment and all its tags.
*
- * '''Note:''' the only instantiation site of this class is in [[CommentFactory]].
+ * '''Note:''' the only instantiation site of this class is in [[model.CommentFactory]].
*
* @author Manohar Jonnalagedda
* @author Gilles Dubochet */