summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/macros/util/Helpers.scala6
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala62
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Scanners.scala7
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala13
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala4
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala27
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala5
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala9
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala24
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala28
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala27
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala52
-rw-r--r--src/eclipse/README.md3
-rw-r--r--src/eclipse/test-junit/.classpath12
-rw-r--r--src/eclipse/test-junit/.project35
-rw-r--r--src/library/scala/Option.scala4
-rw-r--r--src/library/scala/Predef.scala31
-rw-r--r--src/library/scala/annotation/cloneable.scala15
-rw-r--r--src/library/scala/collection/concurrent/TrieMap.scala7
-rw-r--r--src/library/scala/collection/immutable/Range.scala3
-rw-r--r--src/library/scala/collection/immutable/StringLike.scala21
-rw-r--r--src/library/scala/concurrent/duration/Duration.scala36
-rw-r--r--src/library/scala/util/Properties.scala3
-rw-r--r--src/partest/scala/tools/partest/BytecodeTest.scala35
-rw-r--r--src/partest/scala/tools/partest/DirectTest.scala27
-rw-r--r--src/partest/scala/tools/partest/nest/Runner.scala3
-rw-r--r--src/partest/scala/tools/partest/utils/Properties.scala1
-rw-r--r--src/reflect/scala/reflect/internal/BaseTypeSeqs.scala9
-rw-r--r--src/reflect/scala/reflect/internal/CapturedVariables.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala48
-rw-r--r--src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala6
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala3
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala22
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala7
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala78
-rw-r--r--src/reflect/scala/reflect/internal/tpe/GlbLubs.scala4
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala13
-rw-r--r--src/repl/scala/tools/nsc/interpreter/ILoop.scala9
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala6
-rw-r--r--src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala8
43 files changed, 460 insertions, 266 deletions
diff --git a/src/compiler/scala/reflect/macros/util/Helpers.scala b/src/compiler/scala/reflect/macros/util/Helpers.scala
index ada8efa833..9b7680717e 100644
--- a/src/compiler/scala/reflect/macros/util/Helpers.scala
+++ b/src/compiler/scala/reflect/macros/util/Helpers.scala
@@ -54,7 +54,7 @@ trait Helpers {
*
* @see Metalevels.scala for more information and examples about metalevels
*/
- def increaseMetalevel(pre: Type, tp: Type): Type = dealiasAndRewrap(tp) {
+ def increaseMetalevel(pre: Type, tp: Type): Type = transparentShallowTransform(RepeatedParamClass, tp) {
case tp => typeRef(pre, MacroContextExprClass, List(tp))
}
@@ -64,8 +64,8 @@ trait Helpers {
*
* @see Metalevels.scala for more information and examples about metalevels
*/
- def decreaseMetalevel(tp: Type): Type = dealiasAndRewrap(tp) {
+ def decreaseMetalevel(tp: Type): Type = transparentShallowTransform(RepeatedParamClass, tp) {
case ExprClassOf(runtimeType) => runtimeType
- case _ => AnyClass.tpe // so that macro impls with rhs = ??? don't screw up our inference
+ case _ => AnyTpe // so that macro impls with rhs = ??? don't screw up our inference
}
} \ No newline at end of file
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index a08633ffc8..eafe03d5cd 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -1060,14 +1060,12 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
@inline final def enteringTyper[T](op: => T): T = enteringPhase(currentRun.typerPhase)(op)
@inline final def enteringUncurry[T](op: => T): T = enteringPhase(currentRun.uncurryPhase)(op)
- // Owners up to and including the first package class.
+ // Owners which aren't package classes.
private def ownerChainString(sym: Symbol): String = (
if (sym == null) ""
- else sym.ownerChain.span(!_.isPackageClass) match {
- case (xs, pkg :: _) => (xs :+ pkg) mkString " -> "
- case _ => sym.ownerChain mkString " -> " // unlikely
- }
+ else sym.ownerChain takeWhile (!_.isPackageClass) mkString " -> "
)
+
private def formatExplain(pairs: (String, Any)*): String = (
pairs.toList collect { case (k, v) if v != null => "%20s: %s".format(k, v) } mkString "\n"
)
@@ -1075,41 +1073,45 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** Don't want to introduce new errors trying to report errors,
* so swallow exceptions.
*/
- override def supplementErrorMessage(errorMessage: String): String =
+ override def supplementErrorMessage(errorMessage: String): String = {
if (currentRun.supplementedError) errorMessage
else try {
+ currentRun.supplementedError = true
val tree = analyzer.lastTreeToTyper
val sym = tree.symbol
val tpe = tree.tpe
- val enclosing = lastSeenContext.enclClassOrMethod.tree
+ 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 {
+ // 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 strs = xs.zipWithIndex map { case (line, idx) => f"${start + idx}%6d $line" }
+ strs.mkString("== Source file context for tree position ==\n\n", "\n", "")
+ }
+ catch { case t: Exception => devWarning("" + t) ; "<Cannot read source file>" }
val info1 = formatExplain(
"while compiling" -> currentSource.path,
- "during phase" -> ( if (globalPhase eq phase) phase else "global=%s, enteringPhase=%s".format(globalPhase, phase) ),
+ "during phase" -> ( if (globalPhase eq phase) phase else "globalPhase=%s, enteringPhase=%s".format(globalPhase, phase) ),
"library version" -> scala.util.Properties.versionString,
"compiler version" -> Properties.versionString,
"reconstructed args" -> settings.recreateArgs.mkString(" ")
)
val info2 = formatExplain(
"last tree to typer" -> tree.summaryString,
+ "tree position" -> pos_s,
+ "tree tpe" -> tpe,
"symbol" -> Option(sym).fold("null")(_.debugLocationString),
- "symbol definition" -> Option(sym).fold("null")(_.defString),
- "tpe" -> tpe,
+ "symbol definition" -> Option(sym).fold("null")(s => s.defString + s" (a ${s.shortSymbolClass})"),
+ "symbol package" -> sym.enclosingPackage.fullName,
"symbol owners" -> ownerChainString(sym),
- "context owners" -> ownerChainString(lastSeenContext.owner)
+ "call site" -> (site.fullLocationString + " in " + site.enclosingPackage)
)
- val info3: List[String] = (
- ( List("== Enclosing template or block ==", nodePrinters.nodeToString(enclosing).trim) )
- ++ ( if (tpe eq null) Nil else List("== Expanded type of tree ==", typeDeconstruct.show(tpe)) )
- ++ ( if (!settings.debug) Nil else List("== Current unit body ==", nodePrinters.nodeToString(currentUnit.body)) )
- ++ ( List(errorMessage) )
- )
-
- currentRun.supplementedError = true
-
- ("\n" + info1) :: info2 :: info3 mkString "\n\n"
+ ("\n" + info1) :: info2 :: context_s :: Nil mkString "\n\n"
}
catch { case _: Exception | _: TypeError => errorMessage }
+ }
/** The id of the currently active run
*/
@@ -1393,9 +1395,13 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
def registerPickle(sym: Symbol): Unit = ()
/** does this run compile given class, module, or case factory? */
+ // NOTE: Early initialized members temporarily typechecked before the enclosing class, see typedPrimaryConstrBody!
+ // Here we work around that wrinkle by claiming that a top-level, early-initialized member is compiled in
+ // *every* run. This approximation works because this method is exclusively called with `this` == `currentRun`.
def compiles(sym: Symbol): Boolean =
if (sym == NoSymbol) false
else if (symSource.isDefinedAt(sym)) true
+ else if (sym.isTopLevel && sym.isEarlyInitialized) true
else if (!sym.isTopLevel) compiles(sym.enclosingTopLevelClass)
else if (sym.isModuleClass) compiles(sym.sourceModule)
else false
@@ -1493,18 +1499,8 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
compileUnits(sources map (new CompilationUnit(_)), firstPhase)
}
- def compileUnits(units: List[CompilationUnit], fromPhase: Phase) {
- try compileUnitsInternal(units, fromPhase)
- catch { case ex: Throwable =>
- val shown = if (settings.verbose)
- stackTraceString(ex)
- else
- stackTraceHeadString(ex) // note that error stacktraces do not print in fsc
-
- globalError(supplementErrorMessage("uncaught exception during compilation: " + shown))
- throw ex
- }
- }
+ def compileUnits(units: List[CompilationUnit], fromPhase: Phase): Unit =
+ compileUnitsInternal(units, fromPhase)
private def compileUnitsInternal(units: List[CompilationUnit], fromPhase: Phase) {
doInvalidation()
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 8391ebdafc..41d89aa3b4 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -221,7 +221,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
try unit.body = transform(unit.body)
catch {
case ex: Exception =>
- println(supplementErrorMessage("unhandled exception while transforming "+unit))
+ log(supplementErrorMessage("unhandled exception while transforming "+unit))
throw ex
}
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
index 82a3144304..80b6ad3cc7 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Scanners.scala
@@ -792,6 +792,7 @@ trait Scanners extends ScannersCommon {
if (ch == '\\') {
nextChar()
if ('0' <= ch && ch <= '7') {
+ val start = charOffset - 2
val leadch: Char = ch
var oct: Int = digit2int(ch, 8)
nextChar()
@@ -803,6 +804,12 @@ trait Scanners extends ScannersCommon {
nextChar()
}
}
+ val alt = if (oct == LF) "\\n" else "\\u%04x" format oct
+ def msg(what: String) = s"Octal escape literals are $what, use $alt instead."
+ if (settings.future)
+ syntaxError(start, msg("unsupported"))
+ else
+ deprecationWarning(start, msg("deprecated"))
putChar(oct.toChar)
} else {
ch match {
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 7edcc944e1..ea2cbbe3d3 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -415,7 +415,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
val INNER_CLASSES_FLAGS =
(asm.Opcodes.ACC_PUBLIC | asm.Opcodes.ACC_PRIVATE | asm.Opcodes.ACC_PROTECTED |
- asm.Opcodes.ACC_STATIC | asm.Opcodes.ACC_INTERFACE | asm.Opcodes.ACC_ABSTRACT)
+ asm.Opcodes.ACC_STATIC | asm.Opcodes.ACC_INTERFACE | asm.Opcodes.ACC_ABSTRACT | asm.Opcodes.ACC_FINAL)
// -----------------------------------------------------------------------------------------
// factory methods
@@ -648,11 +648,12 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
// sort them so inner classes succeed their enclosing class to satisfy the Eclipse Java compiler
for (innerSym <- allInners sortBy (_.name.length)) { // TODO why not sortBy (_.name.toString()) ??
- val flags = mkFlags(
+ val flagsWithFinal: Int = mkFlags(
if (innerSym.rawowner.hasModuleFlag) asm.Opcodes.ACC_STATIC else 0,
javaFlags(innerSym),
if(isDeprecated(innerSym)) asm.Opcodes.ACC_DEPRECATED else 0 // ASM pseudo-access flag
) & (INNER_CLASSES_FLAGS | asm.Opcodes.ACC_DEPRECATED)
+ val flags = if (innerSym.isModuleClass) flagsWithFinal & ~asm.Opcodes.ACC_FINAL else flagsWithFinal // For SI-5676, object overriding.
val jname = javaName(innerSym) // never null
val oname = outerName(innerSym) // null when method-enclosed
val iname = innerName(innerSym) // null for anonymous inner class
@@ -1270,9 +1271,9 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
private def getSuperInterfaces(c: IClass): Array[String] = {
// Additional interface parents based on annotations and other cues
- def newParentForAttr(attr: Symbol): Option[Symbol] = attr match {
- case RemoteAttr => Some(RemoteInterfaceClass)
- case _ => None
+ def newParentForAttr(ann: AnnotationInfo): Symbol = ann.symbol match {
+ case RemoteAttr => RemoteInterfaceClass
+ case _ => NoSymbol
}
/* Drop redundant interfaces (ones which are implemented by some other parent) from the immediate parents.
@@ -1295,7 +1296,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
val ps = c.symbol.info.parents
val superInterfaces0: List[Symbol] = if(ps.isEmpty) Nil else c.symbol.mixinClasses
- val superInterfaces = (superInterfaces0 ++ c.symbol.annotations.flatMap(ann => newParentForAttr(ann.symbol))).distinct
+ val superInterfaces = existingSymbols(superInterfaces0 ++ c.symbol.annotations.map(newParentForAttr)).distinct
if(superInterfaces.isEmpty) EMPTY_STRING_ARRAY
else mkArray(minimizeInterfaces(superInterfaces) map javaName)
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index 250feb69bf..fd85bbb169 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -244,9 +244,9 @@ abstract class SymbolLoaders {
}
class ClassfileLoader(val classfile: AbstractFile) extends SymbolLoader with FlagAssigningCompleter {
- private object classfileParser extends ClassfileParser {
+ private object classfileParser extends {
val global: SymbolLoaders.this.global.type = SymbolLoaders.this.global
- }
+ } with ClassfileParser
protected def description = "class file "+ classfile.toString
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index fb927d15d3..cbfe5460f6 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -39,7 +39,7 @@ abstract class ClassfileParser {
protected var isScala: Boolean = _ // does class file describe a scala class?
protected var isScalaAnnot: Boolean = _ // does class file describe a scala class with its pickled info in an annotation?
protected var isScalaRaw: Boolean = _ // this class file is a scala class with no pickled info
- protected var busy: Option[Symbol] = None // lock to detect recursive reads
+ protected var busy: Symbol = _ // lock to detect recursive reads
protected var currentClass: Name = _ // JVM name of the current class
protected var classTParams = Map[Name,Symbol]()
protected var srcfile0 : Option[AbstractFile] = None
@@ -90,16 +90,15 @@ abstract class ClassfileParser {
case e: RuntimeException => handleError(e)
}
@inline private def pushBusy[T](sym: Symbol)(body: => T): T = {
- busy match {
- case Some(`sym`) => throw new IOException(s"unsatisfiable cyclic dependency in '$sym'")
- case Some(sym1) => throw new IOException(s"illegal class file dependency between '$sym' and '$sym1'")
- case _ => ()
- }
+ if (busy eq sym)
+ throw new IOException(s"unsatisfiable cyclic dependency in '$sym'")
+ else if ((busy ne null) && (busy ne NoSymbol))
+ throw new IOException(s"illegal class file dependency between '$sym' and '$busy'")
- busy = Some(sym)
+ busy = sym
try body
catch parseErrorHandler
- finally busy = None
+ finally busy = NoSymbol
}
@inline private def raiseLoaderLevel[T](body: => T): T = {
loaders.parentsLevel += 1
@@ -588,10 +587,14 @@ abstract class ClassfileParser {
// sealed java enums
if (jflags.isEnum) {
val enumClass = sym.owner.linkedClassOfClass
- if (!enumClass.isSealed)
- enumClass setFlag (SEALED | ABSTRACT)
-
- enumClass addChild sym
+ enumClass match {
+ case NoSymbol =>
+ devWarning(s"no linked class for java enum $sym in ${sym.owner}. A referencing class file might be missing an InnerClasses entry.")
+ case linked =>
+ if (!linked.isSealed)
+ linked setFlag (SEALED | ABSTRACT)
+ linked addChild sym
+ }
}
}
}
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index 385bf2dade..75fb043070 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -533,7 +533,10 @@ abstract class Constructors extends Transform with ast.TreeDSL {
/* Return a pair consisting of (all statements up to and including superclass and trait constr calls, rest) */
def splitAtSuper(stats: List[Tree]) = {
- def isConstr(tree: Tree) = (tree.symbol ne null) && tree.symbol.isConstructor
+ def isConstr(tree: Tree): Boolean = tree match {
+ case Block(_, expr) => isConstr(expr) // SI-6481 account for named argument blocks
+ case _ => (tree.symbol ne null) && tree.symbol.isConstructor
+ }
val (pre, rest0) = stats span (!isConstr(_))
val (supercalls, rest) = rest0 span (isConstr(_))
(pre ::: supercalls, rest)
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index eca958fd8d..e0b1d9ea80 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -594,11 +594,10 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
sym.owner.info //todo: needed?
sym.owner.owner.info //todo: needed?
- assert(
- sym.owner.sourceModule ne NoSymbol,
- "" + sym.fullLocationString + " in " + sym.owner.owner + " " + sym.owner.owner.info.decls
- )
- REF(sym.owner.sourceModule) DOT sym
+ if (sym.owner.sourceModule eq NoSymbol)
+ abort(s"Cannot create static reference to $sym because ${sym.safeOwner} has no source module")
+ else
+ REF(sym.owner.sourceModule) DOT sym
}
def needsInitAndHasOffset(sym: Symbol) =
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index cc4b2d544b..f43e42c027 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -1388,10 +1388,26 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
/* The specialized symbol of 'tree.symbol' for tree.tpe, if there is one */
def specSym(qual: Tree): Symbol = {
val env = unify(symbol.tpe, tree.tpe, emptyEnv, false)
- def isMatch(member: Symbol) = (
- doesConform(symbol, tree.tpe, qual.tpe memberType member, env)
- && TypeEnv.includes(typeEnv(member), env)
- )
+ def isMatch(member: Symbol) = {
+ val memberType = qual.tpe memberType member
+
+ val residualTreeType = tree match {
+ case TypeApply(fun, targs) if fun.symbol == symbol =>
+ // SI-6308 Handle methods with only some type parameters specialized.
+ // drop the specialized type parameters from the PolyType, and
+ // substitute in the type environment.
+ val GenPolyType(tparams, tpe) = fun.tpe
+ val (from, to) = env.toList.unzip
+ val residualTParams = tparams.filterNot(env.contains)
+ GenPolyType(residualTParams, tpe).substituteTypes(from, to)
+ case _ => tree.tpe
+ }
+
+ (
+ doesConform(symbol, residualTreeType, memberType, env)
+ && TypeEnv.includes(typeEnv(member), env)
+ )
+ }
if (env.isEmpty) NoSymbol
else qual.tpe member specializedName(symbol, env) suchThat isMatch
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index fe1607c631..7fa199afaf 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -782,7 +782,7 @@ trait ContextErrors {
}
def MacroExpansionHasInvalidTypeError(expandee: Tree, expanded: Any) = {
- val expected = "expr"
+ val expected = "expr or tree"
val isPathMismatch = expanded != null && expanded.isInstanceOf[scala.reflect.api.Exprs#Expr[_]]
macroExpansionError(expandee,
s"macro must return a compiler-specific $expected; returned value is " + (
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index b53efafdd4..8e79b56814 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -144,6 +144,15 @@ trait Implicits {
private val infoMapCache = new LinkedHashMap[Symbol, InfoMap]
private val improvesCache = perRunCaches.newMap[(ImplicitInfo, ImplicitInfo), Boolean]()
+ private def isInvalidConversionTarget(tpe: Type): Boolean = tpe match {
+ case Function1(_, out) => AnyRefClass.tpe <:< out
+ case _ => false
+ }
+ private def isInvalidConversionSource(tpe: Type): Boolean = tpe match {
+ case Function1(in, _) => in <:< NullClass.tpe
+ case _ => false
+ }
+
def resetImplicits() {
implicitsCache.clear()
infoMapCache.clear()
@@ -1357,10 +1366,10 @@ trait Implicits {
val wasAmbigious = result.isAmbiguousFailure // SI-6667, never search companions after an ambiguous error in in-scope implicits
result = materializeImplicit(pt)
-
// `materializeImplicit` does some preprocessing for `pt`
// is it only meant for manifests/tags or we need to do the same for `implicitsOfExpectedType`?
- if (result.isFailure && !wasAmbigious) result = searchImplicit(implicitsOfExpectedType, isLocal = false)
+ if (result.isFailure && !wasAmbigious)
+ result = searchImplicit(implicitsOfExpectedType, isLocal = false)
if (result.isFailure) {
context.updateBuffer(previousErrs)
@@ -1370,9 +1379,18 @@ trait Implicits {
if (Statistics.canEnable) Statistics.incCounter(oftypeImplicitHits)
}
}
-
- if (result.isFailure && settings.debug)
- log("no implicits found for "+pt+" "+pt.typeSymbol.info.baseClasses+" "+implicitsOfExpectedType)
+ if (result.isSuccess && isView) {
+ if (isInvalidConversionTarget(pt)) {
+ context.issueAmbiguousError(AmbiguousImplicitTypeError(tree, "the result type of an implicit conversion must be more specific than AnyRef"))
+ result = SearchFailure
+ }
+ else if (isInvalidConversionSource(pt)) {
+ context.issueAmbiguousError(AmbiguousImplicitTypeError(tree, "an expression of type Null is ineligible for implicit conversion"))
+ result = SearchFailure
+ }
+ }
+ if (result.isFailure)
+ debuglog("no implicits found for "+pt+" "+pt.typeSymbol.info.baseClasses+" "+implicitsOfExpectedType)
result
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index 6c4d1e20aa..86ba3d2164 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -92,11 +92,12 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
methName: String,
// flattens the macro impl's parameter lists having symbols replaced with their fingerprints
// currently fingerprints are calculated solely from types of the symbols:
- // * c.Expr[T] => IMPLPARAM_EXPR
- // * c.WeakTypeTag[T] => index of the type parameter corresponding to that type tag
- // * everything else (e.g. scala.reflect.macros.Context) => IMPLPARAM_OTHER
+ // * c.Expr[T] => LiftedTyped
+ // * c.Tree => LiftedUntyped
+ // * c.WeakTypeTag[T] => Tagged(index of the type parameter corresponding to that type tag)
+ // * everything else (e.g. scala.reflect.macros.Context) => Other
// f.ex. for: def impl[T: WeakTypeTag, U, V: WeakTypeTag](c: Context)(x: c.Expr[T], y: c.Tree): (U, V) = ???
- // `signature` will be equal to List(List(Other), List(Lifted, Other), List(Tagged(0), Tagged(2)))
+ // `signature` will be equal to List(List(Other), List(LiftedTyped, LiftedUntyped), List(Tagged(0), Tagged(2)))
signature: List[List[Fingerprint]],
// type arguments part of a macro impl ref (the right-hand side of a macro definition)
// these trees don't refer to a macro impl, so we can pickle them as is
@@ -124,7 +125,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
* "className" = "Macros$"))
*/
object MacroImplBinding {
- val versionFormat = 4.0
+ val versionFormat = 5.0
def pickleAtom(obj: Any): Tree =
obj match {
@@ -164,7 +165,8 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
def signature: List[List[Fingerprint]] = {
def fingerprint(tpe: Type): Fingerprint = tpe.dealiasWiden match {
case TypeRef(_, RepeatedParamClass, underlying :: Nil) => fingerprint(underlying)
- case ExprClassOf(_) => Lifted
+ case ExprClassOf(_) => LiftedTyped
+ case TreeType() => LiftedUntyped
case _ => Other
}
@@ -388,7 +390,8 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
val wrappedArgs = mapWithIndex(args)((arg, j) => {
val fingerprint = implParams(min(j, implParams.length - 1))
fingerprint match {
- case Lifted => context.Expr[Nothing](arg)(TypeTag.Nothing) // TODO: SI-5752
+ case LiftedTyped => context.Expr[Nothing](arg)(TypeTag.Nothing) // TODO: SI-5752
+ case LiftedUntyped => arg
case _ => abort(s"unexpected fingerprint $fingerprint in $binding with paramss being $paramss " +
s"corresponding to arg $arg in $argss")
}
@@ -690,6 +693,7 @@ trait Macros extends FastTrack with MacroRuntimes with Traces with Helpers {
}
expanded match {
case expanded: Expr[_] if expandee.symbol.isTermMacro => validateResultingTree(expanded.tree)
+ case expanded: Tree if expandee.symbol.isTermMacro => validateResultingTree(expanded)
case _ => MacroExpansionHasInvalidTypeError(expandee, expanded)
}
} catch {
@@ -804,10 +808,12 @@ class Fingerprint(val value: Int) extends AnyVal {
def paramPos = { assert(isTag, this); value }
def isTag = value >= 0
def isOther = this == Other
- def isExpr = this == Lifted
+ def isExpr = this == LiftedTyped
+ def isTree = this == LiftedUntyped
override def toString = this match {
case Other => "Other"
- case Lifted => "Expr"
+ case LiftedTyped => "Expr"
+ case LiftedUntyped => "Tree"
case _ => s"Tag($value)"
}
}
@@ -815,5 +821,6 @@ class Fingerprint(val value: Int) extends AnyVal {
object Fingerprint {
def Tagged(tparamPos: Int) = new Fingerprint(tparamPos)
val Other = new Fingerprint(-1)
- val Lifted = new Fingerprint(-2)
+ val LiftedTyped = new Fingerprint(-2)
+ val LiftedUntyped = new Fingerprint(-3)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 4683fca192..0305aab844 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -1686,8 +1686,13 @@ trait Namers extends MethodSynthesis {
* call this method?
*/
def companionSymbolOf(original: Symbol, ctx: Context): Symbol = {
+ val owner = original.owner
+ // SI-7264 Force the info of owners from previous compilation runs.
+ // Doing this generally would trigger cycles; that's what we also
+ // use the lower-level scan through the current Context as a fall back.
+ if (!currentRun.compiles(owner)) owner.initialize
original.companionSymbol orElse {
- ctx.lookup(original.name.companionName, original.owner).suchThat(sym =>
+ ctx.lookup(original.name.companionName, owner).suchThat(sym =>
(original.isTerm || sym.hasModuleFlag) &&
(sym isCoDefinedWith original)
)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index ec6b78f2de..cb3a12b60d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -831,8 +831,9 @@ trait Typers extends Adaptations with Tags {
else tpr.typed(withImplicitArgs, mode, pt)
}
orElse { _ =>
- debuglog("fallback on implicits: " + tree + "/" + resetAllAttrs(original))
- val tree1 = typed(resetAllAttrs(original), mode)
+ val resetTree = resetLocalAttrs(original)
+ 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)
@@ -1572,9 +1573,9 @@ trait Typers extends Adaptations with Tags {
}
typedType(decodedtpt)
} else {
- var supertpt = typedTypeConstructor(decodedtpt)
+ val supertpt = typedTypeConstructor(decodedtpt)
val supertparams = if (supertpt.hasSymbolField) supertpt.symbol.typeParams else Nil
- if (supertparams.nonEmpty) {
+ def inferParentTypeArgs: Tree = {
typedPrimaryConstrBody(templ) {
val supertpe = PolyType(supertparams, appliedType(supertpt.tpe, supertparams map (_.tpeHK)))
val supercall = New(supertpe, mmap(argss)(_.duplicate))
@@ -1582,14 +1583,17 @@ trait Typers extends Adaptations with Tags {
ctor setType supertpe // this is an essential hack, otherwise it will occasionally fail to typecheck
atPos(supertpt.pos.focus)(supercall)
} match {
- case EmptyTree => MissingTypeArgumentsParentTpeError(supertpt)
- case tpt => supertpt = TypeTree(tpt.tpe) setPos supertpt.pos // SI-7224: don't .focus positions of the TypeTree of a parent that exists in source
+ case EmptyTree => MissingTypeArgumentsParentTpeError(supertpt); supertpt
+ case tpt => TypeTree(tpt.tpe) setPos supertpt.pos // SI-7224: don't .focus positions of the TypeTree of a parent that exists in source
}
}
+
+ val supertptWithTargs = if (supertparams.isEmpty || context.unit.isJava) supertpt else inferParentTypeArgs
+
// this is the place where we tell the typer what argss should be used for the super call
// if argss are nullary or empty, then (see the docs for `typedPrimaryConstrBody`)
// the super call dummy is already good enough, so we don't need to do anything
- if (argssAreTrivial) supertpt else supertpt updateAttachment SuperArgsAttachment(argss)
+ if (argssAreTrivial) supertptWithTargs else supertptWithTargs updateAttachment SuperArgsAttachment(argss)
}
}
@@ -3185,7 +3189,7 @@ trait Typers extends Adaptations with Tags {
* to that. This is the last thing which is tried (after
* default arguments)
*/
- def tryTupleApply: Option[Tree] = (
+ def tryTupleApply: Tree = (
if (eligibleForTupleConversion(paramTypes, argslen) && !phase.erasedTypes) {
val tupleArgs = List(atPos(tree.pos.makeTransparent)(gen.mkTuple(args)))
// expected one argument, but got 0 or >1 ==> try applying to tuple
@@ -3194,14 +3198,15 @@ trait Typers extends Adaptations with Tags {
silent(_.doTypedApply(tree, fun, tupleArgs, mode, pt)) map { t =>
// Depending on user options, may warn or error here if
// a Unit or tuple was inserted.
- Some(t) filter (tupledTree =>
+ val keepTree = (
!mode.typingExprNotFun
- || tupledTree.symbol == null
- || checkValidAdaptation(tupledTree, args)
+ || t.symbol == null
+ || checkValidAdaptation(t, args)
)
- } orElse { _ => context.undetparams = savedUndetparams ; None }
- }
- else None
+ if (keepTree) t else EmptyTree
+ } orElse { _ => context.undetparams = savedUndetparams ; EmptyTree }
+ }
+ else EmptyTree
)
/* Treats an application which uses named or default arguments.
@@ -3214,7 +3219,7 @@ trait Typers extends Adaptations with Tags {
def checkNotMacro() = {
if (treeInfo.isMacroApplication(fun))
- tryTupleApply getOrElse duplErrorTree(NamedAndDefaultArgumentsNotSupportedForMacros(tree, fun))
+ tryTupleApply orElse duplErrorTree(NamedAndDefaultArgumentsNotSupportedForMacros(tree, fun))
}
if (mt.isErroneous) duplErrTree
@@ -3222,7 +3227,7 @@ trait Typers extends Adaptations with Tags {
// #2064
duplErrorTree(WrongNumberOfArgsError(tree, fun))
} else if (lencmp > 0) {
- tryTupleApply getOrElse duplErrorTree(TooManyArgsNamesDefaultsError(tree, fun))
+ tryTupleApply orElse duplErrorTree(TooManyArgsNamesDefaultsError(tree, fun))
} else if (lencmp == 0) {
// we don't need defaults. names were used, so this application is transformed
// into a block (@see transformNamedApplication in NamesDefaults)
@@ -3275,7 +3280,7 @@ trait Typers extends Adaptations with Tags {
if (!(context.diagnostic contains note)) context.diagnostic = note :: context.diagnostic
doTypedApply(tree, if (blockIsEmpty) fun else fun1, allArgs, mode, pt)
} else {
- tryTupleApply getOrElse duplErrorTree(NotEnoughArgsError(tree, fun, missing))
+ tryTupleApply orElse duplErrorTree(NotEnoughArgsError(tree, fun, missing))
}
}
}
@@ -3311,7 +3316,7 @@ trait Typers extends Adaptations with Tags {
// instantiate dependent method types, must preserve singleton types where possible (stableTypeFor) -- example use case:
// val foo = "foo"; def precise(x: String)(y: x.type): x.type = {...}; val bar : foo.type = precise(foo)(foo)
// precise(foo) : foo.type => foo.type
- val restpe = mt.resultType(args1 map (arg => gen.stableTypeFor(arg) getOrElse arg.tpe))
+ val restpe = mt.resultType(args1 map (arg => gen stableTypeFor arg orElse arg.tpe))
def ifPatternSkipFormals(tp: Type) = tp match {
case MethodType(_, rtp) if (mode.inPatternMode) => rtp
case _ => tp
@@ -3729,7 +3734,7 @@ trait Typers extends Adaptations with Tags {
/** Compute an existential type from raw hidden symbols `syms` and type `tp`
*/
- def packSymbols(hidden: List[Symbol], tp: Type): Type = global.packSymbols(hidden, tp, Some(context0.owner))
+ def packSymbols(hidden: List[Symbol], tp: Type): Type = global.packSymbols(hidden, tp, context0.owner)
def isReferencedFrom(ctx: Context, sym: Symbol): Boolean = (
ctx.owner.isTerm &&
@@ -5109,7 +5114,7 @@ trait Typers extends Adaptations with Tags {
if (mode.inPatternMode) {
val uncheckedTypeExtractor = extractorForUncheckedType(tpt.pos, tptTyped.tpe)
// make fully defined to avoid bounded wildcard types that may be in pt from calling dropExistential (SI-2038)
- val ptDefined = ensureFullyDefined(pt)
+ val ptDefined = ensureFullyDefined(pt) // FIXME this is probably redundant now that we don't dropExistenial in pattern mode.
val ownType = inferTypedPattern(tptTyped, tptTyped.tpe, ptDefined, canRemedy = uncheckedTypeExtractor.nonEmpty)
treeTyped setType ownType
@@ -5343,7 +5348,12 @@ trait Typers extends Adaptations with Tags {
"context.owner" -> context.owner
)
)
- typed1(tree, mode, dropExistential(ptPlugins))
+ val ptWild = if (mode.inPatternMode)
+ ptPlugins // SI-5022 don't widen pt for patterns as types flow from it to the case body.
+ else
+ dropExistential(ptPlugins) // FIXME: document why this is done.
+
+ typed1(tree, mode, ptWild)
}
// Can happen during erroneous compilation - error(s) have been
// reported, but we need to avoid causing an NPE with this tree
diff --git a/src/eclipse/README.md b/src/eclipse/README.md
index 73aa270b77..2bb1a4da8f 100644
--- a/src/eclipse/README.md
+++ b/src/eclipse/README.md
@@ -11,6 +11,9 @@ IMPORTANT
Preferences/General/Workspace/Linked Resources. The value should be the absolute
path to your scala checkout. All paths in project files are relative to this one,
so nothing will work before you do so.
+Additionally, we start using Maven dependencies (e.g. junit) so you need to define
+`classpath variable` inside Eclipse. Define `M2_REPO` in Java/Build Path/Classpath Variables
+to point to your local Maven repository (e.g. $HOME/.m2/repository).
2. The Eclipse Java compiler does not allow certain calls to restricted APIs in the
JDK. The Scala library uses such APIs, so you'd see this error:
diff --git a/src/eclipse/test-junit/.classpath b/src/eclipse/test-junit/.classpath
new file mode 100644
index 0000000000..718f7b6ece
--- /dev/null
+++ b/src/eclipse/test-junit/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+ <classpathentry kind="src" path="test-junit"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/reflect"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/scala-library"/>
+ <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
+ <classpathentry kind="lib" path="lib/ant/ant.jar"/>
+ <classpathentry kind="lib" path="lib/jline.jar"/>
+ <classpathentry combineaccessrules="false" kind="src" path="/scala-compiler"/>
+ <classpathentry kind="var" path="M2_REPO/junit/junit/4.10/junit-4.10.jar"/>
+ <classpathentry kind="output" path="build-test-junit"/>
+</classpath>
diff --git a/src/eclipse/test-junit/.project b/src/eclipse/test-junit/.project
new file mode 100644
index 0000000000..052b6c1b6f
--- /dev/null
+++ b/src/eclipse/test-junit/.project
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+ <name>test-junit</name>
+ <comment></comment>
+ <projects>
+ </projects>
+ <buildSpec>
+ <buildCommand>
+ <name>org.scala-ide.sdt.core.scalabuilder</name>
+ <arguments>
+ </arguments>
+ </buildCommand>
+ </buildSpec>
+ <natures>
+ <nature>org.scala-ide.sdt.core.scalanature</nature>
+ <nature>org.eclipse.jdt.core.javanature</nature>
+ </natures>
+ <linkedResources>
+ <link>
+ <name>build-test-junit</name>
+ <type>2</type>
+ <locationURI>SCALA_BASEDIR/build/junit/classes</locationURI>
+ </link>
+ <link>
+ <name>lib</name>
+ <type>2</type>
+ <locationURI>SCALA_BASEDIR/lib</locationURI>
+ </link>
+ <link>
+ <name>test-junit</name>
+ <type>2</type>
+ <locationURI>SCALA_BASEDIR/test/junit</locationURI>
+ </link>
+ </linkedResources>
+</projectDescription>
diff --git a/src/library/scala/Option.scala b/src/library/scala/Option.scala
index 4b071166c7..905e925f57 100644
--- a/src/library/scala/Option.scala
+++ b/src/library/scala/Option.scala
@@ -128,7 +128,7 @@ sealed abstract class Option[+A] extends Product with Serializable {
* val textField = new JComponent(initalText.orNull,20)
* }}}
*/
- @inline final def orNull[A1 >: A](implicit ev: Null <:< A1): A1 = this getOrElse null
+ @inline final def orNull[A1 >: A](implicit ev: Null <:< A1): A1 = this getOrElse ev(null)
/** Returns a $some containing the result of applying $f to this $option's
* value if this $option is nonempty.
@@ -210,7 +210,7 @@ sealed abstract class Option[+A] extends Product with Serializable {
}
/** Tests whether the option contains a given value as an element.
- *
+ *
* @param elem the element to test.
* @return `true` if the option has an element that is equal (as
* determined by `==`) to `elem`, `false` otherwise.
diff --git a/src/library/scala/Predef.scala b/src/library/scala/Predef.scala
index 569157de20..5ba38600b6 100644
--- a/src/library/scala/Predef.scala
+++ b/src/library/scala/Predef.scala
@@ -346,19 +346,6 @@ object Predef extends LowPriorityImplicits with DeprecatedPredef {
implicit def double2Double(x: Double) = java.lang.Double.valueOf(x)
implicit def boolean2Boolean(x: Boolean) = java.lang.Boolean.valueOf(x)
- // These next eight implicits exist solely to exclude AnyRef methods from the
- // eight implicits above so that primitives are not coerced to AnyRefs. They
- // only create such conflict for AnyRef methods, so the methods on the java.lang
- // boxed types are unambiguously reachable.
- implicit def byte2ByteConflict(x: Byte) = new AnyRef
- implicit def short2ShortConflict(x: Short) = new AnyRef
- implicit def char2CharacterConflict(x: Char) = new AnyRef
- implicit def int2IntegerConflict(x: Int) = new AnyRef
- implicit def long2LongConflict(x: Long) = new AnyRef
- implicit def float2FloatConflict(x: Float) = new AnyRef
- implicit def double2DoubleConflict(x: Double) = new AnyRef
- implicit def boolean2BooleanConflict(x: Boolean) = new AnyRef
-
implicit def Byte2byte(x: java.lang.Byte): Byte = x.byteValue
implicit def Short2short(x: java.lang.Short): Short = x.shortValue
implicit def Character2char(x: java.lang.Character): Char = x.charValue
@@ -481,24 +468,6 @@ private[scala] abstract class LowPriorityImplicits {
@inline implicit def doubleWrapper(x: Double) = new runtime.RichDouble(x)
@inline implicit def booleanWrapper(x: Boolean) = new runtime.RichBoolean(x)
- // These eight implicits exist solely to exclude Null from the domain of
- // the boxed types, so that e.g. "var x: Int = null" is a compile time
- // error rather than a delayed null pointer exception by way of the
- // conversion from java.lang.Integer. If defined in the same template as
- // Integer2int, they would have higher priority because Null is a subtype
- // of Integer. We balance that out and create conflict by moving the
- // definition into the superclass.
- //
- // Caution: do not adjust tightrope tension without safety goggles in place.
- implicit def Byte2byteNullConflict(x: Null): Byte = sys.error("value error")
- implicit def Short2shortNullConflict(x: Null): Short = sys.error("value error")
- implicit def Character2charNullConflict(x: Null): Char = sys.error("value error")
- implicit def Integer2intNullConflict(x: Null): Int = sys.error("value error")
- implicit def Long2longNullConflict(x: Null): Long = sys.error("value error")
- implicit def Float2floatNullConflict(x: Null): Float = sys.error("value error")
- implicit def Double2doubleNullConflict(x: Null): Double = sys.error("value error")
- implicit def Boolean2booleanNullConflict(x: Null): Boolean = sys.error("value error")
-
implicit def genericWrapArray[T](xs: Array[T]): WrappedArray[T] =
if (xs eq null) null
else WrappedArray.make(xs)
diff --git a/src/library/scala/annotation/cloneable.scala b/src/library/scala/annotation/cloneable.scala
deleted file mode 100644
index 4fb62b698f..0000000000
--- a/src/library/scala/annotation/cloneable.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-
-package scala.annotation
-
-/**
- * An annotation that designates the class to which it is applied as cloneable
- */
-@deprecated("instead of `@cloneable class C`, use `class C extends Cloneable`", "2.10.0")
-class cloneable extends scala.annotation.StaticAnnotation
diff --git a/src/library/scala/collection/concurrent/TrieMap.scala b/src/library/scala/collection/concurrent/TrieMap.scala
index 0b5ceeb1c7..6632f30e51 100644
--- a/src/library/scala/collection/concurrent/TrieMap.scala
+++ b/src/library/scala/collection/concurrent/TrieMap.scala
@@ -1012,8 +1012,11 @@ private[collection] class TrieMapIterator[K, V](var level: Int, private var ct:
*/
protected def subdivide(): Seq[Iterator[(K, V)]] = if (subiter ne null) {
// the case where an LNode is being iterated
- val it = subiter
- subiter = null
+ val it = newIterator(level + 1, ct, _mustInit = false)
+ it.depth = -1
+ it.subiter = this.subiter
+ it.current = null
+ this.subiter = null
advance()
this.level += 1
Seq(it, this)
diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala
index 09f8143b55..72c40e889f 100644
--- a/src/library/scala/collection/immutable/Range.scala
+++ b/src/library/scala/collection/immutable/Range.scala
@@ -65,6 +65,7 @@ extends scala.collection.AbstractSeq[Int]
|| (start < end && step < 0)
|| (start == end && !isInclusive)
)
+ @deprecated("This method will be made private, use `length` instead.", "2.11")
final val numRangeElements: Int = {
if (step == 0) throw new IllegalArgumentException("step cannot be 0.")
else if (isEmpty) 0
@@ -74,7 +75,9 @@ extends scala.collection.AbstractSeq[Int]
else len.toInt
}
}
+ @deprecated("This method will be made private, use `last` instead.", "2.11")
final val lastElement = start + (numRangeElements - 1) * step
+ @deprecated("This method will be made private.", "2.11")
final val terminalElement = start + numRangeElements * step
override def last = if (isEmpty) Nil.last else lastElement
diff --git a/src/library/scala/collection/immutable/StringLike.scala b/src/library/scala/collection/immutable/StringLike.scala
index 4768413e75..5a0d24ddd2 100644
--- a/src/library/scala/collection/immutable/StringLike.scala
+++ b/src/library/scala/collection/immutable/StringLike.scala
@@ -222,12 +222,33 @@ self =>
*/
def r(groupNames: String*): Regex = new Regex(toString, groupNames: _*)
+ /**
+ * @throws `java.lang.IllegalArgumentException` - If the string does not contain a parsable boolean.
+ */
def toBoolean: Boolean = parseBoolean(toString)
+ /**
+ * @throws `java.lang.NumberFormatException` - If the string does not contain a parsable byte.
+ */
def toByte: Byte = java.lang.Byte.parseByte(toString)
+ /**
+ * @throws `java.lang.NumberFormatException` - If the string does not contain a parsable short.
+ */
def toShort: Short = java.lang.Short.parseShort(toString)
+ /**
+ * @throws `java.lang.NumberFormatException` - If the string does not contain a parsable int.
+ */
def toInt: Int = java.lang.Integer.parseInt(toString)
+ /**
+ * @throws `java.lang.NumberFormatException` - If the string does not contain a parsable long.
+ */
def toLong: Long = java.lang.Long.parseLong(toString)
+ /**
+ * @throws `java.lang.NumberFormatException` - If the string does not contain a parsable float.
+ */
def toFloat: Float = java.lang.Float.parseFloat(toString)
+ /**
+ * @throws `java.lang.NumberFormatException` - If the string does not contain a parsable double.
+ */
def toDouble: Double = java.lang.Double.parseDouble(toString)
private def parseBoolean(s: String): Boolean =
diff --git a/src/library/scala/concurrent/duration/Duration.scala b/src/library/scala/concurrent/duration/Duration.scala
index a24266bf19..9a8844b489 100644
--- a/src/library/scala/concurrent/duration/Duration.scala
+++ b/src/library/scala/concurrent/duration/Duration.scala
@@ -221,6 +221,8 @@ object Duration {
final def toMinutes: Long = fail("toMinutes")
final def toHours: Long = fail("toHours")
final def toDays: Long = fail("toDays")
+
+ final def toCoarsest: Duration = this
}
/**
@@ -520,6 +522,18 @@ sealed abstract class Duration extends Serializable with Ordered[Duration] {
* $ovf
*/
def plus(other: Duration) = this + other
+ /**
+ * Return duration which is equal to this duration but with a coarsest Unit, or self in case it is already the coarsest Unit
+ * <p/>
+ * Examples:
+ * {{{
+ * Duration(60, MINUTES).toCoarsest // Duration(1, HOURS)
+ * Duration(1000, MILLISECONDS).toCoarsest // Duration(1, SECONDS)
+ * Duration(48, HOURS).toCoarsest // Duration(2, DAYS)
+ * Duration(5, SECONDS).toCoarsest // Duration(5, SECONDS)
+ * }}}
+ */
+ def toCoarsest: Duration
}
object FiniteDuration {
@@ -691,6 +705,28 @@ final class FiniteDuration(val length: Long, val unit: TimeUnit) extends Duratio
final def isFinite() = true
+ final def toCoarsest: Duration = {
+ def loop(length: Long, unit: TimeUnit): FiniteDuration = {
+ def coarserOrThis(coarser: TimeUnit, divider: Int) =
+ if (length % divider == 0) loop(length / divider, coarser)
+ else if (unit == this.unit) this
+ else FiniteDuration(length, unit)
+
+ unit match {
+ case DAYS => FiniteDuration(length, unit)
+ case HOURS => coarserOrThis(DAYS, 24)
+ case MINUTES => coarserOrThis(HOURS, 60)
+ case SECONDS => coarserOrThis(MINUTES, 60)
+ case MILLISECONDS => coarserOrThis(SECONDS, 1000)
+ case MICROSECONDS => coarserOrThis(MILLISECONDS, 1000)
+ case NANOSECONDS => coarserOrThis(MICROSECONDS, 1000)
+ }
+ }
+
+ if (unit == DAYS || length == 0) this
+ else loop(length, unit)
+ }
+
override def equals(other: Any) = other match {
case x: FiniteDuration => toNanos == x.toNanos
case _ => super.equals(other)
diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala
index 2240dde360..fef9cef246 100644
--- a/src/library/scala/util/Properties.scala
+++ b/src/library/scala/util/Properties.scala
@@ -146,6 +146,9 @@ private[scala] trait PropertiesTrait {
/** Returns `true` iff the underlying operating system is a version of Apple Mac OSX. */
def isMac = osName startsWith "Mac OS X"
+ /* Some runtime values. */
+ private[scala] def isAvian = javaVmName contains "Avian"
+
// This is looking for javac, tools.jar, etc.
// Tries JDK_HOME first, then the more common but likely jre JAVA_HOME,
// and finally the system property based javaHome.
diff --git a/src/partest/scala/tools/partest/BytecodeTest.scala b/src/partest/scala/tools/partest/BytecodeTest.scala
index 2699083069..172fa29189 100644
--- a/src/partest/scala/tools/partest/BytecodeTest.scala
+++ b/src/partest/scala/tools/partest/BytecodeTest.scala
@@ -2,10 +2,9 @@ package scala.tools.partest
import scala.tools.nsc.util.JavaClassPath
import scala.collection.JavaConverters._
-import scala.tools.asm
-import asm.{ ClassReader }
-import asm.tree.{ClassNode, MethodNode, InsnList}
-import java.io.InputStream
+import scala.tools.asm.{ClassWriter, ClassReader}
+import scala.tools.asm.tree.{ClassNode, MethodNode, InsnList}
+import java.io.{FileOutputStream, FileInputStream, File => JFile, InputStream}
import AsmNode._
/**
@@ -127,3 +126,31 @@ abstract class BytecodeTest extends ASMConverters {
new JavaClassPath(containers, DefaultJavaContext)
}
}
+
+object BytecodeTest {
+ /** Parse `file` as a class file, transforms the ASM representation with `f`,
+ * and overwrites the orginal file.
+ */
+ def modifyClassFile(file: JFile)(f: ClassNode => ClassNode) {
+ val rfile = new reflect.io.File(file)
+ def readClass: ClassNode = {
+ val cr = new ClassReader(rfile.toByteArray())
+ val cn = new ClassNode()
+ cr.accept(cn, 0)
+ cn
+ }
+
+ def writeClass(cn: ClassNode) {
+ val writer = new ClassWriter(0)
+ cn.accept(writer)
+ val os = rfile.bufferedOutput()
+ try {
+ os.write(writer.toByteArray)
+ } finally {
+ os.close()
+ }
+ }
+
+ writeClass(f(readClass))
+ }
+}
diff --git a/src/partest/scala/tools/partest/DirectTest.scala b/src/partest/scala/tools/partest/DirectTest.scala
index 7f9ca3a321..953b5e5535 100644
--- a/src/partest/scala/tools/partest/DirectTest.scala
+++ b/src/partest/scala/tools/partest/DirectTest.scala
@@ -6,6 +6,7 @@
package scala.tools.partest
import scala.tools.nsc._
+import settings.ScalaVersion
import util.{ SourceFile, BatchSourceFile, CommandLineParser }
import reporters.{Reporter, ConsoleReporter}
@@ -97,4 +98,30 @@ abstract class DirectTest extends App {
final def log(msg: => Any) {
if (isDebug) Console.err println msg
}
+
+ /**
+ * Run a test only if the current java version is at least the version specified.
+ */
+ def testUnderJavaAtLeast[A](version: String)(yesRun: =>A) = new TestUnderJavaAtLeast(version, { yesRun })
+
+ class TestUnderJavaAtLeast[A](version: String, yesRun: => A) {
+ val javaVersion = System.getProperty("java.specification.version")
+
+ // the "ScalaVersion" class parses Java specification versions just fine
+ val requiredJavaVersion = ScalaVersion(version)
+ val executingJavaVersion = ScalaVersion(javaVersion)
+ val shouldRun = executingJavaVersion >= requiredJavaVersion
+ val preamble = if (shouldRun) "Attempting" else "Doing fallback for"
+
+ def logInfo() = log(s"$preamble java $version specific test under java version $javaVersion")
+
+ /*
+ * If the current java version is at least 'version' then 'yesRun' is evaluated
+ * otherwise 'fallback' is
+ */
+ def otherwise(fallback: =>A): A = {
+ logInfo()
+ if (shouldRun) yesRun else fallback
+ }
+ }
}
diff --git a/src/partest/scala/tools/partest/nest/Runner.scala b/src/partest/scala/tools/partest/nest/Runner.scala
index 1034d724d2..a53698eb77 100644
--- a/src/partest/scala/tools/partest/nest/Runner.scala
+++ b/src/partest/scala/tools/partest/nest/Runner.scala
@@ -286,7 +286,7 @@ class Runner(val testFile: File, fileManager: FileManager, val testRunParams: Te
* might be failing, in the normal case.
*/
def diffilter(d: String) = {
- import scala.util.Properties.javaVersion
+ import scala.util.Properties.{javaVersion, isAvian}
val prefix = "#partest"
val margin = "> "
val leader = margin + prefix
@@ -297,6 +297,7 @@ class Runner(val testFile: File, fileManager: FileManager, val testRunParams: Te
val cond = token match {
case "java7" => javaVersion startsWith "1.7"
case "java6" => javaVersion startsWith "1.6"
+ case "avian" => isAvian
case "true" => true
case _ => false
}
diff --git a/src/partest/scala/tools/partest/utils/Properties.scala b/src/partest/scala/tools/partest/utils/Properties.scala
index 1263c96e9e..b9394b50c9 100644
--- a/src/partest/scala/tools/partest/utils/Properties.scala
+++ b/src/partest/scala/tools/partest/utils/Properties.scala
@@ -14,4 +14,5 @@ package utils
object Properties extends scala.util.PropertiesTrait {
protected def propCategory = "partest"
protected def pickJarBasedOn = classOf[nest.RunnerManager]
+ override def isAvian = super.isAvian
}
diff --git a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
index 368e1cde30..e3498a95a6 100644
--- a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
+++ b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
@@ -66,15 +66,14 @@ trait BaseTypeSeqs {
pending += i
try {
mergePrefixAndArgs(variants, Variance.Contravariant, lubDepth(variants)) match {
- case Some(tp0) =>
+ case NoType => typeError("no common type instance of base types "+(variants mkString ", and ")+" exists.")
+ case tp0 =>
pending(i) = false
elems(i) = tp0
tp0
- case None =>
- typeError(
- "no common type instance of base types "+(variants mkString ", and ")+" exists.")
}
- } catch {
+ }
+ catch {
case CyclicInheritance =>
typeError(
"computing the common type instance of base types "+(variants mkString ", and ")+" leads to a cycle.")
diff --git a/src/reflect/scala/reflect/internal/CapturedVariables.scala b/src/reflect/scala/reflect/internal/CapturedVariables.scala
index 2c5e87b95d..ef9646b80f 100644
--- a/src/reflect/scala/reflect/internal/CapturedVariables.scala
+++ b/src/reflect/scala/reflect/internal/CapturedVariables.scala
@@ -30,7 +30,7 @@ trait CapturedVariables { self: SymbolTable =>
def refType(valueRef: Map[Symbol, Symbol], objectRefClass: Symbol) =
if (isPrimitiveValueClass(symClass) && symClass != UnitClass) valueRef(symClass).tpe
else if (erasedTypes) objectRefClass.tpe
- else appliedType(objectRefClass, tpe)
+ else appliedType(objectRefClass, tpe1)
if (vble.hasAnnotation(VolatileAttr)) refType(volatileRefClass, VolatileObjectRefClass)
else refType(refClass, ObjectRefClass)
}
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 851fc98a32..4f2b7e2642 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -409,10 +409,6 @@ trait Definitions extends api.StandardDefinitions {
lazy val JavaRepeatedParamClass = specialPolyClass(tpnme.JAVA_REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => arrayType(tparam.tpe))
lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS_NAME, COVARIANT)(tparam => seqType(tparam.tpe))
- def dropByName(tp: Type): Type = tp match {
- case TypeRef(_, ByNameParamClass, arg :: Nil) => arg
- case _ => tp
- }
def isByNameParamType(tp: Type) = tp.typeSymbol == ByNameParamClass
def isScalaRepeatedParamType(tp: Type) = tp.typeSymbol == RepeatedParamClass
def isJavaRepeatedParamType(tp: Type) = tp.typeSymbol == JavaRepeatedParamClass
@@ -433,29 +429,15 @@ trait Definitions extends api.StandardDefinitions {
case _ => false
}
- def repeatedToSingle(tp: Type): Type = tp match {
- case TypeRef(_, RepeatedParamClass, arg :: Nil) => arg
- case _ => tp
- }
-
- def repeatedToSeq(tp: Type): Type = (tp baseType RepeatedParamClass) match {
- case TypeRef(_, RepeatedParamClass, arg :: Nil) => seqType(arg)
- case _ => tp
- }
-
- def seqToRepeated(tp: Type): Type = (tp baseType SeqClass) match {
- case TypeRef(_, SeqClass, arg :: Nil) => scalaRepeatedType(arg)
- case _ => tp
- }
-
- def isReferenceArray(tp: Type) = tp match {
- case TypeRef(_, ArrayClass, arg :: Nil) => arg <:< AnyRefTpe
- case _ => false
- }
- def isArrayOfSymbol(tp: Type, elem: Symbol) = tp match {
- case TypeRef(_, ArrayClass, arg :: Nil) => arg.typeSymbol == elem
- case _ => false
- }
+ // wrapping and unwrapping
+ def dropByName(tp: Type): Type = elementExtract(ByNameParamClass, tp) orElse tp
+ def repeatedToSingle(tp: Type): Type = elementExtract(RepeatedParamClass, tp) orElse tp
+ def repeatedToSeq(tp: Type): Type = elementTransform(RepeatedParamClass, tp)(seqType) orElse tp
+ def seqToRepeated(tp: Type): Type = elementTransform(SeqClass, tp)(scalaRepeatedType) orElse tp
+ def isReferenceArray(tp: Type) = elementTest(ArrayClass, tp)(_ <:< AnyRefTpe)
+ def isArrayOfSymbol(tp: Type, elem: Symbol) = elementTest(ArrayClass, tp)(_.typeSymbol == elem)
+ def elementType(container: Symbol, tp: Type): Type = elementExtract(container, tp)
+ object ExprClassOf { def unapply(tp: Type): Option[Type] = elementExtractOption(ExprClass, tp) }
// collections classes
lazy val ConsClass = requiredClass[scala.collection.immutable.::[_]]
@@ -514,13 +496,6 @@ trait Definitions extends api.StandardDefinitions {
lazy val ExprClass = ExprsClass.map(sym => getMemberClass(sym, tpnme.Expr))
def ExprSplice = ExprClass.map(sym => getMemberMethod(sym, nme.splice))
def ExprValue = ExprClass.map(sym => getMemberMethod(sym, nme.value))
- object ExprClassOf {
- def unapply(tpe: Type): Option[Type] = tpe.dealias match {
- case ExistentialType(_, underlying) => unapply(underlying)
- case TypeRef(_, ExprClass, t :: Nil) => Some(t)
- case _ => None
- }
- }
lazy val ClassTagModule = requiredModule[scala.reflect.ClassTag[_]]
lazy val ClassTagClass = requiredClass[scala.reflect.ClassTag[_]]
@@ -709,11 +684,6 @@ trait Definitions extends api.StandardDefinitions {
(sym eq PartialFunctionClass) || (sym eq AbstractPartialFunctionClass)
}
- def elementType(container: Symbol, tp: Type): Type = tp match {
- case TypeRef(_, `container`, arg :: Nil) => arg
- case _ => NoType
- }
-
def arrayType(arg: Type) = appliedType(ArrayClass, arg)
def byNameType(arg: Type) = appliedType(ByNameParamClass, arg)
def iteratorOfType(tp: Type) = appliedType(IteratorClass, tp)
diff --git a/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala b/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala
index 6251849182..073f124630 100644
--- a/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala
+++ b/src/reflect/scala/reflect/internal/ExistentialsAndSkolems.scala
@@ -77,14 +77,14 @@ trait ExistentialsAndSkolems {
* also replaced, except for term symbols of an Ident tree, where
* only the type of the Ident is changed.
*/
- final def existentialTransform[T](rawSyms: List[Symbol], tp: Type, rawOwner: Option[Symbol] = None)(creator: (List[Symbol], Type) => T): T = {
+ final def existentialTransform[T](rawSyms: List[Symbol], tp: Type, rawOwner: Symbol = NoSymbol)(creator: (List[Symbol], Type) => T): T = {
val allBounds = existentialBoundsExcludingHidden(rawSyms)
val typeParams: List[Symbol] = rawSyms map { sym =>
val name = sym.name match {
case x: TypeName => x
case x => tpnme.singletonName(x)
}
- def rawOwner0 = rawOwner.getOrElse(abort(s"no owner provided for existential transform over raw parameter: $sym"))
+ def rawOwner0 = rawOwner orElse abort(s"no owner provided for existential transform over raw parameter: $sym")
val bound = allBounds(sym)
val sowner = if (isRawParameter(sym)) rawOwner0 else sym.owner
val quantified = sowner.newExistential(name, sym.pos)
@@ -106,7 +106,7 @@ trait ExistentialsAndSkolems {
* @param hidden The original type
* @param rawOwner The owner for Java raw types.
*/
- final def packSymbols(hidden: List[Symbol], tp: Type, rawOwner: Option[Symbol] = None): Type =
+ final def packSymbols(hidden: List[Symbol], tp: Type, rawOwner: Symbol = NoSymbol): Type =
if (hidden.isEmpty) tp
else existentialTransform(hidden, tp, rawOwner)(existentialAbstraction)
}
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index db5250b7f3..c3596fe62e 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -3415,6 +3415,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
def mapParamss[T](sym: Symbol)(f: Symbol => T): List[List[T]] = mmap(sym.info.paramss)(f)
+ def existingSymbols(syms: List[Symbol]): List[Symbol] =
+ syms filter (s => (s ne null) && (s ne NoSymbol))
+
/** Return closest enclosing method, unless shadowed by an enclosing class. */
// TODO Move back to ExplicitOuter when the other call site is removed.
// no use of closures here in the interest of speed.
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index 6abf344adb..b75fd72526 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -137,20 +137,20 @@ abstract class TreeGen extends macros.TreeBuilder {
/** Replaces tree type with a stable type if possible */
def stabilize(tree: Tree): Tree = stableTypeFor(tree) match {
- case Some(tp) => tree setType tp
- case _ => tree
+ case NoType => tree
+ case tp => tree setType tp
}
/** Computes stable type for a tree if possible */
- def stableTypeFor(tree: Tree): Option[Type] =
- if (treeInfo.admitsTypeSelection(tree))
- tree match {
- case This(_) => Some(ThisType(tree.symbol))
- case Ident(_) => Some(singleType(tree.symbol.owner.thisType, tree.symbol))
- case Select(qual, _) => Some(singleType(qual.tpe, tree.symbol))
- case _ => None
- }
- else None
+ def stableTypeFor(tree: Tree): Type = (
+ if (!treeInfo.admitsTypeSelection(tree)) NoType
+ else tree match {
+ case This(_) => ThisType(tree.symbol)
+ case Ident(_) => singleType(tree.symbol.owner.thisType, tree.symbol)
+ case Select(qual, _) => singleType(qual.tpe, tree.symbol)
+ case _ => NoType
+ }
+ )
/** Builds a reference with stable type to given symbol */
def mkAttributedStableRef(pre: Type, sym: Symbol): Tree =
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index d1e8a04553..3a8d3fd460 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -837,11 +837,12 @@ abstract class TreeInfo {
def unapply(tree: Tree) = refPart(tree) match {
case ref: RefTree => {
- val isBundle = definitions.isMacroBundleType(ref.qualifier.tpe)
+ val qual = ref.qualifier
+ val isBundle = definitions.isMacroBundleType(qual.tpe)
val owner =
- if (isBundle) ref.qualifier.tpe.typeSymbol
+ if (isBundle) qual.tpe.typeSymbol
else {
- val sym = ref.qualifier.symbol
+ val sym = if (qual.hasSymbolField) qual.symbol else NoSymbol
if (sym.isModule) sym.moduleClass else sym
}
Some((isBundle, owner, ref.symbol, dissectApplied(tree).targs))
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 5c9665cdc7..967146a130 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -2455,6 +2455,7 @@ trait Types
else
super.prefixString
)
+ def copy(pre: Type = this.pre, sym: Symbol = this.sym, args: List[Type] = this.args) = TypeRef(pre, sym, args)
override def kind = "TypeRef"
}
@@ -3718,6 +3719,43 @@ trait Types
object unwrapToStableClass extends ClassUnwrapper(existential = false) { }
object unwrapWrapperTypes extends TypeUnwrapper(true, true, true, true) { }
+ def elementExtract(container: Symbol, tp: Type): Type = {
+ assert(!container.isAliasType, container)
+ unwrapWrapperTypes(tp baseType container).dealiasWiden match {
+ case TypeRef(_, `container`, arg :: Nil) => arg
+ case _ => NoType
+ }
+ }
+ def elementExtractOption(container: Symbol, tp: Type): Option[Type] = {
+ elementExtract(container, tp) match {
+ case NoType => None
+ case tp => Some(tp)
+ }
+ }
+ def elementTest(container: Symbol, tp: Type)(f: Type => Boolean): Boolean = {
+ elementExtract(container, tp) match {
+ case NoType => false
+ case tp => f(tp)
+ }
+ }
+ def elementTransform(container: Symbol, tp: Type)(f: Type => Type): Type = {
+ elementExtract(container, tp) match {
+ case NoType => NoType
+ case tp => f(tp)
+ }
+ }
+
+ def transparentShallowTransform(container: Symbol, tp: Type)(f: Type => Type): Type = {
+ def loop(tp: Type): Type = tp match {
+ case tp @ AnnotatedType(_, underlying, _) => tp.copy(underlying = loop(underlying))
+ case tp @ ExistentialType(_, underlying) => tp.copy(underlying = loop(underlying))
+ case tp @ PolyType(_, resultType) => tp.copy(resultType = loop(resultType))
+ case tp @ NullaryMethodType(resultType) => tp.copy(resultType = loop(resultType))
+ case tp => elementTransform(container, tp)(el => appliedType(container, f(el))).orElse(f(tp))
+ }
+ loop(tp)
+ }
+
/** Repack existential types, otherwise they sometimes get unpacked in the
* wrong location (type inference comes up with an unexpected skolem)
*/
@@ -4342,12 +4380,11 @@ trait Types
/** Compute lub (if `variance == Covariant`) or glb (if `variance == Contravariant`) of given list
* of types `tps`. All types in `tps` are typerefs or singletypes
* with the same symbol.
- * Return `Some(x)` if the computation succeeds with result `x`.
- * Return `None` if the computation fails.
+ * Return `x` if the computation succeeds with result `x`.
+ * Return `NoType` if the computation fails.
*/
- def mergePrefixAndArgs(tps: List[Type], variance: Variance, depth: Int): Option[Type] = tps match {
- case List(tp) =>
- Some(tp)
+ def mergePrefixAndArgs(tps: List[Type], variance: Variance, depth: Int): Type = tps match {
+ case tp :: Nil => tp
case TypeRef(_, sym, _) :: rest =>
val pres = tps map (_.prefix) // prefix normalizes automatically
val pre = if (variance.isPositive) lub(pres, depth) else glb(pres, depth)
@@ -4359,12 +4396,13 @@ trait Types
// if argss contain one value type and some other type, the lub is Object
// if argss contain several reference types, the lub is an array over lub of argtypes
if (argss exists typeListIsEmpty) {
- None // something is wrong: an array without a type arg.
- } else {
+ NoType // something is wrong: an array without a type arg.
+ }
+ else {
val args = argss map (_.head)
- if (args.tail forall (_ =:= args.head)) Some(typeRef(pre, sym, List(args.head)))
- else if (args exists (arg => isPrimitiveValueClass(arg.typeSymbol))) Some(ObjectTpe)
- else Some(typeRef(pre, sym, List(lub(args))))
+ if (args.tail forall (_ =:= args.head)) typeRef(pre, sym, List(args.head))
+ else if (args exists (arg => isPrimitiveValueClass(arg.typeSymbol))) ObjectTpe
+ else typeRef(pre, sym, List(lub(args)))
}
}
else transposeSafe(argss) match {
@@ -4373,7 +4411,7 @@ trait Types
// catching just in case (shouldn't happen, but also doesn't cost us)
// [JZ] It happens: see SI-5683.
debuglog(s"transposed irregular matrix!? tps=$tps argss=$argss")
- None
+ NoType
case Some(argsst) =>
val args = map2(sym.typeParams, argsst) { (tparam, as0) =>
val as = as0.distinct
@@ -4404,22 +4442,22 @@ trait Types
}
}
}
- if (args contains NoType) None
- else Some(existentialAbstraction(capturedParams.toList, typeRef(pre, sym, args)))
+ if (args contains NoType) NoType
+ else existentialAbstraction(capturedParams.toList, typeRef(pre, sym, args))
}
} catch {
- case ex: MalformedType => None
+ case ex: MalformedType => NoType
}
case SingleType(_, sym) :: rest =>
val pres = tps map (_.prefix)
val pre = if (variance.isPositive) lub(pres, depth) else glb(pres, depth)
- try {
- Some(singleType(pre, sym))
- } catch {
- case ex: MalformedType => None
- }
+ try singleType(pre, sym)
+ catch { case ex: MalformedType => NoType }
case ExistentialType(tparams, quantified) :: rest =>
- mergePrefixAndArgs(quantified :: rest, variance, depth) map (existentialAbstraction(tparams, _))
+ mergePrefixAndArgs(quantified :: rest, variance, depth) match {
+ case NoType => NoType
+ case tpe => existentialAbstraction(tparams, tpe)
+ }
case _ =>
abort(s"mergePrefixAndArgs($tps, $variance, $depth): unsupported tps")
}
diff --git a/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala b/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala
index 0a7a2a127c..1d3c6b0f23 100644
--- a/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala
+++ b/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala
@@ -125,8 +125,8 @@ private[internal] trait GlbLubs {
}
val tails = tsBts map (_.tail)
mergePrefixAndArgs(elimSub(ts1, depth) map elimHigherOrderTypeParam, Covariant, depth) match {
- case Some(tp) => loop(tp :: pretypes, tails)
- case _ => loop(pretypes, tails)
+ case NoType => loop(pretypes, tails)
+ case tp => loop(tp :: pretypes, tails)
}
}
else {
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index a3684f602f..16405a88b4 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -581,15 +581,10 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
loadBytes[Array[String]]("scala.reflect.ScalaLongSignature") match {
case Some(slsig) =>
info(s"unpickling Scala $clazz and $module with long Scala signature")
- val byteSegments = slsig map (_.getBytes)
- val lens = byteSegments map ByteCodecs.decode
- val bytes = Array.ofDim[Byte](lens.sum)
- var len = 0
- for ((bs, l) <- byteSegments zip lens) {
- bs.copyToArray(bytes, len, l)
- len += l
- }
- unpickler.unpickle(bytes, 0, clazz, module, jclazz.getName)
+ val encoded = slsig flatMap (_.getBytes)
+ val len = ByteCodecs.decode(encoded)
+ val decoded = encoded.take(len)
+ unpickler.unpickle(decoded, 0, clazz, module, jclazz.getName)
case None =>
// class does not have a Scala signature; it's a Java class
info("translating reflection info for Java " + jclazz) //debug
diff --git a/src/repl/scala/tools/nsc/interpreter/ILoop.scala b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
index 9f841f2c44..8ec8b2ed5f 100644
--- a/src/repl/scala/tools/nsc/interpreter/ILoop.scala
+++ b/src/repl/scala/tools/nsc/interpreter/ILoop.scala
@@ -642,10 +642,6 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
}
private def loopPostInit() {
- in match {
- case x: JLineReader => x.consoleReader.postInit
- case _ =>
- }
// Bind intp somewhere out of the regular namespace where
// we can get at it in generated code.
intp.quietBind(NamedParam[IMain]("$intp", intp)(tagOfIMain, classTag[IMain]))
@@ -661,6 +657,11 @@ class ILoop(in0: Option[BufferedReader], protected val out: JPrintWriter)
unleashAndSetPhase()
asyncMessage(power.banner)
}
+ // SI-7418 Now, and only now, can we enable TAB completion.
+ in match {
+ case x: JLineReader => x.consoleReader.postInit
+ case _ =>
+ }
}
def process(settings: Settings): Boolean = savingContextLoader {
this.settings = settings
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala
index 159e16375c..f6373e9e97 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/HtmlPage.scala
@@ -42,8 +42,7 @@ abstract class HtmlPage extends Page { thisPage =>
def body: NodeSeq
def writeFor(site: HtmlFactory) {
- val doctype =
- DocType("html", PublicID("-//W3C//DTD XHTML 1.1//EN", "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd"), Nil)
+ val doctype = DocType("html")
val html =
<html>
<head>
@@ -57,7 +56,6 @@ abstract class HtmlPage extends Page { thisPage =>
</html>
writeFile(site) { (w: Writer) =>
- w.write("<?xml version='1.0' encoding='" + site.encoding + "'?>\n")
w.write(doctype.toString + "\n")
w.write(xml.Xhtml.toXhtml(html))
}
@@ -67,8 +65,6 @@ abstract class HtmlPage extends Page { thisPage =>
// we're only interested in the body, as this will go into the diff
_.write(body.text)
}
-
- //XML.save(pageFile.getPath, html, site.encoding, xmlDecl = false, doctype = doctype)
}
/** Transforms an optional comment into an styled HTML tree representing its body if it is defined, or into an empty
diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala
index c034647320..ce3a5eb1fc 100644
--- a/src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala
+++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Index.scala
@@ -35,10 +35,10 @@ class Index(universe: doc.Universe, val index: doc.Index) extends HtmlPage {
val body =
<body>
<div id="library">
- <img class='class icon' src={ relativeLinkTo{List("class.png", "lib")} }/>
- <img class='trait icon' src={ relativeLinkTo{List("trait.png", "lib")} }/>
- <img class='object icon' src={ relativeLinkTo{List("object.png", "lib")} }/>
- <img class='package icon' src={ relativeLinkTo{List("package.png", "lib")} }/>
+ <img class='class icon' alt='class icon' src={ relativeLinkTo{List("class.png", "lib")} }/>
+ <img class='trait icon' alt='trait icon' src={ relativeLinkTo{List("trait.png", "lib")} }/>
+ <img class='object icon' alt='trait icon' src={ relativeLinkTo{List("object.png", "lib")} }/>
+ <img class='package icon' alt='trait icon' src={ relativeLinkTo{List("package.png", "lib")} }/>
</div>
{ browser }
<div id="content" class="ui-layout-center">