summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala8
-rw-r--r--src/compiler/scala/tools/nsc/interactive/REPL.scala18
-rw-r--r--src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala24
-rw-r--r--src/compiler/scala/tools/nsc/scratchpad/Mixer.scala7
-rw-r--r--src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala23
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala8
-rw-r--r--src/library/scala/reflect/base/Exprs.scala10
-rw-r--r--src/library/scala/runtime/WorksheetSupport.scala20
-rw-r--r--src/library/scala/unchecked.scala42
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala42
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala4
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala1
-rw-r--r--src/reflect/scala/reflect/internal/util/HashSet.scala2
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala11
18 files changed, 156 insertions, 73 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index f681de93b6..a804cc92d3 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -932,7 +932,6 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
ca
}
- // TODO this method isn't exercised during bootstrapping. Open question: is it bug free?
private def arrEncode(sb: ScalaSigBytes): Array[String] = {
var strs: List[String] = Nil
val bSeven: Array[Byte] = sb.sevenBitsMayBeZero
@@ -941,14 +940,15 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
var offset = 0
var encLength = 0
while(offset < bSeven.size) {
- val newEncLength = encLength.toLong + (if(bSeven(offset) == 0) 2 else 1)
- if(newEncLength > 65535) {
+ val deltaEncLength = (if(bSeven(offset) == 0) 2 else 1)
+ val newEncLength = encLength.toLong + deltaEncLength
+ if(newEncLength >= 65535) {
val ba = bSeven.slice(prevOffset, offset)
strs ::= new java.lang.String(ubytesToCharArray(ba))
encLength = 0
prevOffset = offset
} else {
- encLength += 1
+ encLength += deltaEncLength
offset += 1
}
}
diff --git a/src/compiler/scala/tools/nsc/interactive/REPL.scala b/src/compiler/scala/tools/nsc/interactive/REPL.scala
index 6876ea14e0..65e7eb5fc6 100644
--- a/src/compiler/scala/tools/nsc/interactive/REPL.scala
+++ b/src/compiler/scala/tools/nsc/interactive/REPL.scala
@@ -124,9 +124,9 @@ object REPL {
* @param iContents An Array[Char] containing the instrumented source
* @return The name of the instrumented source file
*/
- def writeInstrumented(iFullName: String, iContents: Array[Char]): String = {
+ def writeInstrumented(iFullName: String, suffix: String, iContents: Array[Char]): String = {
val iSimpleName = iFullName drop ((iFullName lastIndexOf '.') + 1)
- val iSourceName = iSimpleName + "$instrumented.scala"
+ val iSourceName = iSimpleName + suffix
val ifile = new FileWriter(iSourceName)
ifile.write(iContents)
ifile.close()
@@ -186,18 +186,20 @@ object REPL {
* and outputs in the right column, or None if the presentation compiler
* does not respond to askInstrumented.
*/
- def instrument(arguments: List[String], line: Int): Option[String] = {
+ def instrument(arguments: List[String], line: Int): Option[(String, String)] = {
val source = toSourceFile(arguments.head)
// strip right hand side comment column and any trailing spaces from all lines
- val strippedSource = new BatchSourceFile(source.file, SourceInserter.stripRight(source.content))
+ val strippedContents = SourceInserter.stripRight(source.content)
+ val strippedSource = new BatchSourceFile(source.file, strippedContents)
println("stripped source = "+strippedSource)
comp.askReload(List(strippedSource), reloadResult)
comp.askInstrumented(strippedSource, line, instrumentedResult)
using(instrumentedResult) {
case (iFullName, iContents) =>
println(s"instrumented source $iFullName = ${iContents.mkString}")
- val iSourceName = writeInstrumented(iFullName, iContents)
- iSourceName
+ val iSourceName = writeInstrumented(iFullName, "$instrumented.scala", iContents)
+ val sSourceName = writeInstrumented(iFullName, "$stripped.scala", strippedContents)
+ (iSourceName, sSourceName)
/*
* val vdirOpt = compileInstrumented(iSourceName, arguments.tail)
runInstrumented(vdirOpt, iFullName, strippedSource.content)
@@ -227,9 +229,9 @@ object REPL {
case List("complete", file, off1) =>
doComplete(makePos(file, off1, off1))
case "instrument" :: arguments =>
- println(instrument(arguments, -1).map(_.mkString))
+ println(instrument(arguments, -1))
case "instrumentTo" :: line :: arguments =>
- println(instrument(arguments, line.toInt).map(_.mkString))
+ println(instrument(arguments, line.toInt))
case List("quit") =>
comp.askShutdown()
exit(1) // Don't use sys yet as this has to run on 2.8.2 also.
diff --git a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala b/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
index bd1869e1a4..efc393c812 100644
--- a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
+++ b/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
@@ -3,7 +3,7 @@ package interactive
import scala.reflect.internal.util.{SourceFile, BatchSourceFile, RangePosition}
import collection.mutable.ArrayBuffer
-import reflect.internal.Chars.isLineBreakChar
+import reflect.internal.Chars.{isLineBreakChar, isWhitespace}
trait ScratchPadMaker { self: Global =>
@@ -40,14 +40,28 @@ trait ScratchPadMaker { self: Global =>
toPrint.clear()
}
+ /** The position where to insert an instrumentation statement in front of giuven statement.
+ * This is at the latest `stat.pos.start`. But in order not to mess with column numbers
+ * in position we try to insert it at the end of the preceding line instead.
+ * To be safe, this can be done only if there's only whitespace between that position and
+ * statement's start position.
+ */
+ private def instrumentPos(stat: Tree): Int = {
+ var start = stat.pos.start
+ while (start > 0 && isWhitespace(contents(start - 1))) start -= 1
+ if (start > 0 && isLineBreakChar(contents(start - 1))) start -= 1
+ start
+ }
+
private def addSkip(stat: Tree): Unit = {
- if (stat.pos.start > skipped) applyPendingPatches(stat.pos.start)
+ val ipos = instrumentPos(stat)
+ if (stat.pos.start > skipped) applyPendingPatches(ipos)
if (stat.pos.start >= endOffset)
- patches += Patch(stat.pos.start, ";$stop()")
+ patches += Patch(ipos, ";$stop()")
var end = stat.pos.end
if (end > skipped) {
- while (end < contents.length && !(isLineBreakChar(contents(end)))) end += 1
- patches += Patch(stat.pos.start, ";$skip("+(end-skipped)+"); ")
+ while (end < contents.length && !isLineBreakChar(contents(end))) end += 1
+ patches += Patch(ipos, ";$skip("+(end-skipped)+"); ")
skipped = end
}
}
diff --git a/src/compiler/scala/tools/nsc/scratchpad/Mixer.scala b/src/compiler/scala/tools/nsc/scratchpad/Mixer.scala
index 46ccc32097..67ff916b11 100644
--- a/src/compiler/scala/tools/nsc/scratchpad/Mixer.scala
+++ b/src/compiler/scala/tools/nsc/scratchpad/Mixer.scala
@@ -23,7 +23,7 @@ class Mixer {
val nextSpace = comments indexOf (' ', idx)
var nextNL = comments indexOf ('\n', nextSpace + 1)
if (nextNL < 0) nextNL = comments.length
- val result =
+ val result =
(new String(comments.slice(idx, nextSpace)).toInt, comments.slice(nextSpace + 1, nextNL))
idx = nextNL + 1
result
@@ -46,7 +46,10 @@ class Mixer {
mixed += '\n'
col = 0
}
- mixed ++= (" " * (sepColumn - col))
+ while (col < sepColumn) {
+ mixed += ' '
+ col += 1
+ }
}
for ((offset, cs) <- parseComments(comments)) {
val sep =
diff --git a/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala b/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala
index 0991577829..ee26bb2817 100644
--- a/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala
+++ b/src/compiler/scala/tools/nsc/settings/StandardScalaSettings.scala
@@ -43,7 +43,7 @@ trait StandardScalaSettings {
val target = ChoiceSetting ("-target", "target", "Target platform for object files. All JVM 1.5 targets are deprecated.",
List("jvm-1.5", "jvm-1.5-fjbg", "jvm-1.5-asm", "jvm-1.6", "jvm-1.7", "msil"),
"jvm-1.6")
- val unchecked = BooleanSetting ("-unchecked", "Enable detailed unchecked (erasure) warnings.")
+ val unchecked = BooleanSetting ("-unchecked", "Enable additional warnings where generated code depends on assumptions.")
val uniqid = BooleanSetting ("-uniqid", "Uniquely tag all identifiers in debugging output.")
val usejavacp = BooleanSetting ("-usejavacp", "Utilize the java.class.path in classpath resolution.")
val verbose = BooleanSetting ("-verbose", "Output messages about what the compiler is doing.")
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index 1f7c34b8ad..f0979978b0 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -416,7 +416,7 @@ abstract class ExplicitOuter extends InfoTransform
val (checkExhaustive, requireSwitch) = nselector match {
case Typed(nselector1, tpt) =>
- val unchecked = treeInfo.isUncheckedAnnotation(tpt.tpe)
+ val unchecked = tpt.tpe hasAnnotation UncheckedClass
if (unchecked)
nselector = nselector1
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index e096b75d6d..3be4a46a79 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -1366,14 +1366,16 @@ trait Infer {
else if (param.isContravariant) >:>
else =:=
)
- val TypeRef(_, sym, args) = arg
-
- ( isLocalBinding(sym)
- || arg.typeSymbol.isTypeParameterOrSkolem
- || (sym.name == tpnme.WILDCARD) // avoid spurious warnings on HK types
- || check(arg, param.tpe, conforms)
- || warn("non-variable type argument " + arg)
- )
+ (arg hasAnnotation UncheckedClass) || {
+ val TypeRef(_, sym, args) = arg.withoutAnnotations
+
+ ( isLocalBinding(sym)
+ || arg.typeSymbol.isTypeParameterOrSkolem
+ || (sym.name == tpnme.WILDCARD) // avoid spurious warnings on HK types
+ || check(arg, param.tpe, conforms)
+ || warn("non-variable type argument " + arg)
+ )
+ }
}
// Checking if pt (the expected type of the pattern, and the type
@@ -1404,8 +1406,11 @@ trait Infer {
case _ =>
def where = ( if (inPattern) "pattern " else "" ) + typeToTest
if (check(typeToTest, typeEnsured, =:=)) ()
+ // Note that this is a regular warning, not an uncheckedWarning,
+ // which is now the province of such notifications as "pattern matcher
+ // exceeded its analysis budget."
else warningMessages foreach (m =>
- context.unit.uncheckedWarning(tree.pos, s"$m in type $where is unchecked since it is eliminated by erasure"))
+ context.unit.warning(tree.pos, s"$m in type $where is unchecked since it is eliminated by erasure"))
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
index a4457936c8..a8286c9f19 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
@@ -1228,7 +1228,7 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
if (settings.XnoPatmatAnalysis.value) (true, false)
else scrut match {
case Typed(_, tpt) =>
- (treeInfo.isUncheckedAnnotation(tpt.tpe),
+ (tpt.tpe hasAnnotation UncheckedClass,
// matches with two or fewer cases need not apply for switchiness (if-then-else will do)
treeInfo.isSwitchAnnotation(tpt.tpe) && casesNoSubstOnly.lengthCompare(2) > 0)
case _ =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 0895f5a421..d785988738 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2286,7 +2286,7 @@ trait Typers extends Modes with Adaptations with Tags {
// but not in real life (i.e., now that's we've reset the method's type skolems'
// infos back to their pre-GADT-constraint state)
if (isFullyDefined(pt) && !(body1.tpe <:< pt))
- body1 = typedPos(body1.pos)(gen.mkCast(body1, pt))
+ body1 = typedPos(body1.pos)(gen.mkCast(body1, pt.normalize))
}
@@ -3220,7 +3220,7 @@ trait Typers extends Modes with Adaptations with Tags {
// we don't create a new Context for a Match, so find the CaseDef, then go out one level and navigate back to the match that has this case
// val thisCase = context.nextEnclosing(_.tree.isInstanceOf[CaseDef])
// val unchecked = thisCase.outer.tree.collect{case Match(selector, cases) if cases contains thisCase => selector} match {
- // case List(Typed(_, tpt)) if treeInfo.isUncheckedAnnotation(tpt.tpe) => true
+ // case List(Typed(_, tpt)) if tpt.tpe hasAnnotation UncheckedClass => true
// case t => println("outer tree: "+ (t, thisCase, thisCase.outer.tree)); false
// }
// println("wrapClassTagUnapply"+ (!isPastTyper && infer.containsUnchecked(pt), pt, uncheckedPattern))
@@ -4522,7 +4522,9 @@ trait Typers extends Modes with Adaptations with Tags {
}) setType qual.tpe setPos qual.pos,
name)
case _ if accessibleError.isDefined =>
- val qual1 = adaptToMemberWithArgs(tree, qual, name, mode, false, false)
+ // don't adapt constructor, SI-6074
+ val qual1 = if (name == nme.CONSTRUCTOR) qual
+ else adaptToMemberWithArgs(tree, qual, name, mode, false, false)
if (!qual1.isErrorTyped && (qual1 ne qual))
typed(Select(qual1, name) setPos tree.pos, mode, pt)
else
diff --git a/src/library/scala/reflect/base/Exprs.scala b/src/library/scala/reflect/base/Exprs.scala
index 8e429afb21..ea975bba52 100644
--- a/src/library/scala/reflect/base/Exprs.scala
+++ b/src/library/scala/reflect/base/Exprs.scala
@@ -14,8 +14,8 @@ trait Exprs { self: Universe =>
def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # Expr[T]
def tree: Tree
- def staticTpe: Type
- def actualTpe: Type
+ def staticType: Type
+ def actualType: Type
def splice: T
val value: T
@@ -24,7 +24,7 @@ trait Exprs { self: Universe =>
override def canEqual(x: Any) = x.isInstanceOf[Expr[_]]
override def equals(x: Any) = x.isInstanceOf[Expr[_]] && this.mirror == x.asInstanceOf[Expr[_]].mirror && this.tree == x.asInstanceOf[Expr[_]].tree
override def hashCode = mirror.hashCode * 31 + tree.hashCode
- override def toString = "Expr["+staticTpe+"]("+tree+")"
+ override def toString = "Expr["+staticType+"]("+tree+")"
}
object Expr {
@@ -43,8 +43,8 @@ trait Exprs { self: Universe =>
// [Eugene++] this is important
// !!! remove when we have improved type inference for singletons
// search for .type] to find other instances
- lazy val staticTpe: Type = implicitly[AbsTypeTag[T]].tpe
- def actualTpe: Type = treeType(tree)
+ lazy val staticType: Type = implicitly[AbsTypeTag[T]].tpe
+ def actualType: Type = treeType(tree)
def splice: T = throw new UnsupportedOperationException("""
|the function you're calling has not been spliced by the compiler.
diff --git a/src/library/scala/runtime/WorksheetSupport.scala b/src/library/scala/runtime/WorksheetSupport.scala
index db6d6359a3..6f2a4d382d 100644
--- a/src/library/scala/runtime/WorksheetSupport.scala
+++ b/src/library/scala/runtime/WorksheetSupport.scala
@@ -14,9 +14,11 @@ object WorksheetSupport {
* By default it is 30ms.
*/
private class FlushedOutputStream(out: OutputStream) extends OutputStream {
+ protected def flushInterval = 30000000L // interval between flushes, by default 30ms
+ protected def width = 80 // output width, by default 80 characters
+ protected def tabInc = 8 // tab increment, by default 8 characters
private var lastFlush: Long = 0L
- protected val flushInterval = 30000000L // 30ms
- private var lastCh: Int = '\n'
+ private var col = -1
override def write(b: Array[Byte], off: Int, len: Int) = {
for (idx <- off until (off + len min b.length)) writeOne(b(idx))
flush()
@@ -33,14 +35,18 @@ object WorksheetSupport {
}
}
def writeOne(c: Int) {
- if (lastCh == '\n') {
- lastCh = 0
+ if (col < 0) {
+ col = 0
write((currentOffset+" ").getBytes)
}
out.write(c)
- lastCh = c
+ col =
+ if (c == '\n') -1
+ else if (c == '\t') (col / tabInc) * tabInc + tabInc
+ else col + 1
+ if (col >= width) writeOne('\n')
}
- def ensureNewLine() = if (lastCh != '\n') writeOne('\n')
+ def ensureNewLine() = if (col > 0) writeOne('\n')
}
private val flushedOut = new FlushedOutputStream(System.out)
@@ -69,7 +75,7 @@ object WorksheetSupport {
try op
catch {
case ex: StopException => ;
- case ex => ex.printStackTrace()
+ case ex: Throwable => ex.printStackTrace()
}
}
diff --git a/src/library/scala/unchecked.scala b/src/library/scala/unchecked.scala
index 10d34312cf..5b05792d97 100644
--- a/src/library/scala/unchecked.scala
+++ b/src/library/scala/unchecked.scala
@@ -6,32 +6,30 @@
** |/ **
\* */
-
-
package scala
-/** An annotation that gets applied to a selector in a match expression.
- * If it is present, exhaustiveness warnings for that expression will be
- * suppressed.
- * For example, compiling the code:
+/** An annotation to designate that the annotated entity
+ * should not be considered for additional compiler checks.
+ * Specific applications include annotating the subject of
+ * a match expression to suppress exhaustiveness warnings, and
+ * annotating a type argument in a match case to suppress
+ * unchecked warnings.
+ *
+ * Such suppression should be used with caution, without which
+ * one may encounter [[scala.MatchError]] or [[java.lang.ClassCastException]]
+ * at runtime. In most cases one can and should address the
+ * warning instead of suppressing it.
+ *
* {{{
- * object test extends App {
- * def f(x: Option[Int]) = x match {
- * case Some(y) => y
- * }
- * f(None)
+ * object Test extends App {
+ * // This would normally warn "match is not exhaustive"
+ * // because `None` is not covered.
+ * def f(x: Option[String]) = (x: @unchecked) match { case Some(y) => y }
+ * // This would normally warn "type pattern is unchecked"
+ * // but here will blindly cast the head element to String.
+ * def g(xs: Any) = xs match { case x: List[String @unchecked] => x.head }
* }
- * }}}
- * will display the following warning:
- * {{{
- * test.scala:2: warning: does not cover case {object None}
- * def f(x: Option[int]) = x match {
- * ^
- * one warning found
- * }}}
- * The above message may be suppressed by substituting the expression `x`
- * with `(x: @unchecked)`. Then the modified code will compile silently,
- * but, in any case, a [[scala.MatchError]] will be raised at runtime.
+ * }}}
*
* @since 2.4
*/
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index 13f5f743f1..2fa8ccc044 100644
--- a/src/reflect/scala/reflect/api/Symbols.scala
+++ b/src/reflect/scala/reflect/api/Symbols.scala
@@ -158,10 +158,22 @@ trait Symbols extends base.Symbols { self: Universe =>
*/
def isOverride: Boolean
+ /** Is this symbol labelled as "abstract override"?
+ */
+ def isAbstractOverride: Boolean
+
/** Is this symbol a macro?
*/
def isMacro: Boolean
+ /** Is this symbol a parameter (either a method parameter or a type parameter)?
+ */
+ def isParameter: Boolean
+
+ /** Is this symbol a specialized type parameter or a generated specialized member?
+ */
+ def isSpecialized: Boolean
+
/******************* helpers *******************/
/** ...
@@ -240,6 +252,25 @@ trait Symbols extends base.Symbols { self: Universe =>
/** Setter method for a backing field of a val or a val, NoSymbol for all other term symbols.
*/
def setter: Symbol
+
+ /** Does this symbol represent a field of a class
+ * that was generated from a parameter of that class?
+ */
+ def isParamAccessor: Boolean
+
+ /** Does this symbol represent a field of a case class
+ * that corresponds to a parameter in the first parameter list of the
+ * primary constructor of that class?
+ */
+ def isCaseAccessor: Boolean
+
+ /** Does this symbol represent a parameter with a default value?
+ */
+ def isParamWithDefault: Boolean
+
+ /** Does this symbol represent a by-name parameter?
+ */
+ def isByNameParam: Boolean
}
/** The API of type symbols */
@@ -275,6 +306,13 @@ trait Symbols extends base.Symbols { self: Universe =>
/** The API of method symbols */
trait MethodSymbolApi extends TermSymbolApi with MethodSymbolBase { this: MethodSymbol =>
+ /** Does this method represent a constructor?
+ *
+ * If `owner` is a class, then this is a vanilla JVM constructor.
+ * If `owner` is a trait, then this is a mixin constructor.
+ */
+ def isConstructor: Boolean
+
/** For a polymorphic method, its type parameters, the empty list for all other methods */
def typeParams: List[Symbol]
@@ -286,6 +324,10 @@ trait Symbols extends base.Symbols { self: Universe =>
*/
def params: List[List[Symbol]]
+ /** Does this method support variable length argument lists?
+ */
+ def isVarargs: Boolean
+
/** The return type of the method */
def returnType: Type
}
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index c356416112..9ae4302734 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -64,6 +64,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def kind: String = kindString
def isExistential: Boolean = this.isExistentiallyBound
+ def isParamWithDefault: Boolean = this.hasDefault
+ def isByNameParam: Boolean = this.isValueParameter && (this hasFlag BYNAMEPARAM)
def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match {
case n: TermName => newTermSymbol(n, pos, newFlags)
@@ -2496,6 +2498,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def params: List[List[Symbol]] = paramss
+ override def isVarargs: Boolean = definitions.isVarArgsList(paramss.flatten)
+
override def returnType: Type = {
def loop(tpe: Type): Type =
tpe match {
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 17a01e1af9..f6b004f985 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -326,9 +326,6 @@ abstract class TreeInfo {
case _ => false
}
- /** a Match(Typed(_, tpt), _) is unchecked if isUncheckedAnnotation(tpt.tpe) */
- def isUncheckedAnnotation(tpe: Type) = tpe hasAnnotation definitions.UncheckedClass
-
/** a Match(Typed(_, tpt), _) must be translated into a switch if isSwitchAnnotation(tpt.tpe) */
def isSwitchAnnotation(tpe: Type) = tpe hasAnnotation definitions.SwitchClass
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 442a91774d..386d2896be 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -3822,6 +3822,7 @@ trait Types extends api.Types { self: SymbolTable =>
Statistics.incCounter(rawTypeCount)
if (uniqueRunId != currentRunId) {
uniques = util.HashSet[Type]("uniques", initialUniquesCapacity)
+ perRunCaches.recordCache(uniques)
uniqueRunId = currentRunId
}
(uniques findEntryOrUpdate tp).asInstanceOf[T]
diff --git a/src/reflect/scala/reflect/internal/util/HashSet.scala b/src/reflect/scala/reflect/internal/util/HashSet.scala
index a771dad2b0..cd1fe2e9f3 100644
--- a/src/reflect/scala/reflect/internal/util/HashSet.scala
+++ b/src/reflect/scala/reflect/internal/util/HashSet.scala
@@ -13,7 +13,7 @@ object HashSet {
new HashSet[T](label, initialCapacity)
}
-class HashSet[T >: Null <: AnyRef](val label: String, initialCapacity: Int) extends Set[T] {
+class HashSet[T >: Null <: AnyRef](val label: String, initialCapacity: Int) extends Set[T] with collection.generic.Clearable {
private var used = 0
private var table = new Array[AnyRef](initialCapacity)
private def index(x: Int): Int = math.abs(x % table.length)
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 64c47a5502..5eb7770de6 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -777,7 +777,16 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
lookupClass
else if (jclazz.isLocalClass0 || isInvalidClassName(jname))
// local classes and implementation classes not preserved by unpickling - treat as Java
- jclassAsScala(jclazz)
+ //
+ // upd. but only if they cannot be loaded as top-level classes
+ // otherwise we may mistake mangled symbolic names for mangled nested names
+ //
+ // in case when a Java binary name can be treated both as a top-level class and as a nested class
+ // (as described in http://groups.google.com/group/scala-internals/browse_thread/thread/10855403bbf04298)
+ // we check for a top-level class first
+ // this is totally correct, because a top-level class and a nested class with the same name cannot coexist
+ // so it's either one or another, but not both - therefore we always load $-bearing classes correctly
+ lookupClass orElse jclassAsScala(jclazz)
else if (jclazz.isArray)
ArrayClass
else