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/backend/jvm/GenASM.scala8
-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/Macros.scala27
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala7
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala30
-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/partest/scala/tools/partest/BytecodeTest.scala35
-rw-r--r--src/partest/scala/tools/partest/DirectTest.scala27
-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
31 files changed, 318 insertions, 203 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/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 7edcc944e1..19a6e11986 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -1270,9 +1270,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 +1295,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/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..8d422f415d 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)
@@ -3185,7 +3186,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 +3195,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 +3216,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 +3224,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 +3277,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 +3313,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 +3731,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 &&
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/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/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 f3cea1fd00..2da9fa1cca 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -3413,6 +3413,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">