summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/actors-migration/scala/actors/Pattern.scala1
-rw-r--r--src/actors-migration/scala/actors/StashingActor.scala1
-rw-r--r--src/actors-migration/scala/actors/Timeout.scala1
-rw-r--r--src/actors/scala/actors/AbstractActor.scala3
-rw-r--r--src/actors/scala/actors/Actor.scala3
-rw-r--r--src/actors/scala/actors/CanReply.scala3
-rw-r--r--src/actors/scala/actors/Combinators.scala2
-rw-r--r--src/actors/scala/actors/MQueue.scala2
-rw-r--r--src/actors/scala/actors/Reactor.scala1
-rw-r--r--src/build/maven/scala-library-pom.xml4
-rw-r--r--src/compiler/scala/tools/cmd/CommandLine.scala1
-rw-r--r--src/compiler/scala/tools/cmd/FromString.scala2
-rw-r--r--src/compiler/scala/tools/cmd/package.scala4
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala13
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala20
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala11
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala6
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala25
-rw-r--r--src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala2
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/LinkTo.scala (renamed from src/compiler/scala/tools/nsc/doc/model/Links.scala)0
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interactive/CompilerControl.scala15
-rw-r--r--src/compiler/scala/tools/nsc/interactive/Global.scala12
-rw-r--r--src/compiler/scala/tools/nsc/interactive/REPL.scala13
-rw-r--r--src/compiler/scala/tools/nsc/interactive/RangePositions.scala48
-rw-r--r--src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala12
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaScanners.scala2
-rw-r--r--src/compiler/scala/tools/nsc/matching/Patterns.scala2
-rw-r--r--src/compiler/scala/tools/nsc/scratchpad/Executor.scala55
-rw-r--r--src/compiler/scala/tools/nsc/scratchpad/Mixer.scala98
-rw-r--r--src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala14
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala47
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala50
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala13
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala200
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala105
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala59
-rw-r--r--src/compiler/scala/tools/nsc/util/InterruptReq.scala11
-rw-r--r--src/compiler/scala/tools/nsc/util/WorkScheduler.scala7
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala2
-rw-r--r--src/library/scala/StringContext.scala24
-rw-r--r--src/library/scala/collection/GenTraversableOnce.scala1
-rw-r--r--src/library/scala/collection/TraversableLike.scala1
-rw-r--r--src/library/scala/collection/concurrent/TrieMap.scala8
-rw-r--r--src/library/scala/collection/parallel/ParIterableLike.scala2
-rw-r--r--src/library/scala/math/Ordering.scala2
-rw-r--r--src/library/scala/reflect/ClassManifestDeprecatedApis.scala (renamed from src/library/scala/reflect/ClassManifest.scala)0
-rw-r--r--src/library/scala/reflect/base/Base.scala23
-rw-r--r--src/library/scala/reflect/base/Names.scala2
-rw-r--r--src/library/scala/reflect/base/StandardNames.scala17
-rw-r--r--src/library/scala/reflect/base/Types.scala17
-rw-r--r--src/library/scala/runtime/Tuple2Zipped.scala1
-rw-r--r--src/library/scala/runtime/Tuple3Zipped.scala1
-rw-r--r--src/library/scala/runtime/WorksheetSupport.scala87
-rw-r--r--src/library/scala/util/Try.scala6
-rw-r--r--src/library/scala/xml/dtd/ElementValidator.scala1
-rw-r--r--src/partest/scala/tools/partest/DirectTest.scala2
-rw-r--r--src/partest/scala/tools/partest/ScaladocModelTest.scala26
-rw-r--r--src/partest/scala/tools/partest/instrumented/Instrumentation.scala10
-rw-r--r--src/partest/scala/tools/partest/instrumented/Profiler.java4
-rw-r--r--src/partest/scala/tools/partest/javaagent/ASMTransformer.java4
-rw-r--r--src/partest/scala/tools/partest/nest/RunnerManager.scala6
-rw-r--r--src/partest/scala/tools/partest/package.scala5
-rw-r--r--src/reflect/scala/reflect/api/Names.scala3
-rw-r--r--src/reflect/scala/reflect/api/StandardNames.scala140
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala25
-rw-r--r--src/reflect/scala/reflect/api/Types.scala9
-rw-r--r--src/reflect/scala/reflect/internal/BaseTypeSeqs.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala10
-rw-r--r--src/reflect/scala/reflect/internal/Positions.scala14
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala13
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala276
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala10
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala30
-rw-r--r--src/reflect/scala/reflect/internal/util/Origins.scala2
-rw-r--r--src/reflect/scala/reflect/internal/util/SourceFile.scala4
-rw-r--r--src/reflect/scala/reflect/internal/util/TableDef.scala1
-rw-r--r--src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala29
-rw-r--r--src/reflect/scala/reflect/makro/Universe.scala11
-rw-r--r--src/reflect/scala/reflect/runtime/ReflectionUtils.scala2
-rw-r--r--src/reflect/scala/reflect/runtime/TwoWayCache.scala38
-rw-r--r--src/reflect/scala/tools/nsc/io/File.scala6
-rw-r--r--src/reflect/scala/tools/nsc/io/Path.scala2
-rw-r--r--src/reflect/scala/tools/nsc/io/Streamable.scala2
-rw-r--r--src/reflect/scala/tools/nsc/io/VirtualDirectory.scala2
-rw-r--r--src/scalap/scala/tools/scalap/Arguments.scala2
-rw-r--r--src/scalap/scala/tools/scalap/CodeWriter.scala4
-rw-r--r--src/scalap/scala/tools/scalap/Decode.scala4
-rw-r--r--src/scalap/scala/tools/scalap/MetaParser.scala2
-rw-r--r--src/scalap/scala/tools/scalap/scalax/rules/package.scala9
-rw-r--r--src/swing/scala/swing/Action.scala2
-rw-r--r--src/swing/scala/swing/ComboBox.scala4
-rw-r--r--src/swing/scala/swing/GridBagPanel.scala3
-rw-r--r--src/swing/scala/swing/RichWindow.scala4
-rw-r--r--src/swing/scala/swing/ScrollPane.scala6
-rw-r--r--src/swing/scala/swing/Swing.scala1
-rw-r--r--src/swing/scala/swing/UIElement.scala2
-rw-r--r--src/swing/scala/swing/Window.scala2
-rw-r--r--src/swing/scala/swing/package.scala3
105 files changed, 893 insertions, 927 deletions
diff --git a/src/actors-migration/scala/actors/Pattern.scala b/src/actors-migration/scala/actors/Pattern.scala
index 97dbd2cccd..26e9d1bb64 100644
--- a/src/actors-migration/scala/actors/Pattern.scala
+++ b/src/actors-migration/scala/actors/Pattern.scala
@@ -1,6 +1,7 @@
package scala.actors
import scala.concurrent.util.Duration
+import language.implicitConversions
object pattern {
diff --git a/src/actors-migration/scala/actors/StashingActor.scala b/src/actors-migration/scala/actors/StashingActor.scala
index 37300f9d63..8f96e1b002 100644
--- a/src/actors-migration/scala/actors/StashingActor.scala
+++ b/src/actors-migration/scala/actors/StashingActor.scala
@@ -3,6 +3,7 @@ package scala.actors
import scala.collection._
import scala.concurrent.util.Duration
import java.util.concurrent.TimeUnit
+import language.implicitConversions
object StashingActor extends Combinators {
implicit def mkBody[A](body: => A) = new InternalActor.Body[A] {
diff --git a/src/actors-migration/scala/actors/Timeout.scala b/src/actors-migration/scala/actors/Timeout.scala
index 0d9532a14b..7e400ab140 100644
--- a/src/actors-migration/scala/actors/Timeout.scala
+++ b/src/actors-migration/scala/actors/Timeout.scala
@@ -10,6 +10,7 @@ package scala.actors
import scala.concurrent.util.Duration
import java.util.concurrent.TimeUnit
+import language.implicitConversions
case class Timeout(duration: Duration) {
def this(timeout: Long) = this(Duration(timeout, TimeUnit.MILLISECONDS))
diff --git a/src/actors/scala/actors/AbstractActor.scala b/src/actors/scala/actors/AbstractActor.scala
index 3817f9cda3..dec91859bb 100644
--- a/src/actors/scala/actors/AbstractActor.scala
+++ b/src/actors/scala/actors/AbstractActor.scala
@@ -6,9 +6,10 @@
** |/ **
\* */
-
package scala.actors
+import language.higherKinds
+
/**
* @author Philipp Haller
*
diff --git a/src/actors/scala/actors/Actor.scala b/src/actors/scala/actors/Actor.scala
index bc9bbc6ef0..0b1e7fb1e9 100644
--- a/src/actors/scala/actors/Actor.scala
+++ b/src/actors/scala/actors/Actor.scala
@@ -1,5 +1,3 @@
-
-
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2005-2011, LAMP/EPFL **
@@ -12,6 +10,7 @@ package scala.actors
import scala.util.control.ControlThrowable
import java.util.{Timer, TimerTask}
+import language.implicitConversions
/**
* Provides functions for the definition of actors, as well as actor
diff --git a/src/actors/scala/actors/CanReply.scala b/src/actors/scala/actors/CanReply.scala
index 5053f43e94..9bf0022247 100644
--- a/src/actors/scala/actors/CanReply.scala
+++ b/src/actors/scala/actors/CanReply.scala
@@ -6,9 +6,10 @@
** |/ **
\* */
-
package scala.actors
+import language.higherKinds
+
/**
* Defines result-bearing message send operations.
*
diff --git a/src/actors/scala/actors/Combinators.scala b/src/actors/scala/actors/Combinators.scala
index c1a9095614..dd704436fc 100644
--- a/src/actors/scala/actors/Combinators.scala
+++ b/src/actors/scala/actors/Combinators.scala
@@ -10,6 +10,8 @@
package scala.actors
+import language.implicitConversions
+
private[actors] trait Combinators {
/**
diff --git a/src/actors/scala/actors/MQueue.scala b/src/actors/scala/actors/MQueue.scala
index 4a148d2cb3..43074649fd 100644
--- a/src/actors/scala/actors/MQueue.scala
+++ b/src/actors/scala/actors/MQueue.scala
@@ -121,7 +121,7 @@ private[actors] class MQueue[Msg >: Null](protected val label: String) {
* or `'''null'''` if `p` fails for all of them.
*/
def extractFirst(p: (Msg, OutputChannel[Any]) => Boolean): MQueueElement[Msg] =
- removeInternal(0)(p) orNull
+ removeInternal(0)(p).orNull
def extractFirst(pf: PartialFunction[Msg, Any]): MQueueElement[Msg] = {
if (isEmpty) // early return
diff --git a/src/actors/scala/actors/Reactor.scala b/src/actors/scala/actors/Reactor.scala
index 7a8d738758..c962bb9d3d 100644
--- a/src/actors/scala/actors/Reactor.scala
+++ b/src/actors/scala/actors/Reactor.scala
@@ -12,6 +12,7 @@ package scala.actors
import scala.actors.scheduler.{DelegatingScheduler, ExecutorScheduler,
ForkJoinScheduler, ThreadPoolConfig}
import java.util.concurrent.{ThreadPoolExecutor, TimeUnit, LinkedBlockingQueue}
+import language.implicitConversions
private[actors] object Reactor {
diff --git a/src/build/maven/scala-library-pom.xml b/src/build/maven/scala-library-pom.xml
index e8db512125..d1192b2dd8 100644
--- a/src/build/maven/scala-library-pom.xml
+++ b/src/build/maven/scala-library-pom.xml
@@ -31,11 +31,11 @@
<url>https://issues.scala-lang.org/</url>
</issueManagement>
<dependencies>
- <dependency>
+ <!--<dependency>
<groupId>com.typesafe</groupId>
<artifactId>config</artifactId>
<version>0.4.0</version>
- </dependency>
+ </dependency>-->
</dependencies>
<distributionManagement>
<repository>
diff --git a/src/compiler/scala/tools/cmd/CommandLine.scala b/src/compiler/scala/tools/cmd/CommandLine.scala
index d9a74a698c..ced3a97380 100644
--- a/src/compiler/scala/tools/cmd/CommandLine.scala
+++ b/src/compiler/scala/tools/cmd/CommandLine.scala
@@ -7,7 +7,6 @@ package scala.tools
package cmd
import scala.collection.mutable.ListBuffer
-import language.postfixOps
trait CommandLineConfig {
def enforceArity: Boolean = true
diff --git a/src/compiler/scala/tools/cmd/FromString.scala b/src/compiler/scala/tools/cmd/FromString.scala
index 415940b3fd..d473796f39 100644
--- a/src/compiler/scala/tools/cmd/FromString.scala
+++ b/src/compiler/scala/tools/cmd/FromString.scala
@@ -43,7 +43,7 @@ object FromString {
else cmd.runAndExit(println("'%s' is not an existing directory." format s))
}
def ExistingDirRelativeTo(root: Directory) = new FromString[Directory]()(tagOfDirectory) {
- private def resolve(s: String) = toDir(s) toAbsoluteWithRoot root toDirectory
+ private def resolve(s: String) = (toDir(s) toAbsoluteWithRoot root).toDirectory
override def isDefinedAt(s: String) = resolve(s).isDirectory
def apply(s: String): Directory =
if (isDefinedAt(s)) resolve(s)
diff --git a/src/compiler/scala/tools/cmd/package.scala b/src/compiler/scala/tools/cmd/package.scala
index 5786b00fd1..8e74e6169e 100644
--- a/src/compiler/scala/tools/cmd/package.scala
+++ b/src/compiler/scala/tools/cmd/package.scala
@@ -8,6 +8,10 @@ package scala.tools
package object cmd {
def returning[T](x: T)(f: T => Unit): T = { f(x) ; x }
+ // make some language features in this package compile without warning
+ implicit def implicitConversions = language.implicitConversions
+ implicit def postfixOps = language.postfixOps
+
private[cmd] def debug(msg: String) = println(msg)
def runAndExit(body: => Unit): Nothing = {
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 1d29e33c50..9a6d32be01 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -95,11 +95,12 @@ trait Trees extends reflect.internal.Trees { self: Global =>
val (edefs, rest) = body span treeInfo.isEarlyDef
val (evdefs, etdefs) = edefs partition treeInfo.isEarlyValDef
val gvdefs = evdefs map {
- case vdef @ ValDef(_, _, tpt, _) => copyValDef(vdef)(
- // !!! I know "atPos in case" wasn't intentionally planted to
- // add an air of mystery to this file, but it is the sort of
- // comment which only its author could love.
- tpt = atPos(vdef.pos.focus)(TypeTree() setOriginal tpt setPos tpt.pos.focus), // atPos in case
+ case vdef @ ValDef(_, _, tpt, _) =>
+ copyValDef(vdef)(
+ // atPos for the new tpt is necessary, since the original tpt might have no position
+ // (when missing type annotation for ValDef for example), so even though setOriginal modifies the
+ // position of TypeTree, it would still be NoPosition. That's what the author meant.
+ tpt = atPos(vdef.pos.focus)(TypeTree() setOriginal tpt setPos tpt.pos.focus),
rhs = EmptyTree
)
}
@@ -125,7 +126,7 @@ trait Trees extends reflect.internal.Trees { self: Global =>
DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant())))))
}
}
- constrs foreach (ensureNonOverlapping(_, parents ::: gvdefs))
+ constrs foreach (ensureNonOverlapping(_, parents ::: gvdefs, focus=false))
// Field definitions for the class - remove defaults.
val fieldDefs = vparamss.flatten map (vd => copyValDef(vd)(mods = vd.mods &~ DEFAULTPARAM, rhs = EmptyTree))
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index 982267097b..c46b650949 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -73,6 +73,14 @@ abstract class GenICode extends SubComponent {
ctx1
}
+ /** If the selector type has a member with the right name,
+ * it is the host class; otherwise the symbol's owner.
+ */
+ def findHostClass(selector: Type, sym: Symbol) = selector member sym.name match {
+ case NoSymbol => log(s"Rejecting $selector as host class for $sym") ; sym.owner
+ case _ => selector.typeSymbol
+ }
+
/////////////////// Code generation ///////////////////////
def gen(tree: Tree, ctx: Context): Context = tree match {
@@ -949,13 +957,14 @@ abstract class GenICode extends SubComponent {
*/
fun match {
case Select(qual, _) =>
- val qualSym = qual.tpe.typeSymbol
+ val qualSym = findHostClass(qual.tpe, sym)
+
if (qualSym == ArrayClass) cm setTargetTypeKind toTypeKind(qual.tpe)
else cm setHostClass qualSym
- debuglog(
+ log(
if (qualSym == ArrayClass) "Stored target type kind " + toTypeKind(qual.tpe) + " for " + sym.fullName
- else "Set more precise host class for " + sym.fullName + " host: " + qualSym
+ else s"Set more precise host class for ${sym.fullName} hostClass: $qualSym"
)
case _ =>
}
@@ -1005,13 +1014,14 @@ abstract class GenICode extends SubComponent {
case Select(qualifier, selector) =>
val sym = tree.symbol
generatedType = toTypeKind(sym.info)
- val hostClass = qualifier.tpe.typeSymbol.orElse(sym.owner)
+ val hostClass = findHostClass(qualifier.tpe, sym)
+ log(s"Host class of $sym with qual $qualifier (${qualifier.tpe}) is $hostClass")
if (sym.isModule) {
genLoadModule(ctx, tree)
}
else if (sym.isStaticMember) {
- ctx.bb.emit(LOAD_FIELD(sym, true) setHostClass hostClass, tree.pos)
+ ctx.bb.emit(LOAD_FIELD(sym, true) setHostClass hostClass, tree.pos)
ctx
}
else {
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
index 7a5615ac26..962c47f443 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
@@ -470,6 +470,8 @@ abstract class TypeFlowAnalysis {
val isOnWatchlist = mutable.Set.empty[Instruction]
+ val warnIfInlineFails = mutable.Set.empty[opcodes.CALL_METHOD] // cache for a given IMethod (ie cleared on Inliner.analyzeMethod).
+
/* Each time CallerCalleeInfo.isSafeToInline determines a concrete callee is unsafe to inline in the current caller,
the fact is recorded in this TFA instance for the purpose of avoiding devoting processing to that callsite next time.
The condition of "being unsafe to inline in the current caller" sticks across inlinings and TFA re-inits
@@ -510,6 +512,7 @@ abstract class TypeFlowAnalysis {
// initially populate the watchlist with all callsites standing a chance of being inlined
isOnWatchlist.clear()
relevantBBs.clear()
+ warnIfInlineFails.clear()
/* TODO Do we want to perform inlining in non-finally exception handlers?
* Seems counterproductive (the larger the method the less likely it will be JITed.
* It's not that putting on radar only `linearizer linearizeAt (m, m.startBlock)` makes for much shorter inlining times (a minor speedup nonetheless)
@@ -533,11 +536,11 @@ abstract class TypeFlowAnalysis {
private def putOnRadar(blocks: Traversable[BasicBlock]) {
for(bb <- blocks) {
- val preCands = bb.toList collect {
- case cm : opcodes.CALL_METHOD
- if isPreCandidate(cm) /* && !isReceiverKnown(cm) */
- => cm
+ val calls = bb.toList collect { case cm : opcodes.CALL_METHOD => cm }
+ for(c <- calls; if(inliner.hasInline(c.method))) {
+ warnIfInlineFails += c
}
+ val preCands = calls filter isPreCandidate
isOnWatchlist ++= preCands
}
relevantBBs ++= blocks
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 025046f19e..e590a0b691 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -1159,7 +1159,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
val linkedClass = moduleClass.companionClass
val linkedModule = linkedClass.companionSymbol
lazy val conflictingNames: Set[Name] = {
- linkedClass.info.members collect { case sym if sym.name.isTermName => sym.name } toSet
+ (linkedClass.info.members collect { case sym if sym.name.isTermName => sym.name }).toSet
}
debuglog("Potentially conflicting names for forwarders: " + conflictingNames)
@@ -1351,7 +1351,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
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 = (superInterfaces0 ++ c.symbol.annotations.flatMap(ann => newParentForAttr(ann.symbol))).distinct
if(superInterfaces.isEmpty) EMPTY_STRING_ARRAY
else mkArray(minimizeInterfaces(superInterfaces) map javaName)
@@ -3183,7 +3183,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
hops ::= prev
if (hops.contains(dest)) {
// leave infinite-loops in place
- return (dest, hops filterNot (dest eq))
+ return (dest, hops filterNot (dest eq _))
}
prev = dest;
false
diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
index 44acfed411..cce18d436f 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala
@@ -129,11 +129,15 @@ abstract class Inliners extends SubComponent {
override def apply(c: IClass) { queue += c }
override def run() {
+ knownLacksInline.clear()
+ knownHasInline.clear()
try {
super.run()
for(c <- queue) { inliner analyzeClass c }
} finally {
inliner.clearCaches()
+ knownLacksInline.clear()
+ knownHasInline.clear()
}
}
}
@@ -157,7 +161,21 @@ abstract class Inliners extends SubComponent {
}
}
- def hasInline(sym: Symbol) = sym hasAnnotation ScalaInlineClass
+ val knownLacksInline = mutable.Set.empty[Symbol] // cache to avoid multiple inliner.hasInline() calls.
+ val knownHasInline = mutable.Set.empty[Symbol] // as above. Motivated by the need to warn on "inliner failures".
+
+ def hasInline(sym: Symbol) = {
+ if (knownLacksInline(sym)) false
+ else if(knownHasInline(sym)) true
+ else {
+ val b = (sym hasAnnotation ScalaInlineClass)
+ if(b) { knownHasInline += sym }
+ else { knownLacksInline += sym }
+
+ b
+ }
+ }
+
def hasNoInline(sym: Symbol) = sym hasAnnotation ScalaNoInlineClass
/**
@@ -536,6 +554,10 @@ abstract class Inliners extends SubComponent {
}
while (retry && count < MAX_INLINE_RETRY)
+ for(inlFail <- tfa.warnIfInlineFails) {
+ warn(inlFail.pos, "At the end of the day, could not inline @inline-marked method " + inlFail.method.originalName.decode)
+ }
+
m.normalize
if (sizeBeforeInlining > 0) {
val instrAfterInlining = m.code.instructionCount
@@ -731,6 +753,7 @@ abstract class Inliners extends SubComponent {
tfa.remainingCALLs.remove(instr) // this bookkpeeping is done here and not in MTFAGrowable.reinit due to (1st) convenience and (2nd) necessity.
tfa.isOnWatchlist.remove(instr) // ditto
+ tfa.warnIfInlineFails.remove(instr)
val targetPos = instr.pos
log("Inlining " + inc.m + " in " + caller.m + " at pos: " + posToStr(targetPos))
diff --git a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala b/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala
index bae61f1a3b..c46c33c1ee 100644
--- a/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala
+++ b/src/compiler/scala/tools/nsc/doc/html/page/diagram/DotDiagramGenerator.scala
@@ -333,7 +333,7 @@ class DotDiagramGenerator(settings: doc.Settings) extends DiagramGenerator {
else
NodeSeq.Empty
} catch {
- case exc =>
+ case exc: Exception =>
if (settings.docDiagramsDebug.value) {
settings.printMsg("\n\n**********************************************************************")
settings.printMsg("Encountered an error while generating page for " + template.qualifiedName)
diff --git a/src/compiler/scala/tools/nsc/doc/model/Links.scala b/src/compiler/scala/tools/nsc/doc/model/LinkTo.scala
index b76dee0f14..b76dee0f14 100644
--- a/src/compiler/scala/tools/nsc/doc/model/Links.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/LinkTo.scala
diff --git a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
index 1a11964e37..85d6a8911e 100644
--- a/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/comment/CommentFactory.scala
@@ -660,7 +660,7 @@ trait CommentFactory { thisFactory: ModelFactory with CommentFactory with Member
else if (check(",,")) subscript()
else if (check("[[")) link()
else {
- readUntil { char == safeTagMarker || check("''") || char == '`' || check("__") || char == '^' || check(",,") || check("[[") || check("{{") || isInlineEnd || checkParaEnded || char == endOfLine }
+ readUntil { char == safeTagMarker || check("''") || char == '`' || check("__") || char == '^' || check(",,") || check("[[") || isInlineEnd || checkParaEnded || char == endOfLine }
Text(getRead())
}
}
diff --git a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
index 801b4ad22b..aab1c8fb7e 100644
--- a/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
+++ b/src/compiler/scala/tools/nsc/interactive/CompilerControl.scala
@@ -252,6 +252,19 @@ trait CompilerControl { self: Global =>
/** Asks for a computation to be done quickly on the presentation compiler thread */
def ask[A](op: () => A): A = if (self.onCompilerThread) op() else scheduler doQuickly op
+ /** Asks for a computation to be done on presentation compiler thread, returning
+ * a response with the result or an exception
+ */
+ def askForResponse[A](op: () => A): Response[A] = {
+ val r = new Response[A]
+ val ir = scheduler askDoQuickly op
+ ir onComplete {
+ case Left(result) => r set result
+ case Right(exc) => r raise exc
+ }
+ r
+ }
+
def onCompilerThread = Thread.currentThread == compileRunner
/** Info given for every member found by completion
@@ -390,7 +403,7 @@ trait CompilerControl { self: Global =>
case _ => println("don't know what to do with this " + action.getClass)
}
}
-
+
override def doQuickly[A](op: () => A): A = {
throw new FailedInterrupt(new Exception("Posted a work item to a compiler that's shutting down"))
}
diff --git a/src/compiler/scala/tools/nsc/interactive/Global.scala b/src/compiler/scala/tools/nsc/interactive/Global.scala
index 2a435aa6f6..27b6cae2a6 100644
--- a/src/compiler/scala/tools/nsc/interactive/Global.scala
+++ b/src/compiler/scala/tools/nsc/interactive/Global.scala
@@ -1030,11 +1030,15 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
}
}
- def getInstrumented(source: SourceFile, line: Int, response: Response[(String, Array[Char])]) {
- respond(response) {
- instrument(source, line)
+ def getInstrumented(source: SourceFile, line: Int, response: Response[(String, Array[Char])]) =
+ try {
+ interruptsEnabled = false
+ respond(response) {
+ instrument(source, line)
+ }
+ } finally {
+ interruptsEnabled = true
}
- }
// ---------------- Helper classes ---------------------------
diff --git a/src/compiler/scala/tools/nsc/interactive/REPL.scala b/src/compiler/scala/tools/nsc/interactive/REPL.scala
index 1dcc979255..6876ea14e0 100644
--- a/src/compiler/scala/tools/nsc/interactive/REPL.scala
+++ b/src/compiler/scala/tools/nsc/interactive/REPL.scala
@@ -11,7 +11,7 @@ import scala.tools.nsc.symtab._
import scala.tools.nsc.ast._
import scala.tools.nsc.reporters._
import scala.tools.nsc.io._
-import scala.tools.nsc.scratchpad.{Executor, SourceInserter}
+import scala.tools.nsc.scratchpad.SourceInserter
import scala.tools.nsc.interpreter.AbstractFileClassLoader
import java.io.{File, FileWriter}
@@ -138,7 +138,6 @@ object REPL {
* @param arguments Further argumenrs to pass to the compiler
* @return Optionallu, if no -d option is given, the virtual directory
* contained the generated bytecode classes
- */
def compileInstrumented(iSourceName: String, arguments: List[String]): Option[AbstractFile] = {
println("compiling "+iSourceName)
val command = new CompilerCommand(iSourceName :: arguments, reporter.error(scala.reflect.internal.util.NoPosition, _))
@@ -176,6 +175,7 @@ object REPL {
println("done")
si.currentContents
}
+ */
/** The method for implementing worksheet functionality.
* @param arguments a file name, followed by optional command line arguments that are passed
@@ -186,17 +186,22 @@ object REPL {
* and outputs in the right column, or None if the presentation compiler
* does not respond to askInstrumented.
*/
- def instrument(arguments: List[String], line: Int): Option[Array[Char]] = {
+ def instrument(arguments: List[String], line: Int): Option[String] = {
val source = toSourceFile(arguments.head)
// strip right hand side comment column and any trailing spaces from all lines
val strippedSource = new BatchSourceFile(source.file, SourceInserter.stripRight(source.content))
+ println("stripped source = "+strippedSource)
comp.askReload(List(strippedSource), reloadResult)
comp.askInstrumented(strippedSource, line, instrumentedResult)
using(instrumentedResult) {
case (iFullName, iContents) =>
+ println(s"instrumented source $iFullName = ${iContents.mkString}")
val iSourceName = writeInstrumented(iFullName, iContents)
- val vdirOpt = compileInstrumented(iSourceName, arguments.tail)
+ iSourceName
+/*
+ * val vdirOpt = compileInstrumented(iSourceName, arguments.tail)
runInstrumented(vdirOpt, iFullName, strippedSource.content)
+ */
}
}
diff --git a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
index 06828f3a3a..b702d2787c 100644
--- a/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
+++ b/src/compiler/scala/tools/nsc/interactive/RangePositions.scala
@@ -41,11 +41,11 @@ self: scala.tools.nsc.Global =>
/** A position that wraps a set of trees.
* The point of the wrapping position is the point of the default position.
* If some of the trees are ranges, returns a range position enclosing all ranges
- * Otherwise returns default position.
+ * Otherwise returns default position that is either focused or not.
*/
- override def wrappingPos(default: Position, trees: List[Tree]): Position = {
+ override def wrappingPos(default: Position, trees: List[Tree], focus: Boolean): Position = {
val ranged = trees filter (_.pos.isRange)
- if (ranged.isEmpty) default.focus
+ if (ranged.isEmpty) if (focus) default.focus else default
else new RangePosition(default.source, (ranged map (_.pos.start)).min, default.point, (ranged map (_.pos.end)).max)
}
@@ -59,13 +59,25 @@ self: scala.tools.nsc.Global =>
if (headpos.isDefined) wrappingPos(headpos, trees) else headpos
}
-/*
- override def integratePos(tree: Tree, pos: Position) =
- if (pos.isSynthetic && !tree.pos.isSynthetic) tree.syntheticDuplicate
- else tree
-*/
-
// -------------- ensuring no overlaps -------------------------------
+
+ /** Ensure that given tree has no positions that overlap with
+ * any of the positions of `others`. This is done by
+ * shortening the range, assigning TransparentPositions
+ * to some of the nodes in `tree` or focusing on the position.
+ */
+ override def ensureNonOverlapping(tree: Tree, others: List[Tree], focus: Boolean) {
+ def isOverlapping(pos: Position) =
+ pos.isRange && (others exists (pos overlaps _.pos))
+ if (isOverlapping(tree.pos)) {
+ val children = tree.children
+ children foreach (ensureNonOverlapping(_, others, focus))
+ if (tree.pos.isOpaqueRange) {
+ val wpos = wrappingPos(tree.pos, children, focus)
+ tree setPos (if (isOverlapping(wpos)) tree.pos.makeTransparent else wpos)
+ }
+ }
+ }
def solidDescendants(tree: Tree): List[Tree] =
if (tree.pos.isTransparent) tree.children flatMap solidDescendants
@@ -106,24 +118,6 @@ self: scala.tools.nsc.Global =>
if (ts.head == t) replacement ::: ts.tail
else ts.head :: replace(ts.tail, t, replacement)
- /** Ensure that given tree has no positions that overlap with
- * any of the positions of `others`. This is done by
- * shortening the range or assigning TransparentPositions
- * to some of the nodes in `tree`.
- */
- override def ensureNonOverlapping(tree: Tree, others: List[Tree]) {
- def isOverlapping(pos: Position) =
- pos.isRange && (others exists (pos overlaps _.pos))
- if (isOverlapping(tree.pos)) {
- val children = tree.children
- children foreach (ensureNonOverlapping(_, others))
- if (tree.pos.isOpaqueRange) {
- val wpos = wrappingPos(tree.pos.focus, children)
- tree setPos (if (isOverlapping(wpos)) tree.pos.makeTransparent else wpos)
- }
- }
- }
-
/** Does given list of trees have mutually non-overlapping positions?
* pre: None of the trees is transparent
*/
diff --git a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala b/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
index c79248e1c1..bd1869e1a4 100644
--- a/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
+++ b/src/compiler/scala/tools/nsc/interactive/ScratchPadMaker.scala
@@ -30,8 +30,12 @@ trait ScratchPadMaker { self: Global =>
private def literal(str: String) = "\"\"\""+str+"\"\"\""
+ private val prologue = "import scala.runtime.WorksheetSupport._; def main(args: Array[String])=$execute{"
+
+ private val epilogue = "}"
+
private def applyPendingPatches(offset: Int) = {
- if (skipped == 0) patches += Patch(offset, "import scala.tools.nsc.scratchpad.Executor._; ")
+ if (skipped == 0) patches += Patch(offset, prologue)
for (msg <- toPrint) patches += Patch(offset, ";System.out.println("+msg+")")
toPrint.clear()
}
@@ -92,10 +96,12 @@ trait ScratchPadMaker { self: Global =>
case PackageDef(_, _) =>
super.traverse(tree)
case ModuleDef(_, name, Template(_, _, body)) =>
- if (objectName.length == 0)
- objectName = tree.symbol.fullName
+ val topLevel = objectName.isEmpty
+ if (topLevel) objectName = tree.symbol.fullName
body foreach traverseStat
applyPendingPatches(skipped)
+ if (topLevel)
+ patches += Patch(skipped, epilogue)
case _ =>
}
diff --git a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
index a37fdc3ed1..58c2426602 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaScanners.scala
@@ -139,7 +139,7 @@ trait JavaScanners extends ast.parser.ScannersCommon {
kwOffset = offset
arr
}
- final val tokenName = allKeywords map (_.swap) toMap
+ final val tokenName = allKeywords.map(_.swap).toMap
//Token representation -----------------------------------------------------
diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala
index bbe22ca314..28dfd3fc77 100644
--- a/src/compiler/scala/tools/nsc/matching/Patterns.scala
+++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala
@@ -402,7 +402,7 @@ trait Patterns extends ast.TreeDSL {
case _ => toPats(args)
}
- def resTypes = analyzer.unapplyTypeList(unfn.symbol, unfn.tpe)
+ def resTypes = analyzer.unapplyTypeList(unfn.symbol, unfn.tpe, args.length)
def resTypesString = resTypes match {
case Nil => "Boolean"
case xs => xs.mkString(", ")
diff --git a/src/compiler/scala/tools/nsc/scratchpad/Executor.scala b/src/compiler/scala/tools/nsc/scratchpad/Executor.scala
deleted file mode 100644
index 89523df71e..0000000000
--- a/src/compiler/scala/tools/nsc/scratchpad/Executor.scala
+++ /dev/null
@@ -1,55 +0,0 @@
-package scala.tools.nsc.scratchpad
-
-import java.io.{PrintStream, OutputStreamWriter, Writer}
-
-import scala.runtime.ScalaRunTime.stringOf
-import java.lang.reflect.InvocationTargetException
-import scala.reflect.runtime.ReflectionUtils._
-
-object Executor {
-
- println("exec started")
-
- private var currentWriter: CommentWriter = null
-
- /** Execute module with given name, redirecting all output to given
- * source inserter. Catch all exceptions and print stacktrace of underlying causes.
- */
- def execute(name: String, si: SourceInserter, classLoader: ClassLoader = getClass.getClassLoader) {
- val oldSysOut = System.out
- val oldSysErr = System.err
- val oldConsOut = Console.out
- val oldConsErr = Console.err
- val oldCwr = currentWriter
- currentWriter = new CommentWriter(si)
- val newOut = new PrintStream(new CommentOutputStream(currentWriter))
- System.setOut(newOut)
- System.setErr(newOut)
- Console.setOut(newOut)
- Console.setErr(newOut)
- try {
- singletonInstance(classLoader, name)
- } catch {
- case ex: Throwable =>
- unwrapThrowable(ex) match {
- case _: StopException => ;
- case cause => cause.printStackTrace()
- }
- } finally {
- currentWriter.close()
- System.setOut(oldSysOut)
- System.setErr(oldSysErr)
- Console.setOut(oldConsOut)
- Console.setErr(oldConsErr)
- currentWriter = oldCwr
- }
- }
-
- def $skip(n: Int) = currentWriter.skip(n)
-
- def $stop() = throw new StopException
-
- def $show(x: Any): String = stringOf(x, scala.Int.MaxValue)
-}
-
-class StopException extends Exception
diff --git a/src/compiler/scala/tools/nsc/scratchpad/Mixer.scala b/src/compiler/scala/tools/nsc/scratchpad/Mixer.scala
new file mode 100644
index 0000000000..46ccc32097
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/scratchpad/Mixer.scala
@@ -0,0 +1,98 @@
+package scala.tools.nsc.scratchpad
+
+import java.io.{FileInputStream, InputStreamReader, IOException}
+
+import scala.runtime.ScalaRunTime.stringOf
+import java.lang.reflect.InvocationTargetException
+import scala.reflect.runtime.ReflectionUtils._
+import collection.mutable.ArrayBuffer
+
+class Mixer {
+
+ protected val stdSeparator = "//> "
+ protected val ctdSeparator = "//| "
+ protected val sepColumn = 50
+ protected val tabInc = 8
+
+ type Comments = Seq[(Int, Array[Char])]
+
+ def parseComments(comments: Array[Char]): Iterator[(Int, Array[Char])] = new Iterator[(Int, Array[Char])] {
+ var idx = 0
+ def hasNext = idx < comments.length
+ def next() = {
+ val nextSpace = comments indexOf (' ', idx)
+ var nextNL = comments indexOf ('\n', nextSpace + 1)
+ if (nextNL < 0) nextNL = comments.length
+ val result =
+ (new String(comments.slice(idx, nextSpace)).toInt, comments.slice(nextSpace + 1, nextNL))
+ idx = nextNL + 1
+ result
+ }
+ }
+
+ def mix(source: Array[Char], comments: Array[Char]): Array[Char] = {
+ val mixed = new ArrayBuffer[Char]
+ var written = 0
+ def align() = {
+ var idx = mixed.lastIndexOf('\n') + 1
+ var col = 0
+ while (idx < mixed.length) {
+ col =
+ if (mixed(idx) == '\t') (col / tabInc) * tabInc + tabInc
+ else col + 1
+ idx += 1
+ }
+ if (col > sepColumn) {
+ mixed += '\n'
+ col = 0
+ }
+ mixed ++= (" " * (sepColumn - col))
+ }
+ for ((offset, cs) <- parseComments(comments)) {
+ val sep =
+ if (written < offset) {
+ for (i <- written until offset) mixed += source(i)
+ written = offset
+ stdSeparator
+ } else {
+ mixed += '\n'
+ ctdSeparator
+ }
+ align()
+ mixed ++= sep ++= cs
+ }
+ mixed ++= source.view(written, source.length)
+ mixed.toArray
+ }
+
+}
+
+object Mixer extends Mixer {
+
+ def contents(name: String): Array[Char] = {
+ val page = new Array[Char](2 << 14)
+ val buf = new ArrayBuffer[Char]
+ val in = new FileInputStream(name)
+ val rdr = new InputStreamReader(in)
+ var nread = 0
+ do {
+ nread = rdr.read(page, 0, page.length)
+ buf ++= (if (nread == page.length) page else page.take(nread))
+ } while (nread >= 0)
+ buf.toArray
+ }
+
+ def main(args: Array[String]) {
+ val mixer = new Mixer
+ try {
+ require(args.length == 2, "required arguments: file1 file2")
+ val source = contents(args(0))
+ val comments = contents(args(1))
+ val mixed = mixer.mix(source, comments)
+ println(mixed.mkString)
+ } catch {
+ case ex: IOException =>
+ println("error: "+ ex.getMessage)
+ }
+ }
+}
diff --git a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
index 9b4e793241..46c52e68a2 100644
--- a/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
+++ b/src/compiler/scala/tools/nsc/symtab/SymbolLoaders.scala
@@ -112,11 +112,23 @@ abstract class SymbolLoaders {
enterClassAndModule(root, name, new SourcefileLoader(src))
}
+ /** The package objects of scala and scala.reflect should always
+ * be loaded in binary if classfiles are available, even if sourcefiles
+ * are newer. Late-compiling these objects from source leads to compilation
+ * order issues.
+ * Note: We do a name-base comparison here because the method is called before we even
+ * have ReflectPackage defined.
+ */
+ def binaryOnly(owner: Symbol, name: String): Boolean =
+ name == "package" &&
+ (owner.fullName == "scala" || owner.fullName == "scala.reflect")
+
/** Initialize toplevel class and module symbols in `owner` from class path representation `classRep`
*/
def initializeFromClassPath(owner: Symbol, classRep: ClassPath[platform.BinaryRepr]#ClassRep) {
((classRep.binary, classRep.source) : @unchecked) match {
- case (Some(bin), Some(src)) if platform.needCompile(bin, src) =>
+ case (Some(bin), Some(src))
+ if platform.needCompile(bin, src) && !binaryOnly(owner, classRep.name) =>
if (settings.verbose.value) inform("[symloader] picked up newer source file for " + src.path)
global.loaders.enterToplevelsFromSource(owner, classRep.name, src)
case (None, Some(src)) =>
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index e672f1914a..108c5ced6f 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -58,23 +58,6 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
}
private def mkTerm(prefix: String): TermName = unit.freshTermName(prefix)
- /** Kludge to provide a safe fix for #4560:
- * If we generate a reference in an implementation class, we
- * watch out for embedded This(..) nodes that point to the interface.
- * These must be wrong. We fix them by setting symbol and type to
- * the enclosing implementation class instead.
- */
- def safeREF(sym: Symbol) = {
- def fix(tree: Tree): Unit = tree match {
- case Select(qual @ This(_), name) if qual.symbol != currentClass =>
- qual.setSymbol(currentClass).setType(currentClass.tpe)
- case _ =>
- }
- val tree = REF(sym)
- if (currentClass.isImplClass && sym.owner == currentClass) fix(tree)
- tree
- }
-
//private val classConstantMeth = new HashMap[String, Symbol]
//private val symbolStaticFields = new HashMap[String, (Symbol, Tree, Tree)]
@@ -164,7 +147,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
val varDef = typedPos( VAL(varSym) === forInit )
newStaticMembers append transform(varDef)
- val varInit = typedPos( safeREF(varSym) === forInit )
+ val varInit = typedPos( REF(varSym) === forInit )
newStaticInits append transform(varInit)
varSym
@@ -200,7 +183,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
addStaticVariableToClass(nme.reflParamsCacheName, arrayType(ClassClass.tpe), fromTypesToClassArrayLiteral(paramTypes), true)
addStaticMethodToClass((_, forReceiverSym) =>
- gen.mkMethodCall(REF(forReceiverSym), Class_getMethod, Nil, List(LIT(method), safeREF(reflParamsCacheSym)))
+ gen.mkMethodCall(REF(forReceiverSym), Class_getMethod, Nil, List(LIT(method), REF(reflParamsCacheSym)))
)
case MONO_CACHE =>
@@ -239,11 +222,11 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
addStaticMethodToClass((_, forReceiverSym) =>
BLOCK(
IF (isCacheEmpty(forReceiverSym)) THEN BLOCK(
- safeREF(reflMethodCacheSym) === ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), safeREF(reflParamsCacheSym))) ,
- safeREF(reflClassCacheSym) === gen.mkSoftRef(REF(forReceiverSym)),
+ REF(reflMethodCacheSym) === ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), REF(reflParamsCacheSym))) ,
+ REF(reflClassCacheSym) === gen.mkSoftRef(REF(forReceiverSym)),
UNIT
) ENDIF,
- safeREF(reflMethodCacheSym)
+ REF(reflMethodCacheSym)
)
)
@@ -277,22 +260,22 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
val reflPolyCacheSym: Symbol = (
addStaticVariableToClass(nme.reflPolyCacheName, SoftReferenceClass.tpe, mkNewPolyCache, false)
)
- def getPolyCache = gen.mkCast(fn(safeREF(reflPolyCacheSym), nme.get), MethodCacheClass.tpe)
+ def getPolyCache = gen.mkCast(fn(REF(reflPolyCacheSym), nme.get), MethodCacheClass.tpe)
addStaticMethodToClass((reflMethodSym, forReceiverSym) => {
val methodSym = reflMethodSym.newVariable(mkTerm("method"), ad.pos) setInfo MethodClass.tpe
BLOCK(
- IF (getPolyCache OBJ_EQ NULL) THEN (safeREF(reflPolyCacheSym) === mkNewPolyCache) ENDIF,
+ IF (getPolyCache OBJ_EQ NULL) THEN (REF(reflPolyCacheSym) === mkNewPolyCache) ENDIF,
VAL(methodSym) === ((getPolyCache DOT methodCache_find)(REF(forReceiverSym))) ,
IF (REF(methodSym) OBJ_!= NULL) .
THEN (Return(REF(methodSym)))
ELSE {
- def methodSymRHS = ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), safeREF(reflParamsCacheSym)))
+ def methodSymRHS = ((REF(forReceiverSym) DOT Class_getMethod)(LIT(method), REF(reflParamsCacheSym)))
def cacheRHS = ((getPolyCache DOT methodCache_add)(REF(forReceiverSym), REF(methodSym)))
BLOCK(
REF(methodSym) === (REF(ensureAccessibleMethod) APPLY (methodSymRHS)),
- safeREF(reflPolyCacheSym) === gen.mkSoftRef(cacheRHS),
+ REF(reflPolyCacheSym) === gen.mkSoftRef(cacheRHS),
Return(REF(methodSym))
)
}
@@ -400,7 +383,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
def genDefaultCall = {
// reflective method call machinery
val invokeName = MethodClass.tpe member nme.invoke_ // reflect.Method.invoke(...)
- def cache = safeREF(reflectiveMethodCache(ad.symbol.name.toString, paramTypes)) // cache Symbol
+ def cache = REF(reflectiveMethodCache(ad.symbol.name.toString, paramTypes)) // cache Symbol
def lookup = Apply(cache, List(qual1() GETCLASS)) // get Method object from cache
def invokeArgs = ArrayValue(TypeTree(ObjectClass.tpe), params) // args for invocation
def invocation = (lookup DOT invokeName)(qual1(), invokeArgs) // .invoke(qual1, ...)
@@ -495,7 +478,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
typedPos {
val sym = currentOwner.newValue(mkTerm("qual"), ad.pos) setInfo qual0.tpe
- qual = safeREF(sym)
+ qual = REF(sym)
BLOCK(
VAL(sym) === qual0,
@@ -678,7 +661,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
val rhs = gen.mkMethodCall(Symbol_apply, arg :: Nil)
val staticFieldSym = getSymbolStaticField(tree.pos, symname, rhs, tree)
// create a reference to a static field
- val ntree = typedWithPos(tree.pos)(safeREF(staticFieldSym))
+ val ntree = typedWithPos(tree.pos)(REF(staticFieldSym))
super.transform(ntree)
// This transform replaces Array(Predef.wrapArray(Array(...)), <tag>)
@@ -711,7 +694,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
// create field definition and initialization
val stfieldDef = theTyper.typedPos(pos)(VAL(stfieldSym) === rhs)
- val stfieldInit = theTyper.typedPos(pos)(safeREF(stfieldSym) === rhs)
+ val stfieldInit = theTyper.typedPos(pos)(REF(stfieldSym) === rhs)
// add field definition to new defs
newStaticMembers append stfieldDef
@@ -777,8 +760,8 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
val stfieldDef = localTyper.typedPos(tree.pos)(VAL(stfieldSym) === EmptyTree)
val flattenedInit = fixedrhs match {
- case Block(stats, expr) => Block(stats, safeREF(stfieldSym) === expr)
- case rhs => safeREF(stfieldSym) === rhs
+ case Block(stats, expr) => Block(stats, REF(stfieldSym) === expr)
+ case rhs => REF(stfieldSym) === rhs
}
val stfieldInit = localTyper.typedPos(tree.pos)(flattenedInit)
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index afbe528b1f..1f7c34b8ad 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -377,6 +377,7 @@ abstract class ExplicitOuter extends InfoTransform
}
}
+ // requires settings.XoldPatmat.value
def matchTranslation(tree: Match) = {
val Match(selector, cases) = tree
var nselector = transform(selector)
@@ -519,33 +520,32 @@ abstract class ExplicitOuter extends InfoTransform
super.transform(treeCopy.Apply(tree, sel, outerVal :: args))
// entry point for pattern matcher translation
- case mch: Match if (!opt.virtPatmat) => // don't use old pattern matcher as fallback when the user wants the virtualizing one
- matchTranslation(mch)
-
- case _ =>
- if (opt.virtPatmat) { // this turned out to be expensive, hence the hacky `if` and `return`
- tree match {
- // for patmatvirtualiser
- // base.<outer>.eq(o) --> base.$outer().eq(o) if there's an accessor, else the whole tree becomes TRUE
- // TODO remove the synthetic `<outer>` method from outerFor??
- case Apply(eqsel@Select(eqapp@Apply(sel@Select(base, outerAcc), Nil), eq), args) if outerAcc == nme.OUTER_SYNTH =>
- val outerFor = sel.symbol.owner.toInterface // TODO: toInterface necessary?
- val acc = outerAccessor(outerFor)
- if(acc == NoSymbol) {
- // println("WARNING: no outer for "+ outerFor)
- return transform(TRUE) // urgh... drop condition if there's no accessor
- } else {
- // println("(base, acc)= "+(base, acc))
- val outerSelect = localTyper typed Apply(Select(base, acc), Nil)
- // achieves the same as: localTyper typed atPos(tree.pos)(outerPath(base, base.tpe.typeSymbol, outerFor.outerClass))
- // println("(b, tpsym, outerForI, outerFor, outerClass)= "+ (base, base.tpe.typeSymbol, outerFor, sel.symbol.owner, outerFor.outerClass))
- // println("outerSelect = "+ outerSelect)
- return transform(treeCopy.Apply(tree, treeCopy.Select(eqsel, outerSelect, eq), args))
- }
- case _ =>
- }
+ case m: Match if settings.XoldPatmat.value => // the new pattern matcher runs in its own phase right after typer
+ matchTranslation(m)
+
+ // for the new pattern matcher
+ // base.<outer>.eq(o) --> base.$outer().eq(o) if there's an accessor, else the whole tree becomes TRUE
+ // TODO remove the synthetic `<outer>` method from outerFor??
+ case Apply(eqsel@Select(eqapp@Apply(sel@Select(base, nme.OUTER_SYNTH), Nil), eq), args) if !settings.XoldPatmat.value =>
+ val outerFor = sel.symbol.owner.toInterface // TODO: toInterface necessary?
+ val acc = outerAccessor(outerFor)
+
+ if (acc == NoSymbol ||
+ // since we can't fix SI-4440 properly (we must drop the outer accessors of final classes when there's no immediate reference to them in sight)
+ // at least don't crash... this duplicates maybeOmittable from constructors
+ (acc.owner.isEffectivelyFinal && !acc.isOverridingSymbol)) {
+ unit.uncheckedWarning(tree.pos, "The outer reference in this type test cannot be checked at run time.")
+ return transform(TRUE) // urgh... drop condition if there's no accessor (or if it may disappear after constructors)
+ } else {
+ // println("(base, acc)= "+(base, acc))
+ val outerSelect = localTyper typed Apply(Select(base, acc), Nil)
+ // achieves the same as: localTyper typed atPos(tree.pos)(outerPath(base, base.tpe.typeSymbol, outerFor.outerClass))
+ // println("(b, tpsym, outerForI, outerFor, outerClass)= "+ (base, base.tpe.typeSymbol, outerFor, sel.symbol.owner, outerFor.outerClass))
+ // println("outerSelect = "+ outerSelect)
+ return transform(treeCopy.Apply(tree, treeCopy.Select(eqsel, outerSelect, eq), args))
}
+ case _ =>
if (settings.Xmigration28.value) tree match {
case TypeApply(fn @ Select(qual, _), args) if fn.symbol == Object_isInstanceOf || fn.symbol == Any_isInstanceOf =>
if (isArraySeqTest(qual.tpe, args.head.tpe))
diff --git a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
index 5f66cadbc9..e937589f54 100644
--- a/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExtensionMethods.scala
@@ -78,13 +78,13 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
}
/** This method removes the `$this` argument from the parameter list a method.
- *
+ *
* A method may be a `PolyType`, in which case we tear out the `$this` and the class
* type params from its nested `MethodType`.
* It may be a `MethodType`, either with a curried parameter list in which the first argument
* is a `$this` - we just return the rest of the list.
* This means that the corresponding symbol was generated during `extmethods`.
- *
+ *
* It may also be a `MethodType` in which the `$this` does not appear in a curried parameter list.
* The curried lists disappear during `uncurry`, and the methods may be duplicated afterwards,
* for instance, during `specialize`.
@@ -105,6 +105,14 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
private val extensionDefs = mutable.Map[Symbol, mutable.ListBuffer[Tree]]()
+ def checkNonCyclic(pos: Position, seen: Set[Symbol], clazz: Symbol): Unit =
+ if (seen contains clazz)
+ unit.error(pos, "value class may not unbox to itself")
+ else {
+ val unboxed = erasure.underlyingOfValueClass(clazz).typeSymbol
+ if (unboxed.isDerivedValueClass) checkNonCyclic(pos, seen + clazz, unboxed)
+ }
+
def extensionMethInfo(extensionMeth: Symbol, origInfo: Type, clazz: Symbol): Type = {
var newTypeParams = cloneSymbolsAtOwner(clazz.typeParams, extensionMeth)
val thisParamType = appliedType(clazz.typeConstructor, newTypeParams map (_.tpeHK))
@@ -129,6 +137,7 @@ abstract class ExtensionMethods extends Transform with TypingTransformers {
tree match {
case Template(_, _, _) =>
if (currentOwner.isDerivedValueClass) {
+ checkNonCyclic(currentOwner.pos, Set(), currentOwner)
extensionDefs(currentOwner.companionModule) = new mutable.ListBuffer[Tree]
currentOwner.primaryConstructor.makeNotPrivate(NoSymbol)
super.transform(tree)
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index ffcb682cf7..63f93aa000 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -798,6 +798,10 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
var specializingOn = specializedParams(sym)
val unusedStvars = specializingOn filterNot specializedTypeVars(sym.info)
+ // I think the last condition should be !sym.isHidden, but that made the
+ // compiler start warning about Tuple1.scala and Tuple2.scala claiming
+ // their type parameters are used in non-specializable positions. Why is
+ // unusedStvars.nonEmpty for these classes???
if (unusedStvars.nonEmpty && currentRun.compiles(sym) && !sym.isSynthetic) {
reporter.warning(sym.pos,
"%s %s unused or used in non-specializable positions.".format(
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index 2983c65e78..5c0207e5c7 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -618,7 +618,7 @@ abstract class UnCurry extends InfoTransform
val fn1 = withInPattern(false)(transform(fn))
val args1 = transformTrees(fn.symbol.name match {
case nme.unapply => args
- case nme.unapplySeq => transformArgs(tree.pos, fn.symbol, args, analyzer.unapplyTypeListFromReturnTypeSeq(fn.tpe))
+ case nme.unapplySeq => transformArgs(tree.pos, fn.symbol, args, analyzer.unapplyTypeList(fn.symbol, fn.tpe, args.length))
case _ => sys.error("internal error: UnApply node has wrong symbol")
})
treeCopy.UnApply(tree, fn1, args1)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 805f60ba87..0fc298e886 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -552,7 +552,6 @@ trait Contexts { self: Analyzer =>
( (ab.isTerm || ab == rootMirror.RootClass)
|| (accessWithin(ab) || accessWithinLinked(ab)) &&
( !sym.hasLocalFlag
- || sym.owner.isImplClass // allow private local accesses to impl classes
|| sym.isProtected && isSubThisType(pre, sym.owner)
|| pre =:= sym.owner.thisType
)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 47cf80807a..e096b75d6d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -49,6 +49,69 @@ trait Infer {
} else formals1
}
+ /** Returns `(formals, formalsExpanded)` where `formalsExpanded` are the expected types
+ * for the `nbSubPats` sub-patterns of an extractor pattern, of which the corresponding
+ * unapply[Seq] call is assumed to have result type `resTp`.
+ *
+ * `formals` are the formal types before expanding a potential repeated parameter (must come last in `formals`, if at all)
+ *
+ * @throws TypeError when the unapply[Seq] definition is ill-typed
+ * @returns (null, null) when the expected number of sub-patterns cannot be satisfied by the given extractor
+ *
+ * From the spec:
+ * 8.1.8 ExtractorPatterns
+ *
+ * An extractor pattern x(p1, ..., pn) where n ≥ 0 is of the same syntactic form as a constructor pattern.
+ * However, instead of a case class, the stable identifier x denotes an object which has a member method named unapply or unapplySeq that matches the pattern.
+ * An unapply method in an object x matches the pattern x(p1, ..., pn) if it takes exactly one argument and one of the following applies:
+ *
+ * n = 0 and unapply’s result type is Boolean.
+ *
+ * n = 1 and unapply’s result type is Option[T], for some type T.
+ * the (only) argument pattern p1 is typed in turn with expected type T
+ *
+ * n > 1 and unapply’s result type is Option[(T1, ..., Tn)], for some types T1, ..., Tn.
+ * the argument patterns p1, ..., pn are typed in turn with expected types T1, ..., Tn
+ */
+ def extractorFormalTypes(resTp: Type, nbSubPats: Int, unappSym: Symbol): (List[Type], List[Type]) = {
+ val isUnapplySeq = unappSym.name == nme.unapplySeq
+ val booleanExtractor = resTp.typeSymbolDirect == BooleanClass
+
+ @inline def seqToRepeatedChecked(tp: Type) = {
+ val toRepeated = seqToRepeated(tp)
+ if (tp eq toRepeated) throw new TypeError("(the last tuple-component of) the result type of an unapplySeq must be a Seq[_]")
+ else toRepeated
+ }
+
+ val formals =
+ if (nbSubPats == 0 && booleanExtractor && !isUnapplySeq) Nil
+ else resTp.baseType(OptionClass).typeArgs match {
+ case optionTArg :: Nil =>
+ if (nbSubPats == 1)
+ if (isUnapplySeq) List(seqToRepeatedChecked(optionTArg))
+ else List(optionTArg)
+ // TODO: update spec to reflect we allow any ProductN, not just TupleN
+ else getProductArgs(optionTArg) match {
+ case Nil if isUnapplySeq => List(seqToRepeatedChecked(optionTArg))
+ case tps if isUnapplySeq => tps.init :+ seqToRepeatedChecked(tps.last)
+ case tps => tps
+ }
+ case _ =>
+ if (isUnapplySeq)
+ throw new TypeError(s"result type $resTp of unapplySeq defined in ${unappSym.owner+unappSym.owner.locationString} not in {Option[_], Some[_]}")
+ else
+ throw new TypeError(s"result type $resTp of unapply defined in ${unappSym.owner+unappSym.owner.locationString} not in {Boolean, Option[_], Some[_]}")
+ }
+
+ // for unapplySeq, replace last vararg by as many instances as required by nbSubPats
+ val formalsExpanded =
+ if (isUnapplySeq && formals.nonEmpty) formalTypes(formals, nbSubPats)
+ else formals
+
+ if (formalsExpanded.lengthCompare(nbSubPats) != 0) (null, null)
+ else (formals, formalsExpanded)
+ }
+
def actualTypes(actuals: List[Type], nformals: Int): List[Type] =
if (nformals == 1 && !hasLength(actuals, 1))
List(if (actuals.isEmpty) UnitClass.tpe else tupleType(actuals))
@@ -1261,64 +1324,89 @@ trait Infer {
}
// if top-level abstract types can be checked using a classtag extractor, don't warn about them
- def checkCheckable(tree: Tree, tp: Type, inPattern: Boolean, canRemedy: Boolean = false) = {
- val kind = if (inPattern) "pattern " else ""
+ def checkCheckable(tree: Tree, typeToTest: Type, typeEnsured: Type, inPattern: Boolean, canRemedy: Boolean = false) = {
+ log(s"checkCheckable($tree, $typeToTest, $typeEnsured, inPattern = $inPattern, canRemedy = $canRemedy")
- def patternWarning(tp0: Type, prefix: String) = {
- context.unit.uncheckedWarning(tree.pos, prefix+tp0+" in type "+kind+tp+" is unchecked since it is eliminated by erasure")
+ sealed abstract class TypeConformance(check: (Type, Type) => Boolean) {
+ def apply(t1: Type, t2: Type): Boolean = check(t1, t2) && {
+ log(s"Skipping unchecked for statically verifiable condition $t1 ${this} $t2")
+ true
+ }
}
- def check(tp: Type, bound: List[Symbol]) {
- def isLocalBinding(sym: Symbol) =
- sym.isAbstractType &&
- ((bound contains sym) ||
- sym.name == tpnme.WILDCARD || {
+ // I tried to use varianceInType to track the variance implications
+ // but I could not make it work.
+ case object =:= extends TypeConformance(_ =:= _)
+ case object <:< extends TypeConformance(_ <:< _)
+ case object >:> extends TypeConformance((t1, t2) => t2 <:< t1)
+ case object =!= extends TypeConformance((t1, t2) => false)
+
+ var bound: List[Symbol] = Nil
+ var warningMessages: List[String] = Nil
+
+ def isLocalBinding(sym: Symbol) = (
+ sym.isAbstractType && (
+ (bound contains sym)
+ || (sym.name == tpnme.WILDCARD)
+ || {
val e = context.scope.lookupEntry(sym.name)
(e ne null) && e.sym == sym && !e.sym.isTypeParameterOrSkolem && e.owner == context.scope
- })
- tp match {
- case SingleType(pre, _) =>
- check(pre, bound)
- case TypeRef(pre, sym, args) =>
- if (sym.isAbstractType) {
- // we only use the extractor for top-level type tests, type arguments (see below) remain unchecked
- if (!isLocalBinding(sym) && !canRemedy) patternWarning(tp, "abstract type ")
- } else if (sym.isAliasType) {
- check(tp.normalize, bound)
- } else if (sym == NothingClass || sym == NullClass || sym == AnyValClass) {
- TypePatternOrIsInstanceTestError(tree, tp)
- } else {
- for (arg <- args) {
- if (sym == ArrayClass) check(arg, bound)
- else if (arg.typeArgs.nonEmpty) () // avoid spurious warnings with higher-kinded types
- else if (sym == NonLocalReturnControlClass) () // no way to suppress unchecked warnings on try/catch
- else arg match {
- case TypeRef(_, sym, _) if isLocalBinding(sym) =>
- ;
- case _ =>
- // Want to warn about type arguments, not type parameters. Otherwise we'll
- // see warnings about "invisible" types, like: val List(x0) = x1 leading to "non
- // variable type-argument A in type pattern List[A]..."
- if (!arg.typeSymbol.isTypeParameterOrSkolem)
- patternWarning(arg, "non variable type-argument ")
- }
- }
- }
- check(pre, bound)
- case RefinedType(parents, decls) =>
- if (decls.isEmpty) for (p <- parents) check(p, bound)
- else patternWarning(tp, "refinement ")
- case ExistentialType(quantified, tp1) =>
- check(tp1, bound ::: quantified)
- case ThisType(_) =>
- ()
- case NoPrefix =>
- ()
- case _ =>
- patternWarning(tp, "type ")
- ()
+ }
+ )
+ )
+ def check(tp0: Type, pt: Type, conformance: TypeConformance): Boolean = {
+ val tp = tp0.normalize
+ // Set the warning message to be issued when the top-level call fails.
+ def warn(what: String): Boolean = {
+ warningMessages ::= what
+ false
+ }
+ def checkArg(param: Symbol, arg: Type) = {
+ def conforms = (
+ if (param.isCovariant) <:<
+ else if (param.isContravariant) >:>
+ else =:=
+ )
+ val TypeRef(_, sym, args) = arg
+
+ ( isLocalBinding(sym)
+ || arg.typeSymbol.isTypeParameterOrSkolem
+ || (sym.name == tpnme.WILDCARD) // avoid spurious warnings on HK types
+ || check(arg, param.tpe, conforms)
+ || warn("non-variable type argument " + arg)
+ )
}
+
+ // Checking if pt (the expected type of the pattern, and the type
+ // we are guaranteed) conforms to tp (the type expressed in the pattern's
+ // type test.) If it does, then even if the type being checked for appears
+ // to be uncheckable, it is not a warning situation, because it is indeed
+ // checked: not at runtime, but statically.
+ conformance.apply(pt, tp) || (tp match {
+ case SingleType(pre, _) => check(pre, pt, =:=)
+ case ExistentialType(quantified, tp1) => bound :::= quantified ; check(tp1, pt, <:<)
+ case ThisType(_) | NoPrefix => true
+ case RefinedType(parents, decls) if decls.isEmpty => parents forall (p => check(p, pt, <:<))
+ case RefinedType(_, _) => warn("refinement " + tp)
+ case TypeRef(_, ArrayClass, arg :: Nil) => check(arg, NoType, =!=)
+ case TypeRef(_, NonLocalReturnControlClass, _) => true // no way to suppress unchecked warnings on try/catch
+ // we only use the extractor for top-level type tests, type arguments remain unchecked
+ case TypeRef(_, sym, _) if sym.isAbstractType => isLocalBinding(sym) || canRemedy || warn("abstract type " + tp)
+ case TypeRef(_, _, Nil) => false // leaf node
+ case TypeRef(pre, sym, args) => forall2(sym.typeParams, args)(checkArg) && check(pre, pt.prefix, =:=)
+ case _ => warn("type " + tp)
+ })
+ }
+ typeToTest match {
+ // Prohibit top-level type tests for these, but they are
+ // acceptable nested (e.g. case Foldable[Nothing] => ... )
+ case TypeRef(_, NothingClass | NullClass | AnyValClass, _) =>
+ TypePatternOrIsInstanceTestError(tree, typeToTest)
+ case _ =>
+ def where = ( if (inPattern) "pattern " else "" ) + typeToTest
+ if (check(typeToTest, typeEnsured, =:=)) ()
+ else warningMessages foreach (m =>
+ context.unit.uncheckedWarning(tree.pos, s"$m in type $where is unchecked since it is eliminated by erasure"))
}
- check(tp, List())
}
/** Type intersection of simple type tp1 with general type tp2.
@@ -1355,7 +1443,7 @@ trait Infer {
return ErrorType
}
- checkCheckable(tree0, pattp, inPattern = true, canRemedy)
+ checkCheckable(tree0, pattp, pt, inPattern = true, canRemedy)
if (pattp <:< pt) ()
else {
debuglog("free type params (1) = " + tpparams)
@@ -1434,7 +1522,7 @@ trait Infer {
)
// Intentionally *not* using `Type#typeSymbol` here, which would normalize `tp`
- // and collect symbols from the result type of any resulting `PolyType`s, which
+ // and collect symbols from the result type of any resulting `PolyType`s, which
// are not free type parameters of `tp`.
//
// Contrast with `isFreeTypeParamNoSkolem`.
@@ -1467,7 +1555,7 @@ trait Infer {
def inferExprAlternative(tree: Tree, pt: Type) = tree.tpe match {
case OverloadedType(pre, alts) => tryTwice { isSecondTry =>
val alts0 = alts filter (alt => isWeaklyCompatible(pre.memberType(alt), pt))
- val noAlternatives = alts0.isEmpty
+ val noAlternatives = alts0.isEmpty
val alts1 = if (noAlternatives) alts else alts0
//println("trying "+alts1+(alts1 map (_.tpe))+(alts1 map (_.locationString))+" for "+pt)
@@ -1625,7 +1713,7 @@ trait Infer {
val saved = context.state
var fallback = false
context.setBufferErrors()
- // We cache the current buffer because it is impossible to
+ // We cache the current buffer because it is impossible to
// distinguish errors that occurred before entering tryTwice
// and our first attempt in 'withImplicitsDisabled'. If the
// first attempt fails we try with implicits on *and* clean
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
index 43edad3576..cf5c7265ad 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternMatching.scala
@@ -218,11 +218,6 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
if(phase.id >= currentRun.uncurryPhase.id) debugwarn("running translateMatch at "+ phase +" on "+ selector +" match "+ cases)
patmatDebug("translating "+ cases.mkString("{", "\n", "}"))
- def repeatedToSeq(tp: Type): Type = (tp baseType RepeatedParamClass) match {
- case TypeRef(_, RepeatedParamClass, arg :: Nil) => seqType(arg)
- case _ => tp
- }
-
val start = Statistics.startTimer(patmatNanos)
val selectorTp = repeatedToSeq(elimAnonymousClass(selector.tpe.widen.withoutAnnotations))
@@ -417,8 +412,9 @@ trait PatternMatching extends Transform with TypingTransformers with ast.TreeDSL
**/
// must treat Typed and Bind together -- we need to know the patBinder of the Bind pattern to get at the actual type
case MaybeBoundTyped(subPatBinder, pt) =>
+ val next = glb(List(patBinder.info.widen, pt)).normalize
// a typed pattern never has any subtrees
- noFurtherSubPats(TypeTestTreeMaker(subPatBinder, patBinder, pt, glb(List(patBinder.info.widen, pt)).normalize)(pos))
+ noFurtherSubPats(TypeTestTreeMaker(subPatBinder, patBinder, pt, next)(pos))
/** A pattern binder x@p consists of a pattern variable x and a pattern p.
The type of the variable x is the static type T of the pattern p.
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index a378a95786..fe82af5b23 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -14,7 +14,7 @@ import util.returning
abstract class TreeCheckers extends Analyzer {
import global._
- private def classstr(x: AnyRef) = x.getClass.getName split """\\.|\\$""" last;
+ private def classstr(x: AnyRef) = (x.getClass.getName split """\\.|\\$""").last
private def typestr(x: Type) = " (tpe = " + x + ")"
private def treestr(t: Tree) = t + " [" + classstr(t) + "]" + typestr(t.tpe)
private def ownerstr(s: Symbol) = "'" + s + "'" + s.locationString
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 9e498a3012..5c25cd008b 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -1194,30 +1194,46 @@ trait Typers extends Modes with Adaptations with Tags {
}
val found = tree.tpe
- val req = pt
- if (!found.isErroneous && !req.isErroneous) {
- if (!context.reportErrors && isPastTyper && req.skolemsExceptMethodTypeParams.nonEmpty) {
- // Ignore type errors raised in later phases that are due to mismatching types with existential skolems
- // We have lift crashing in 2.9 with an adapt failure in the pattern matcher.
- // Here's my hypothsis why this happens. The pattern matcher defines a variable of type
- //
- // val x: T = expr
- //
- // where T is the type of expr, but T contains existential skolems ts.
- // In that case, this value definition does not typecheck.
- // The value definition
- //
- // val x: T forSome { ts } = expr
- //
- // would typecheck. Or one can simply leave out the type of the `val`:
- //
- // val x = expr
- context.unit.warning(tree.pos, "recovering from existential Skolem type error in tree \n" + tree + "\nwith type " + tree.tpe + "\n expected type = " + pt + "\n context = " + context.tree)
- adapt(tree, mode, deriveTypeWithWildcards(pt.skolemsExceptMethodTypeParams)(pt))
- } else {
- // create an actual error
- AdaptTypeError(tree, found, req)
+ if (!found.isErroneous && !pt.isErroneous) {
+ if (!context.reportErrors && isPastTyper) {
+ val (bound, req) = pt match {
+ case ExistentialType(qs, tpe) => (qs, tpe)
+ case _ => (Nil, pt)
+ }
+ val boundOrSkolems = bound ++ pt.skolemsExceptMethodTypeParams
+ if (boundOrSkolems.nonEmpty) {
+ // Ignore type errors raised in later phases that are due to mismatching types with existential skolems
+ // We have lift crashing in 2.9 with an adapt failure in the pattern matcher.
+ // Here's my hypothsis why this happens. The pattern matcher defines a variable of type
+ //
+ // val x: T = expr
+ //
+ // where T is the type of expr, but T contains existential skolems ts.
+ // In that case, this value definition does not typecheck.
+ // The value definition
+ //
+ // val x: T forSome { ts } = expr
+ //
+ // would typecheck. Or one can simply leave out the type of the `val`:
+ //
+ // val x = expr
+ //
+ // SI-6029 shows another case where we also fail (in uncurry), but this time the expected
+ // type is an existential type.
+ //
+ // The reason for both failures have to do with the way we (don't) transform
+ // skolem types along with the trees that contain them. We'd need a
+ // radically different approach to do it. But before investing a lot of time to
+ // to do this (I have already sunk 3 full days with in the end futile attempts
+ // to consistently transform skolems and fix 6029), I'd like to
+ // investigate ways to avoid skolems completely.
+ //
+ log("recovering from existential or skolem type error in tree \n" + tree + "\nwith type " + tree.tpe + "\n expected type = " + pt + "\n context = " + context.tree)
+ return adapt(tree, mode, deriveTypeWithWildcards(boundOrSkolems)(pt))
+ }
}
+ // create an actual error
+ AdaptTypeError(tree, found, pt)
}
setError(tree)
}
@@ -2749,6 +2765,14 @@ trait Typers extends Modes with Adaptations with Tags {
def typedArgs(args: List[Tree], mode: Int) =
args mapConserve (arg => typedArg(arg, mode, 0, WildcardType))
+ /** Type trees in `args0` against corresponding expected type in `adapted0`.
+ *
+ * The mode in which each argument is typed is derived from `mode` and
+ * whether the arg was originally by-name or var-arg (need `formals0` for that)
+ * the default is by-val, of course.
+ *
+ * (docs reverse-engineered -- AM)
+ */
def typedArgs(args0: List[Tree], mode: Int, formals0: List[Type], adapted0: List[Type]): List[Tree] = {
val sticky = onlyStickyModes(mode)
def loop(args: List[Tree], formals: List[Type], adapted: List[Type]): List[Tree] = {
@@ -3157,12 +3181,13 @@ trait Typers extends Modes with Adaptations with Tags {
if (fun1.tpe.isErroneous) duplErrTree
else {
- val formals0 = unapplyTypeList(fun1.symbol, fun1.tpe)
- val formals1 = formalTypes(formals0, args.length)
+ val resTp = fun1.tpe.finalResultType.normalize
+ val nbSubPats = args.length
- if (!sameLength(formals1, args)) duplErrorTree(WrongNumberArgsPatternError(tree, fun))
+ val (formals, formalsExpanded) = extractorFormalTypes(resTp, nbSubPats, fun1.symbol)
+ if (formals == null) duplErrorTree(WrongNumberArgsPatternError(tree, fun))
else {
- val args1 = typedArgs(args, mode, formals0, formals1)
+ val args1 = typedArgs(args, mode, formals, formalsExpanded)
// This used to be the following (failing) assert:
// assert(isFullyDefined(pt), tree+" ==> "+UnApply(fun1, args1)+", pt = "+pt)
// I modified as follows. See SI-1048.
@@ -3663,7 +3688,8 @@ trait Typers extends Modes with Adaptations with Tags {
typedClassOf(tree, args.head, true)
else {
if (!isPastTyper && fun.symbol == Any_isInstanceOf && !targs.isEmpty)
- checkCheckable(tree, targs.head, inPattern = false)
+ checkCheckable(tree, targs.head, AnyClass.tpe, inPattern = false)
+
val resultpe = restpe.instantiateTypeParams(tparams, targs)
//@M substitution in instantiateParams needs to be careful!
//@M example: class Foo[a] { def foo[m[x]]: m[a] = error("") } (new Foo[Int]).foo[List] : List[Int]
@@ -4521,7 +4547,7 @@ trait Typers extends Modes with Adaptations with Tags {
assert(errorContainer == null, "Cannot set ambiguous error twice for identifier")
errorContainer = tree
}
-
+
val fingerPrint: Long = name.fingerPrint
var defSym: Symbol = tree.symbol // the directly found symbol
@@ -4652,15 +4678,28 @@ trait Typers extends Modes with Adaptations with Tags {
// If the ambiguous name is a monomorphic type, we can relax this far.
def mt1 = t1 memberType impSym
def mt2 = t2 memberType impSym1
+ def characterize = List(
+ s"types: $t1 =:= $t2 ${t1 =:= t2} members: ${mt1 =:= mt2}",
+ s"member type 1: $mt1",
+ s"member type 2: $mt2",
+ s"$impSym == $impSym1 ${impSym == impSym1}",
+ s"${impSym.debugLocationString} ${impSym.getClass}",
+ s"${impSym1.debugLocationString} ${impSym1.getClass}"
+ ).mkString("\n ")
+
+ // The symbol names are checked rather than the symbols themselves because
+ // each time an overloaded member is looked up it receives a new symbol.
+ // So foo.member("x") != foo.member("x") if x is overloaded. This seems
+ // likely to be the cause of other bugs too...
+ if (t1 =:= t2 && impSym.name == impSym1.name)
+ log(s"Suppressing ambiguous import: $t1 =:= $t2 && $impSym == $impSym1")
// Monomorphism restriction on types is in part because type aliases could have the
// same target type but attach different variance to the parameters. Maybe it can be
// relaxed, but doesn't seem worth it at present.
- if (t1 =:= t2 && impSym == impSym1)
- log(s"Suppressing ambiguous import: $t1 =:= $t2 && $impSym == $impSym1")
else if (mt1 =:= mt2 && name.isTypeName && impSym.isMonomorphicType && impSym1.isMonomorphicType)
log(s"Suppressing ambiguous import: $mt1 =:= $mt2 && $impSym and $impSym1 are equivalent")
else {
- log(s"Import is genuinely ambiguous: !($t1 =:= $t2)")
+ log(s"Import is genuinely ambiguous:\n " + characterize)
ambiguousError(s"it is imported twice in the same scope by\n${imports.head}\nand ${imports1.head}")
}
}
@@ -4880,7 +4919,7 @@ trait Typers extends Modes with Adaptations with Tags {
case UnApply(fun, args) =>
val fun1 = typed(fun)
- val tpes = formalTypes(unapplyTypeList(fun.symbol, fun1.tpe), args.length)
+ val tpes = formalTypes(unapplyTypeList(fun.symbol, fun1.tpe, args.length), args.length)
val args1 = map2(args, tpes)(typedPattern)
treeCopy.UnApply(tree, fun1, args1) setType pt
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index ad936ac39d..d508e10813 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -31,59 +31,18 @@ trait Unapplies extends ast.TreeDSL
// moduleClass symbol of the companion module.
class ClassForCaseCompanionAttachment(val caseClass: ClassDef)
- /** returns type list for return type of the extraction */
- def unapplyTypeList(ufn: Symbol, ufntpe: Type) = {
+ /** returns type list for return type of the extraction
+ * @see extractorFormalTypes
+ */
+ def unapplyTypeList(ufn: Symbol, ufntpe: Type, nbSubPats: Int) = {
assert(ufn.isMethod, ufn)
//Console.println("utl "+ufntpe+" "+ufntpe.typeSymbol)
ufn.name match {
- case nme.unapply => unapplyTypeListFromReturnType(ufntpe)
- case nme.unapplySeq => unapplyTypeListFromReturnTypeSeq(ufntpe)
- case _ => throw new TypeError(ufn+" is not an unapply or unapplySeq")
- }
- }
- /** (the inverse of unapplyReturnTypeSeq)
- * for type Boolean, returns Nil
- * for type Option[T] or Some[T]:
- * - returns T0...Tn if n>0 and T <: Product[T0...Tn]]
- * - returns T otherwise
- */
- def unapplyTypeListFromReturnType(tp1: Type): List[Type] = {
- val tp = unapplyUnwrap(tp1)
- tp.typeSymbol match { // unapplySeqResultToMethodSig
- case BooleanClass => Nil
- case OptionClass | SomeClass =>
- val prod = tp.typeArgs.head
-// the spec doesn't allow just any subtype of Product, it *must* be TupleN[...] -- see run/virtpatmat_extends_product.scala
-// this breaks plenty of stuff, though...
-// val targs =
-// if (isTupleType(prod)) getProductArgs(prod)
-// else List(prod)
- val targs = getProductArgs(prod)
-
- if (targs.isEmpty || targs.tail.isEmpty) List(prod) // special n == 0 || n == 1
- else targs // n > 1
- case _ =>
- throw new TypeError("result type "+tp+" of unapply not in {Boolean, Option[_], Some[_]}")
- }
- }
-
- /** let type be the result type of the (possibly polymorphic) unapply method
- * for type Option[T] or Some[T]
- * -returns T0...Tn-1,Tn* if n>0 and T <: Product[T0...Tn-1,Seq[Tn]]],
- * -returns R* if T = Seq[R]
- */
- def unapplyTypeListFromReturnTypeSeq(tp1: Type): List[Type] = {
- val tp = unapplyUnwrap(tp1)
- tp.typeSymbol match {
- case OptionClass | SomeClass =>
- val ts = unapplyTypeListFromReturnType(tp1)
- val last1 = (ts.last baseType SeqClass) match {
- case TypeRef(pre, SeqClass, args) => typeRef(pre, RepeatedParamClass, args)
- case _ => throw new TypeError("last not seq")
- }
- ts.init :+ last1
- case _ =>
- throw new TypeError("result type "+tp+" of unapply not in {Option[_], Some[_]}")
+ case nme.unapply | nme.unapplySeq =>
+ val (formals, _) = extractorFormalTypes(unapplyUnwrap(ufntpe), nbSubPats, ufn)
+ if (formals == null) throw new TypeError(s"$ufn of type $ufntpe cannot extract $nbSubPats sub-patterns")
+ else formals
+ case _ => throw new TypeError(ufn+" is not an unapply or unapplySeq")
}
}
diff --git a/src/compiler/scala/tools/nsc/util/InterruptReq.scala b/src/compiler/scala/tools/nsc/util/InterruptReq.scala
index 61aaa1bdcb..816d16f767 100644
--- a/src/compiler/scala/tools/nsc/util/InterruptReq.scala
+++ b/src/compiler/scala/tools/nsc/util/InterruptReq.scala
@@ -2,6 +2,7 @@ package scala.tools.nsc
package util
/** A class of work items to be used in interrupt requests.
+ * Todo: we should replace the Eithers by Futures or Try's.
*/
abstract class InterruptReq {
/** The result type of the operation
@@ -11,9 +12,14 @@ abstract class InterruptReq {
/** The operation to be performed */
protected val todo: () => R
+ type Continuation = Either[R, Throwable] => Unit
+
/** The result provided */
private var result: Option[Either[R, Throwable]] = None
+ /** The continuations waiting asynchronously on a provided result */
+ private var waiting: List[Continuation] = Nil
+
/** To be called from interrupted server to execute demanded task */
def execute(): Unit = synchronized {
try {
@@ -22,6 +28,7 @@ abstract class InterruptReq {
case t: Throwable => result = Some(Right(t))
} finally {
notify()
+ for (k <- waiting.reverse) k(result.get)
}
}
@@ -38,6 +45,10 @@ abstract class InterruptReq {
case Right(t) => throw new FailedInterrupt(t)
}
}
+
+ def onComplete(k: Continuation) = synchronized {
+ waiting = k :: waiting
+ }
}
class FailedInterrupt(cause: Throwable) extends Exception("Compiler exception during call to 'ask'", cause)
diff --git a/src/compiler/scala/tools/nsc/util/WorkScheduler.scala b/src/compiler/scala/tools/nsc/util/WorkScheduler.scala
index 8c037cbda5..b1f4696d3e 100644
--- a/src/compiler/scala/tools/nsc/util/WorkScheduler.scala
+++ b/src/compiler/scala/tools/nsc/util/WorkScheduler.scala
@@ -54,6 +54,11 @@ class WorkScheduler {
/** Called from client: have interrupt executed by server and return result */
def doQuickly[A](op: () => A): A = {
+ val ir = askDoQuickly(op)
+ ir.getResult()
+ }
+
+ def askDoQuickly[A](op: () => A): InterruptReq { type R = A } = {
val ir = new InterruptReq {
type R = A
val todo = op
@@ -62,7 +67,7 @@ class WorkScheduler {
interruptReqs enqueue ir
notify()
}
- ir.getResult()
+ ir
}
/** Called from client: have action executed by server */
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
index 017c8d24fd..211560e343 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
@@ -475,7 +475,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
val (prologue, rest) = (anfStats :+ anfExpr) span (s => !s.isInstanceOf[DefDef]) // find first case
// println("rest: "+ rest)
// val (defs, calls) = rest partition (_.isInstanceOf[DefDef])
- if (rest nonEmpty){
+ if (rest.nonEmpty) {
// the filter drops the ()'s emitted when transValue encountered a LabelDef
val stats = prologue ++ (rest filter (_.isInstanceOf[DefDef])).reverse // ++ calls
// println("REVERSED "+ (stats mkString ("{", "\n", "}")))
diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala
index f11dfb72ae..7d37fa4aa1 100644
--- a/src/library/scala/StringContext.scala
+++ b/src/library/scala/StringContext.scala
@@ -26,7 +26,7 @@ case class StringContext(parts: String*) {
* @param `args` The arguments to be checked.
* @throws An `IllegalArgumentException` if this is not the case.
*/
- def checkLengths(args: Any*): Unit =
+ def checkLengths(args: Seq[Any]): Unit =
if (parts.length != args.length + 1)
throw new IllegalArgumentException("wrong number of arguments for interpolated string")
@@ -42,11 +42,27 @@ case class StringContext(parts: String*) {
* @throws A `StringContext.InvalidEscapeException` if if a `parts` string contains a backslash (`\`) character
* that does not start a valid escape sequence.
*/
- def s(args: Any*): String = {
- checkLengths(args: _*)
+ def s(args: Any*): String = standardInterpolator(treatEscapes, args)
+
+ /** The raw string interpolator.
+ *
+ * It inserts its arguments between corresponding parts of the string context.
+ * As opposed to the simple string interpolator `s`, this one does not treat
+ * standard escape sequences as defined in the Scala specification.
+ * @param `args` The arguments to be inserted into the resulting string.
+ * @throws An `IllegalArgumentException`
+ * if the number of `parts` in the enclosing `StringContext` does not exceed
+ * the number of arguments `arg` by exactly 1.
+ * @throws A `StringContext.InvalidEscapeException` if if a `parts` string contains a backslash (`\`) character
+ * that does not start a valid escape sequence.
+ */
+ def raw(args: Any*): String = standardInterpolator(identity, args)
+
+ def standardInterpolator(process: String => String, args: Seq[Any]): String = {
+ checkLengths(args)
val pi = parts.iterator
val ai = args.iterator
- val bldr = new java.lang.StringBuilder(treatEscapes(pi.next()))
+ val bldr = new java.lang.StringBuilder(process(pi.next()))
while (ai.hasNext) {
bldr append ai.next
bldr append treatEscapes(pi.next())
diff --git a/src/library/scala/collection/GenTraversableOnce.scala b/src/library/scala/collection/GenTraversableOnce.scala
index 25edcfe19c..4e0f71ee8b 100644
--- a/src/library/scala/collection/GenTraversableOnce.scala
+++ b/src/library/scala/collection/GenTraversableOnce.scala
@@ -11,6 +11,7 @@ package scala.collection
import scala.reflect.ClassTag
import scala.collection.generic.CanBuildFrom
import scala.annotation.unchecked.{ uncheckedVariance => uV }
+import language.higherKinds
/** A template trait for all traversable-once objects which may be
* traversed in parallel.
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala
index 9356832afd..641dd095da 100644
--- a/src/library/scala/collection/TraversableLike.scala
+++ b/src/library/scala/collection/TraversableLike.scala
@@ -13,6 +13,7 @@ import mutable.{ Builder }
import annotation.{tailrec, migration, bridge}
import annotation.unchecked.{ uncheckedVariance => uV }
import parallel.ParIterable
+import language.higherKinds
/** A template trait for traversable collections of type `Traversable[A]`.
*
diff --git a/src/library/scala/collection/concurrent/TrieMap.scala b/src/library/scala/collection/concurrent/TrieMap.scala
index 2d8217551a..3d0aa6fd07 100644
--- a/src/library/scala/collection/concurrent/TrieMap.scala
+++ b/src/library/scala/collection/concurrent/TrieMap.scala
@@ -188,7 +188,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
if (sn.hc == hc && equal(sn.k, k, ct)) {
if (GCAS(cn, cn.updatedAt(pos, new SNode(k, v, hc), gen), ct)) Some(sn.v) else null
} else None
- case otherv: V =>
+ case otherv =>
if (sn.hc == hc && equal(sn.k, k, ct) && sn.v == otherv) {
if (GCAS(cn, cn.updatedAt(pos, new SNode(k, v, hc), gen), ct)) Some(sn.v) else null
} else None
@@ -200,7 +200,7 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
val ncnode = rn.insertedAt(pos, flag, new SNode(k, v, hc), gen)
if (GCAS(cn, ncnode, ct)) None else null
case INode.KEY_PRESENT => None
- case otherv: V => None
+ case otherv => None
}
case sn: TNode[K, V] =>
clean(parent, ct, lev - 5)
@@ -224,9 +224,9 @@ private[collection] final class INode[K, V](bn: MainNode[K, V], g: Gen) extends
case Some(v0) => if (insertln()) Some(v0) else null
case None => None
}
- case otherv: V =>
+ case otherv =>
ln.get(k) match {
- case Some(v0) if v0 == otherv => if (insertln()) Some(otherv) else null
+ case Some(v0) if v0 == otherv => if (insertln()) Some(otherv.asInstanceOf[V]) else null
case _ => None
}
}
diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala
index d4f1c2f39f..85758b29bc 100644
--- a/src/library/scala/collection/parallel/ParIterableLike.scala
+++ b/src/library/scala/collection/parallel/ParIterableLike.scala
@@ -30,7 +30,7 @@ import java.util.concurrent.atomic.AtomicBoolean
import annotation.unchecked.uncheckedVariance
import annotation.unchecked.uncheckedStable
-import language.implicitConversions
+import language.{ higherKinds, implicitConversions }
/** A template trait for parallel collections of type `ParIterable[T]`.
diff --git a/src/library/scala/math/Ordering.scala b/src/library/scala/math/Ordering.scala
index ab685815a1..9020bb9edd 100644
--- a/src/library/scala/math/Ordering.scala
+++ b/src/library/scala/math/Ordering.scala
@@ -28,7 +28,7 @@ import language.{implicitConversions, higherKinds}
* Sorting.quickSort(pairs)(Ordering.by[(String, Int, Int), Int](_._2)
*
* // sort by the 3rd element, then 1st
- * Sorting.quickSort(pairs)(Ordering[(Int, String)].on[(String, Int, Int)]((_._3, _._1))
+ * Sorting.quickSort(pairs)(Ordering[(Int, String)].on(x => (x._3, x._1)))
* }}}
*
* An Ordering[T] is implemented by specifying compare(a:T, b:T), which
diff --git a/src/library/scala/reflect/ClassManifest.scala b/src/library/scala/reflect/ClassManifestDeprecatedApis.scala
index d226e43e77..d226e43e77 100644
--- a/src/library/scala/reflect/ClassManifest.scala
+++ b/src/library/scala/reflect/ClassManifestDeprecatedApis.scala
diff --git a/src/library/scala/reflect/base/Base.scala b/src/library/scala/reflect/base/Base.scala
index 4457a6cf14..53854f160d 100644
--- a/src/library/scala/reflect/base/Base.scala
+++ b/src/library/scala/reflect/base/Base.scala
@@ -52,7 +52,6 @@ class Base extends Universe { self =>
else if (isFreeTerm) "free term"
else if (isTerm) "value"
else "symbol"
- // [Eugene++ to Martin] base names should expose `decode`
override def toString() = s"$kindString $name"
}
implicit val SymbolTag = ClassTag[Symbol](classOf[Symbol])
@@ -96,8 +95,8 @@ class Base extends Universe { self =>
// todo. write a decent toString that doesn't crash on recursive types
class Type extends TypeBase {
- def typeSymbol: Symbol = NoSymbol
def termSymbol: Symbol = NoSymbol
+ def typeSymbol: Symbol = NoSymbol
}
implicit val TypeTagg = ClassTag[Type](classOf[Type])
@@ -204,20 +203,22 @@ class Base extends Universe { self =>
object nme extends TermNamesBase {
type NameType = TermName
- val EMPTY = newTermName("")
- val ROOT = newTermName("<root>")
- val EMPTY_PACKAGE_NAME = newTermName("<empty>")
- val CONSTRUCTOR = newTermName("<init>")
+ val WILDCARD = newTermName("_")
+ val CONSTRUCTOR = newTermName("<init>")
+ val ROOTPKG = newTermName("_root_")
+ val EMPTY = newTermName("")
+ val EMPTY_PACKAGE_NAME = newTermName("<empty>")
+ val ROOT = newTermName("<root>")
val NO_NAME = newTermName("<none>")
- val WILDCARD = newTermName("_")
}
object tpnme extends TypeNamesBase {
type NameType = TypeName
- val EMPTY = nme.EMPTY.toTypeName
- val ROOT = nme.ROOT.toTypeName
- val EMPTY_PACKAGE_NAME = nme.EMPTY_PACKAGE_NAME.toTypeName
- val WILDCARD = nme.WILDCARD.toTypeName
+ val WILDCARD = nme.WILDCARD.toTypeName
+ val EMPTY = nme.EMPTY.toTypeName
+ val WILDCARD_STAR = newTypeName("_*")
+ val EMPTY_PACKAGE_NAME = nme.EMPTY_PACKAGE_NAME.toTypeName
+ val ROOT = nme.ROOT.toTypeName
}
type FlagSet = Long
diff --git a/src/library/scala/reflect/base/Names.scala b/src/library/scala/reflect/base/Names.scala
index 280a6ce8a2..532b780e7e 100644
--- a/src/library/scala/reflect/base/Names.scala
+++ b/src/library/scala/reflect/base/Names.scala
@@ -1,6 +1,8 @@
package scala.reflect
package base
+import language.implicitConversions
+
/** A trait that manages names.
* A name is a string in one of two name universes: terms and types.
* The same string can be a name in both universes.
diff --git a/src/library/scala/reflect/base/StandardNames.scala b/src/library/scala/reflect/base/StandardNames.scala
index 8a3fbe9683..50399a4a1e 100644
--- a/src/library/scala/reflect/base/StandardNames.scala
+++ b/src/library/scala/reflect/base/StandardNames.scala
@@ -6,6 +6,11 @@
package scala.reflect
package base
+// Q: I have a pretty name. Where do I put it - into base.StandardNames or into api.StandardNames?
+// A: Is it necessary to construct trees (like EMPTY or WILDCARD_STAR)? If yes, then it goes to base.StandardNames.
+// Is it necessary to perform reflection (like ERROR or LOCAL_SUFFIX_STRING)? If yes, then it goes to api.StandardNames.
+// Otherwise it goes nowhere - reflection API should stay minimalistic.
+
trait StandardNames {
self: Universe =>
@@ -14,16 +19,16 @@ trait StandardNames {
trait NamesBase {
type NameType >: Null <: Name
- val EMPTY: NameType
- val ROOT: NameType
- val EMPTY_PACKAGE_NAME: NameType
val WILDCARD: NameType
}
- trait TypeNamesBase extends NamesBase
-
trait TermNamesBase extends NamesBase {
val CONSTRUCTOR: TermName
- val NO_NAME: NameType
+ val ROOTPKG: TermName
+ }
+
+ trait TypeNamesBase extends NamesBase {
+ val EMPTY: NameType
+ val WILDCARD_STAR: NameType
}
}
diff --git a/src/library/scala/reflect/base/Types.scala b/src/library/scala/reflect/base/Types.scala
index 6e8ffc7984..28aaf2d04d 100644
--- a/src/library/scala/reflect/base/Types.scala
+++ b/src/library/scala/reflect/base/Types.scala
@@ -3,25 +3,14 @@ package base
trait Types { self: Universe =>
- /** The base API that all types support */
- abstract class TypeBase {
-
- /** The term symbol associated with the type, or `NoSymbol` for types
- * that do not refer to a term symbol.
- */
- def termSymbol: Symbol
-
- /** The type symbol associated with the type, or `NoSymbol` for types
- * that do not refer to a type symbol.
- */
- def typeSymbol: Symbol
- }
-
/** The type of Scala types, and also Scala type signatures.
* (No difference is internally made between the two).
*/
type Type >: Null <: TypeBase
+ /** The base API that all types support */
+ abstract class TypeBase
+
/** A tag that preserves the identity of the `Type` abstract type from erasure.
* Can be used for pattern matching, instance tests, serialization and likes.
*/
diff --git a/src/library/scala/runtime/Tuple2Zipped.scala b/src/library/scala/runtime/Tuple2Zipped.scala
index 5ad364c8a5..dce7eef08d 100644
--- a/src/library/scala/runtime/Tuple2Zipped.scala
+++ b/src/library/scala/runtime/Tuple2Zipped.scala
@@ -10,6 +10,7 @@ package scala.runtime
import scala.collection.{ TraversableLike, IterableLike }
import scala.collection.generic.{ CanBuildFrom => CBF }
+import language.{ higherKinds, implicitConversions }
/** This interface is intended as a minimal interface, not complicated
* by the requirement to resolve type constructors, for implicit search (which only
diff --git a/src/library/scala/runtime/Tuple3Zipped.scala b/src/library/scala/runtime/Tuple3Zipped.scala
index 4e9c542c58..f3ca08649d 100644
--- a/src/library/scala/runtime/Tuple3Zipped.scala
+++ b/src/library/scala/runtime/Tuple3Zipped.scala
@@ -10,6 +10,7 @@ package scala.runtime
import scala.collection.{ TraversableLike, IterableLike }
import scala.collection.generic.{ CanBuildFrom => CBF }
+import language.{ higherKinds, implicitConversions }
/** See comment on ZippedTraversable2. */
trait ZippedTraversable3[+El1, +El2, +El3] {
diff --git a/src/library/scala/runtime/WorksheetSupport.scala b/src/library/scala/runtime/WorksheetSupport.scala
new file mode 100644
index 0000000000..db6d6359a3
--- /dev/null
+++ b/src/library/scala/runtime/WorksheetSupport.scala
@@ -0,0 +1,87 @@
+package scala.runtime
+import java.io.{OutputStream, PrintStream}
+import scala.runtime.ScalaRunTime.stringOf
+
+/** A utility object that's needed by the code that executes a worksheet.
+ */
+object WorksheetSupport {
+
+ /** The offset in the source which should be printed */
+ private var currentOffset = 0
+
+ /** A stream that flushes in regular intervals so that output can be captured
+ * in real time. The flush interval is determined by the field "flushInterval".
+ * By default it is 30ms.
+ */
+ private class FlushedOutputStream(out: OutputStream) extends OutputStream {
+ private var lastFlush: Long = 0L
+ protected val flushInterval = 30000000L // 30ms
+ private var lastCh: Int = '\n'
+ override def write(b: Array[Byte], off: Int, len: Int) = {
+ for (idx <- off until (off + len min b.length)) writeOne(b(idx))
+ flush()
+ }
+ override def write(c: Int) {
+ writeOne(c)
+ flush()
+ }
+ override def flush() {
+ val current = System.nanoTime
+ if (current - lastFlush >= flushInterval) {
+ out.flush()
+ lastFlush = current
+ }
+ }
+ def writeOne(c: Int) {
+ if (lastCh == '\n') {
+ lastCh = 0
+ write((currentOffset+" ").getBytes)
+ }
+ out.write(c)
+ lastCh = c
+ }
+ def ensureNewLine() = if (lastCh != '\n') writeOne('\n')
+ }
+
+ private val flushedOut = new FlushedOutputStream(System.out)
+ private val printOut = new PrintStream(flushedOut)
+
+ private def redirected(op: => Unit) = {
+ val oldSysOut = System.out
+ val oldSysErr = System.err
+ val oldConsOut = Console.out
+ val oldConsErr = Console.err
+ System.setOut(printOut)
+ System.setErr(printOut)
+ Console.setOut(printOut)
+ Console.setErr(printOut)
+ try op
+ finally {
+ printOut.close()
+ System.setOut(oldSysOut)
+ System.setErr(oldSysErr)
+ Console.setOut(oldConsOut)
+ Console.setErr(oldConsErr)
+ }
+ }
+
+ def $execute(op: => Unit) = redirected {
+ try op
+ catch {
+ case ex: StopException => ;
+ case ex => ex.printStackTrace()
+ }
+ }
+
+ def $skip(n: Int) = {
+ flushedOut.ensureNewLine()
+ currentOffset += n
+ }
+
+ def $stop() = throw new StopException
+
+ def $show(x: Any): String = stringOf(x, scala.Int.MaxValue)
+}
+
+class StopException extends Exception
+
diff --git a/src/library/scala/util/Try.scala b/src/library/scala/util/Try.scala
index 9475a05d5a..f85bac0b84 100644
--- a/src/library/scala/util/Try.scala
+++ b/src/library/scala/util/Try.scala
@@ -8,11 +8,9 @@
package scala.util
-
-
import collection.Seq
import scala.util.control.NonFatal
-
+import language.implicitConversions
/**
* The `Try` type represents a computation that may either result in an exception, or return a
@@ -208,7 +206,7 @@ final case class Success[+T](value: T) extends Try[T] {
def flatMap[U](f: T => Try[U]): Try[U] =
try f(value)
catch {
- case e => Failure(e)
+ case e: Throwable => Failure(e)
}
def flatten[U](implicit ev: T <:< Try[U]): Try[U] = value
def foreach[U](f: T => U): Unit = f(value)
diff --git a/src/library/scala/xml/dtd/ElementValidator.scala b/src/library/scala/xml/dtd/ElementValidator.scala
index 111c1b5e78..f97da1c8a3 100644
--- a/src/library/scala/xml/dtd/ElementValidator.scala
+++ b/src/library/scala/xml/dtd/ElementValidator.scala
@@ -115,6 +115,7 @@ class ElementValidator() extends Function1[Node,Boolean] {
(dfa delta q).getOrElse(e, throw ValidationException("element %s not allowed here" format e))
}
}
+ case _ => false
}
/** applies various validations - accumulates error messages in exc
diff --git a/src/partest/scala/tools/partest/DirectTest.scala b/src/partest/scala/tools/partest/DirectTest.scala
index 5b4e1b4b25..323705b695 100644
--- a/src/partest/scala/tools/partest/DirectTest.scala
+++ b/src/partest/scala/tools/partest/DirectTest.scala
@@ -70,7 +70,7 @@ abstract class DirectTest extends App {
/** Constructor/main body **/
try show()
- catch { case t => println(t.getMessage) ; t.printStackTrace ; sys.exit(1) }
+ catch { case t: Exception => println(t.getMessage) ; t.printStackTrace ; sys.exit(1) }
/** Debugger interest only below this line **/
protected def isDebug = (sys.props contains "partest.debug") || (sys.env contains "PARTEST_DEBUG")
diff --git a/src/partest/scala/tools/partest/ScaladocModelTest.scala b/src/partest/scala/tools/partest/ScaladocModelTest.scala
index ffc5e74cc0..7117d7c715 100644
--- a/src/partest/scala/tools/partest/ScaladocModelTest.scala
+++ b/src/partest/scala/tools/partest/ScaladocModelTest.scala
@@ -72,7 +72,7 @@ abstract class ScaladocModelTest extends DirectTest {
testModel(universe.rootPackage)
println("Done.")
} catch {
- case e =>
+ case e: Exception =>
println(e)
e.printStackTrace
}
@@ -102,7 +102,7 @@ abstract class ScaladocModelTest extends DirectTest {
// finally, enable easy navigation inside the entities
object access {
- class TemplateAccess(tpl: DocTemplateEntity) {
+ implicit class TemplateAccess(tpl: DocTemplateEntity) {
def _class(name: String): DocTemplateEntity = getTheFirst(_classes(name), tpl.qualifiedName + ".class(" + name + ")")
def _classes(name: String): List[DocTemplateEntity] = tpl.templates.filter(_.name == name).collect({ case c: DocTemplateEntity with Class => c})
@@ -143,21 +143,21 @@ abstract class ScaladocModelTest extends DirectTest {
def _aliasTypeTpls(name: String): List[DocTemplateEntity] = tpl.members.collect({ case dtpl: DocTemplateEntity with AliasType if dtpl.name == name => dtpl })
}
- class PackageAccess(pack: Package) extends TemplateAccess(pack) {
+ trait WithMembers {
+ def members: List[MemberEntity]
+ def _member(name: String): MemberEntity = getTheFirst(_members(name), this.toString + ".member(" + name + ")")
+ def _members(name: String): List[MemberEntity] = members.filter(_.name == name)
+ }
+ implicit class PackageAccess(pack: Package) extends TemplateAccess(pack) {
def _package(name: String): Package = getTheFirst(_packages(name), pack.qualifiedName + ".package(" + name + ")")
def _packages(name: String): List[Package] = pack.packages.filter(_.name == name)
}
-
- class MemberAccess(mbrs: WithMembers) {
- def _member(name: String): MemberEntity = getTheFirst(_members(name), mbrs.toString + ".member(" + name + ")")
- def _members(name: String): List[MemberEntity] = mbrs.members.filter(_.name == name)
+ implicit class DocTemplateEntityMembers(val underlying: DocTemplateEntity) extends WithMembers {
+ def members = underlying.members
+ }
+ implicit class ImplicitConversionMembers(val underlying: ImplicitConversion) extends WithMembers {
+ def members = underlying.members
}
-
- type WithMembers = { def members: List[MemberEntity]; def toString: String } /* DocTemplates and ImplicitConversions */
-
- implicit def templateAccess(tpl: DocTemplateEntity) = new TemplateAccess(tpl)
- implicit def packageAccess(pack: Package) = new PackageAccess(pack)
- implicit def membersAccess(mbrs: WithMembers) = new MemberAccess(mbrs)
def getTheFirst[T](list: List[T], expl: String): T = list.length match {
case 1 => list.head
diff --git a/src/partest/scala/tools/partest/instrumented/Instrumentation.scala b/src/partest/scala/tools/partest/instrumented/Instrumentation.scala
index f29a7f90fd..3589df60f6 100644
--- a/src/partest/scala/tools/partest/instrumented/Instrumentation.scala
+++ b/src/partest/scala/tools/partest/instrumented/Instrumentation.scala
@@ -54,14 +54,20 @@ object Instrumentation {
def startProfiling(): Unit = Profiler.startProfiling()
def stopProfiling(): Unit = Profiler.stopProfiling()
def resetProfiling(): Unit = Profiler.resetProfiling()
+ def isProfiling(): Boolean = Profiler.isProfiling()
def getStatistics: Statistics = {
- Profiler.stopProfiling()
+ val isProfiling = Profiler.isProfiling()
+ if (isProfiling) {
+ Profiler.stopProfiling()
+ }
val stats = Profiler.getStatistics().asScala.toSeq.map {
case (trace, count) => MethodCallTrace(trace.className, trace.methodName, trace.methodDescriptor) -> count.intValue
}
val res = Map(stats: _*)
- Profiler.startProfiling()
+ if (isProfiling) {
+ Profiler.startProfiling()
+ }
res
}
diff --git a/src/partest/scala/tools/partest/instrumented/Profiler.java b/src/partest/scala/tools/partest/instrumented/Profiler.java
index 215bdbba08..0c87060794 100644
--- a/src/partest/scala/tools/partest/instrumented/Profiler.java
+++ b/src/partest/scala/tools/partest/instrumented/Profiler.java
@@ -55,6 +55,10 @@ public class Profiler {
isProfiling = false;
}
+ public static boolean isProfiling() {
+ return isProfiling;
+ }
+
public static void resetProfiling() {
counts = new HashMap<MethodCallTrace, Integer>();
}
diff --git a/src/partest/scala/tools/partest/javaagent/ASMTransformer.java b/src/partest/scala/tools/partest/javaagent/ASMTransformer.java
index 643c683002..09cd485d6b 100644
--- a/src/partest/scala/tools/partest/javaagent/ASMTransformer.java
+++ b/src/partest/scala/tools/partest/javaagent/ASMTransformer.java
@@ -21,7 +21,9 @@ public class ASMTransformer implements ClassFileTransformer {
// we instrument all classes from empty package
(!className.contains("/") ||
// we instrument all classes from scala package
- className.startsWith("scala/"));
+ className.startsWith("scala/") ||
+ // we instrument all classes from `instrumented` package
+ className.startsWith("instrumented/"));
}
public byte[] transform(ClassLoader loader, String className, Class<?> classBeingRedefined, ProtectionDomain protectionDomain, byte[] classfileBuffer) {
diff --git a/src/partest/scala/tools/partest/nest/RunnerManager.scala b/src/partest/scala/tools/partest/nest/RunnerManager.scala
index dc15d4475b..5a7684dc61 100644
--- a/src/partest/scala/tools/partest/nest/RunnerManager.scala
+++ b/src/partest/scala/tools/partest/nest/RunnerManager.scala
@@ -82,7 +82,7 @@ class RunnerManager(kind: String, val fileManager: FileManager, params: TestRunP
private def compareFiles(f1: File, f2: File): String =
try fileManager.compareFiles(f1, f2)
- catch { case t => t.toString }
+ catch { case t: Exception => t.toString }
/** This does something about absolute paths and file separator
* chars before diffing.
@@ -779,11 +779,11 @@ class RunnerManager(kind: String, val fileManager: FileManager, params: TestRunP
logStackTrace(logFile, t, "Possible compiler crash during test of: " + testFile + "\n")
LogContext(logFile)
}
- catch { case t => LogContext(null) }
+ catch { case t: Throwable => LogContext(null) }
}
def run(): (Boolean, LogContext) = {
- val result = try processSingleFile(testFile) catch { case t => (false, crashContext(t)) }
+ val result = try processSingleFile(testFile) catch { case t: Throwable => (false, crashContext(t)) }
passed = Some(result._1)
result
}
diff --git a/src/partest/scala/tools/partest/package.scala b/src/partest/scala/tools/partest/package.scala
index 9b510eacd6..9f45b380eb 100644
--- a/src/partest/scala/tools/partest/package.scala
+++ b/src/partest/scala/tools/partest/package.scala
@@ -30,6 +30,9 @@ package object partest {
implicit private[partest] def temporaryPath2File(x: Path): JFile = x.jfile
implicit private[partest] def temporaryFile2Path(x: JFile): Path = Path(x)
+ implicit lazy val postfixOps = language.postfixOps
+ implicit lazy val implicitConversions = language.implicitConversions
+
def timed[T](body: => T): (T, Long) = {
val t1 = System.currentTimeMillis
val result = body
@@ -60,7 +63,7 @@ package object partest {
def allPropertiesString = {
import collection.JavaConversions._
- System.getProperties.toList.sorted map { case (k, v) => "%s -> %s\n".format(k, v) } mkString
+ System.getProperties.toList.sorted map { case (k, v) => "%s -> %s\n".format(k, v) } mkString ""
}
def showAllJVMInfo() {
diff --git a/src/reflect/scala/reflect/api/Names.scala b/src/reflect/scala/reflect/api/Names.scala
index 222ee5024b..d6868c26ab 100644
--- a/src/reflect/scala/reflect/api/Names.scala
+++ b/src/reflect/scala/reflect/api/Names.scala
@@ -20,9 +20,6 @@ trait Names extends base.Names {
*/
abstract class NameApi extends NameBase {
- // [Eugene++] this functionality should be in base
- // this is because stuff will be reified in mangled state, and people will need a way to figure it out
-
/** Replaces all occurrences of \$op_names in this name by corresponding operator symbols.
* Example: `foo_\$plus\$eq` becomes `foo_+=`
*/
diff --git a/src/reflect/scala/reflect/api/StandardNames.scala b/src/reflect/scala/reflect/api/StandardNames.scala
index eb1ecda900..24d803a24a 100644
--- a/src/reflect/scala/reflect/api/StandardNames.scala
+++ b/src/reflect/scala/reflect/api/StandardNames.scala
@@ -5,6 +5,9 @@
package scala.reflect
package api
+// Q: I have a pretty name. Where do I put it - into base.StandardNames or into api.StandardNames?
+// A: <see base.StandardNames>
+
trait StandardNames extends base.StandardNames {
self: Universe =>
@@ -12,151 +15,16 @@ trait StandardNames extends base.StandardNames {
val tpnme: TypeNamesApi
trait NamesApi extends NamesBase {
- val ANON_CLASS_NAME: NameType
- val ANON_FUN_NAME: NameType
+ val ROOT: NameType
val EMPTY: NameType
val ERROR: NameType
- val IMPORT: NameType
- val MODULE_VAR_SUFFIX: NameType
val PACKAGE: NameType
- val ROOT: NameType
- val SPECIALIZED_SUFFIX: NameType
-
- def flattenedName(segments: Name*): NameType
}
trait TermNamesApi extends NamesApi with TermNamesBase {
- val EXPAND_SEPARATOR_STRING: String
- val IMPL_CLASS_SUFFIX: String
- val INTERPRETER_IMPORT_WRAPPER: String
- val INTERPRETER_LINE_PREFIX: String
- val INTERPRETER_VAR_PREFIX: String
- val INTERPRETER_WRAPPER_SUFFIX: String
- val LOCALDUMMY_PREFIX: String
val LOCAL_SUFFIX_STRING: String
- val MODULE_SUFFIX_NAME: TermName
- val NAME_JOIN_NAME: TermName
- val PROTECTED_PREFIX: String
- val PROTECTED_SET_PREFIX: String
- val SETTER_SUFFIX: TermName
- val SINGLETON_SUFFIX: String
- val SUPER_PREFIX_STRING: String
- val TRAIT_SETTER_SEPARATOR_STRING: String
-
- val FAKE_LOCAL_THIS: TermName
- val INITIALIZER: TermName
- val LAZY_LOCAL: TermName
- val UNIVERSE_BUILD: NameType
- val UNIVERSE_BUILD_PREFIX: NameType
- val UNIVERSE_PREFIX: NameType
- val UNIVERSE_SHORT: NameType
- val MIRROR_PREFIX: NameType
- val MIRROR_SHORT: NameType
- val MIRROR_UNTYPED: NameType
- val REIFY_FREE_PREFIX: NameType
- val REIFY_FREE_THIS_SUFFIX: NameType
- val REIFY_FREE_VALUE_SUFFIX: NameType
- val REIFY_SYMDEF_PREFIX: NameType
- val MIXIN_CONSTRUCTOR: TermName
- val MODULE_INSTANCE_FIELD: TermName
- val OUTER: TermName
- val OUTER_LOCAL: TermName
- val OUTER_SYNTH: TermName
- val SELECTOR_DUMMY: TermName
- val SELF: TermName
- val SPECIALIZED_INSTANCE: TermName
- val STAR: TermName
- val THIS: TermName
-
- val BITMAP_NORMAL: TermName
- val BITMAP_TRANSIENT: TermName
- val BITMAP_CHECKINIT: TermName
- val BITMAP_CHECKINIT_TRANSIENT: TermName
-
- val ROOTPKG: TermName
-
- val ADD: TermName
- val AND: TermName
- val ASR: TermName
- val DIV: TermName
- val EQ: TermName
- val EQL: TermName
- val GE: TermName
- val GT: TermName
- val HASHHASH: TermName
- val LE: TermName
- val LSL: TermName
- val LSR: TermName
- val LT: TermName
- val MINUS: TermName
- val MOD: TermName
- val MUL: TermName
- val NE: TermName
- val OR: TermName
- val PLUS : TermName
- val SUB: TermName
- val XOR: TermName
- val ZAND: TermName
- val ZOR: TermName
-
- val UNARY_~ : TermName
- val UNARY_+ : TermName
- val UNARY_- : TermName
- val UNARY_! : TermName
-
- val ??? : TermName
-
- def isConstructorName(name: Name): Boolean
- def isExceptionResultName(name: Name): Boolean
- def isImplClassName(name: Name): Boolean
- def isLocalDummyName(name: Name): Boolean
- def isLocalName(name: Name): Boolean
- def isLoopHeaderLabel(name: Name): Boolean
- def isModuleName(name: Name): Boolean
- def isOpAssignmentName(name: Name): Boolean
- def isProtectedAccessorName(name: Name): Boolean
- def isReplWrapperName(name: Name): Boolean
- def isSetterName(name: Name): Boolean
- def isSingletonName(name: Name): Boolean
- def isSuperAccessorName(name: Name): Boolean
- def isTraitSetterName(name: Name): Boolean
-
- def defaultGetterName(name: Name, pos: Int): TermName
- def defaultGetterToMethod(name: Name): TermName
- def expandedName(name: TermName, base: Symbol, separator: String): TermName
- def expandedSetterName(name: TermName, base: Symbol): TermName
- def getterName(name: TermName): TermName
- def getterToLocal(name: TermName): TermName
- def getterToSetter(name: TermName): TermName
- def localDummyName(clazz: Symbol): TermName
- def localToGetter(name: TermName): TermName
- def protName(name: Name): TermName
- def protSetterName(name: Name): TermName
- def setterToGetter(name: TermName): TermName
- def superName(name: Name): TermName
-
- def dropLocalSuffix(name: Name): Name
- def originalName(name: Name): Name
- def stripModuleSuffix(name: Name): Name
- def unspecializedName(name: Name): Name
- def segments(name: String, assumeTerm: Boolean): List[Name]
- def splitSpecializedName(name: Name): (Name, String, String)
}
trait TypeNamesApi extends NamesApi with TypeNamesBase {
- val BYNAME_PARAM_CLASS_NAME: TypeName
- val EQUALS_PATTERN_NAME: TypeName
- val JAVA_REPEATED_PARAM_CLASS_NAME: TypeName
- val LOCAL_CHILD: TypeName
- val REFINE_CLASS_NAME: TypeName
- val REPEATED_PARAM_CLASS_NAME: TypeName
- val WILDCARD_STAR: TypeName
- val REIFY_TYPECREATOR_PREFIX: NameType
- val REIFY_TREECREATOR_PREFIX: NameType
-
- def dropSingletonName(name: Name): TypeName
- def implClassName(name: Name): TypeName
- def interfaceName(implname: Name): TypeName
- def singletonName(name: Name): TypeName
}
}
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index 1d2888961b..c94c796279 100644
--- a/src/reflect/scala/reflect/api/Symbols.scala
+++ b/src/reflect/scala/reflect/api/Symbols.scala
@@ -232,31 +232,6 @@ trait Symbols extends base.Symbols { self: Universe =>
/** The overloaded alternatives of this symbol */
def alternatives: List[Symbol]
- /** Performs method overloading resolution. More precisely, resolves an overloaded TermSymbol
- * to a single, non-overloaded TermSymbol that accepts the specified argument types.
- * @param pre The prefix type, i.e. the type of the value the method is dispatched on.
- * This is required when resolving references to type parameters of the type
- * the method is declared in. For example if the method is declared in class `List[A]`,
- * providing the prefix as `List[Int]` allows the overloading resolution to use
- * `Int` instead of `A`.
- * @param targs Type arguments that a candidate alternative must be able to accept. Candidates
- * will be considered with these arguments substituted for their corresponding
- * type parameters.
- * @param posVargs Positional argument types that a candidate alternative must be able to accept.
- * @param nameVargs Named argument types that a candidate alternative must be able to accept.
- * Each element in the sequence should be a pair of a parameter name and an
- * argument type.
- * @param expected Return type that a candidate alternative has to be compatible with.
- * @return Either a single, non-overloaded Symbol referring to the selected alternative
- * or NoSymbol if no single member could be selected given the passed arguments.
- */
- def resolveOverloaded(
- pre: Type = NoPrefix,
- targs: Seq[Type] = List(),
- posVargs: Seq[Type] = List(),
- nameVargs: Seq[(TermName, Type)] = List(),
- expected: Type = NoType
- ): Symbol
}
/** The API of type symbols */
diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala
index 231b9b248b..01de5fa9a7 100644
--- a/src/reflect/scala/reflect/api/Types.scala
+++ b/src/reflect/scala/reflect/api/Types.scala
@@ -8,6 +8,15 @@ trait Types extends base.Types { self: Universe =>
/** The extended API of types
*/
abstract class TypeApi extends TypeBase {
+ /** The term symbol associated with the type, or `NoSymbol` for types
+ * that do not refer to a term symbol.
+ */
+ def termSymbol: Symbol
+
+ /** The type symbol associated with the type, or `NoSymbol` for types
+ * that do not refer to a type symbol.
+ */
+ def typeSymbol: Symbol
/** The defined or declared members with name `name` in this type;
* an OverloadedSymbol if several exist, NoSymbol if none exist.
diff --git a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
index fa758edf05..19f70ba785 100644
--- a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
+++ b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
@@ -226,7 +226,7 @@ trait BaseTypeSeqs {
override def map(g: Type => Type) = lateMap(g)
override def lateMap(g: Type => Type) = orig.lateMap(x => g(f(x)))
override def exists(p: Type => Boolean) = elems exists (x => p(f(x)))
- override protected def maxDepthOfElems: Int = elems map (x => typeDepth(f(x))) max
+ override protected def maxDepthOfElems: Int = elems.map(x => typeDepth(f(x))).max
override def toString = elems.mkString("MBTS(", ",", ")")
}
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index d9b63529eb..90aa0b732c 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -397,6 +397,16 @@ trait Definitions extends api.StandardDefinitions {
case _ => false
}
+ 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 isPrimitiveArray(tp: Type) = tp match {
case TypeRef(_, ArrayClass, arg :: Nil) => isPrimitiveValueClass(arg.typeSymbol)
case _ => false
diff --git a/src/reflect/scala/reflect/internal/Positions.scala b/src/reflect/scala/reflect/internal/Positions.scala
index 6ae9b40fcb..faa161d6b1 100644
--- a/src/reflect/scala/reflect/internal/Positions.scala
+++ b/src/reflect/scala/reflect/internal/Positions.scala
@@ -10,23 +10,25 @@ trait Positions extends api.Positions { self: SymbolTable =>
/** A position that wraps a set of trees.
* The point of the wrapping position is the point of the default position.
* If some of the trees are ranges, returns a range position enclosing all ranges
- * Otherwise returns default position.
+ * Otherwise returns default position that is either focused or not.
*/
- def wrappingPos(default: Position, trees: List[Tree]): Position = default
+ def wrappingPos(default: Position, trees: List[Tree]) = wrappingPos(default, trees, true)
+ def wrappingPos(default: Position, trees: List[Tree], focus: Boolean): Position = default
/** A position that wraps the non-empty set of trees.
* The point of the wrapping position is the point of the first trees' position.
- * If all some the trees are non-synthetic, returns a range position enclosing the non-synthetic trees
+ * If some of the trees are non-synthetic, returns a range position enclosing the non-synthetic trees
* Otherwise returns a synthetic offset position to point.
*/
def wrappingPos(trees: List[Tree]): Position = trees.head.pos
/** Ensure that given tree has no positions that overlap with
* any of the positions of `others`. This is done by
- * shortening the range or assigning TransparentPositions
- * to some of the nodes in `tree`.
+ * shortening the range, assigning TransparentPositions
+ * to some of the nodes in `tree` or focusing on the position.
*/
- def ensureNonOverlapping(tree: Tree, others: List[Tree]) {}
+ def ensureNonOverlapping(tree: Tree, others: List[Tree]){ ensureNonOverlapping(tree, others, true) }
+ def ensureNonOverlapping(tree: Tree, others: List[Tree], focus: Boolean) {}
trait PosAssigner extends Traverser {
var pos: Position
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index c018ddc88e..18f9928124 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -649,19 +649,18 @@ trait Printers extends api.Printers { self: SymbolTable =>
}
def show(name: Name): String = name match {
- // base.StandardNames
case tpnme.EMPTY => "tpnme.EMPTY"
case tpnme.ROOT => "tpnme.ROOT"
+ case tpnme.PACKAGE => "tpnme.PACKAGE"
case tpnme.EMPTY_PACKAGE_NAME => "tpnme.EMPTY_PACKAGE_NAME"
case tpnme.WILDCARD => "tpnme.WILDCARD"
- case nme.CONSTRUCTOR => "nme.CONSTRUCTOR"
- case nme.NO_NAME => "nme.NO_NAME"
- // api.StandardNames
- case tpnme.ERROR => "tpnme.ERROR"
- case nme.ERROR => "nme.ERROR"
case nme.EMPTY => "nme.EMPTY"
- case tpnme.PACKAGE => "tpnme.PACKAGE"
+ case nme.ROOT => "nme.ROOT"
case nme.PACKAGE => "nme.PACKAGE"
+ case nme.EMPTY_PACKAGE_NAME => "nme.EMPTY_PACKAGE_NAME"
+ case nme.WILDCARD => "nme.WILDCARD"
+ case nme.CONSTRUCTOR => "nme.CONSTRUCTOR"
+ case nme.ROOTPKG => "nme.ROOTPKG"
case _ =>
val prefix = if (name.isTermName) "newTermName(\"" else "newTypeName(\""
prefix + name.toString + "\")"
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 10d02376b1..959d4d31ee 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -78,286 +78,12 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def asType: Type = tpe
def asTypeIn(site: Type): Type = site.memberType(this)
def asTypeConstructor: Type = typeConstructor
+ def setFlags(flags: FlagSet): this.type = setInternalFlags(flags)
def setInternalFlags(flag: Long): this.type = { setFlag(flag); this }
def setTypeSignature(tpe: Type): this.type = { setInfo(tpe); this }
def getAnnotations: List[AnnotationInfo] = { initialize; annotations }
def setAnnotations(annots: AnnotationInfo*): this.type = { setAnnotations(annots.toList); this }
- def resolveOverloaded(
- pre: Type,
- targs: Seq[Type],
- posVargTypes: Seq[Type],
- nameVargTypes: Seq[(TermName, Type)],
- expected: Type
- ): Symbol = {
-
- // Begin Correlation Helpers
-
- def isCompatible(tp: Type, pt: Type): Boolean = {
- def isCompatibleByName(tp: Type, pt: Type): Boolean = pt match {
- case TypeRef(_, ByNameParamClass, List(res)) if !definitions.isByNameParamType(tp) =>
- isCompatible(tp, res)
- case _ =>
- false
- }
- (tp weak_<:< pt) || isCompatibleByName(tp, pt)
- }
-
- def signatureAsSpecific(method1: MethodSymbol, method2: MethodSymbol): Boolean = {
- (substituteTypeParams(method1), substituteTypeParams(method2)) match {
- case (NullaryMethodType(r1), NullaryMethodType(r2)) =>
- r1 weak_<:< r2
- case (NullaryMethodType(_), MethodType(_, _)) =>
- true
- case (MethodType(_, _), NullaryMethodType(_)) =>
- false
- case (MethodType(p1, _), MethodType(p2, _)) =>
- val len = p1.length max p2.length
- val sub = extend(p1 map (_.typeSignature), len)
- val sup = extend(p2 map (_.typeSignature), len)
- (sub corresponds sup)(isCompatible)
- }
- }
-
- def scopeMoreSpecific(method1: MethodSymbol, method2: MethodSymbol): Boolean = {
- val o1 = method1.owner.asClassSymbol
- val o2 = method2.owner.asClassSymbol
- val c1 = if (o1.hasFlag(Flag.MODULE)) o1.companionSymbol else o1
- val c2 = if (o2.hasFlag(Flag.MODULE)) o2.companionSymbol else o2
- c1.typeSignature <:< c2.typeSignature
- }
-
- def moreSpecific(method1: MethodSymbol, method2: MethodSymbol): Boolean = {
- def points(m1: MethodSymbol, m2: MethodSymbol) = {
- val p1 = if (signatureAsSpecific(m1, m2)) 1 else 0
- val p2 = if (scopeMoreSpecific(m1, m2)) 1 else 0
- p1 + p2
- }
- points(method1, method2) > points(method2, method1)
- }
-
- def combineInto (
- variadic: Boolean
- )(
- positional: Seq[Type],
- named: Seq[(TermName, Type)]
- )(
- target: Seq[TermName],
- defaults: Map[Int, Type]
- ): Option[Seq[Type]] = {
-
- val offset = positional.length
- val unfilled = target.zipWithIndex drop offset
- val canAcceptAllNameVargs = named forall { case (argName, _) =>
- unfilled exists (_._1 == argName)
- }
-
- val paramNamesUnique = {
- named.length == named.map(_._1).distinct.length
- }
-
- if (canAcceptAllNameVargs && paramNamesUnique) {
-
- val rest = unfilled map { case (paramName, paramIndex) =>
- val passedIn = named.collect {
- case (argName, argType) if argName == paramName => argType
- }.headOption
- if (passedIn isDefined) passedIn
- else defaults.get(paramIndex).map(_.asInstanceOf[Type])
- }
-
- val rest1 = {
- if (variadic && !rest.isEmpty && !rest.last.isDefined) rest.init
- else rest
- }
-
-
- if (rest1 forall (_.isDefined)) {
- val joined = positional ++ rest1.map(_.get)
- val repeatedCollapsed = {
- if (variadic) {
- val (normal, repeated) = joined.splitAt(target.length - 1)
- if (repeated.forall(_ =:= repeated.head)) Some(normal ++ repeated.headOption)
- else None
- }
- else Some(joined)
- }
- if (repeatedCollapsed.exists(_.length == target.length))
- repeatedCollapsed
- else if (variadic && repeatedCollapsed.exists(_.length == target.length - 1))
- repeatedCollapsed
- else None
- } else None
-
- } else None
- }
-
- // Begin Reflection Helpers
-
- // Replaces a repeated parameter type at the end of the parameter list
- // with a number of non-repeated parameter types in order to pad the
- // list to be nargs in length
- def extend(types: Seq[Type], nargs: Int): Seq[Type] = {
- if (isVarArgTypes(types)) {
- val repeatedType = types.last.normalize.typeArgs.head
- types.init ++ Seq.fill(nargs - (types.length - 1))(repeatedType)
- } else types
- }
-
- // Replaces by-name parameters with their result type and
- // TypeRefs with the thing they reference
- def unwrap(paramType: Type): Type = paramType match {
- case TypeRef(_, IntClass, _) => typeOf[Int]
- case TypeRef(_, LongClass, _) => typeOf[Long]
- case TypeRef(_, ShortClass, _) => typeOf[Short]
- case TypeRef(_, ByteClass, _) => typeOf[Byte]
- case TypeRef(_, CharClass, _) => typeOf[Char]
- case TypeRef(_, FloatClass, _) => typeOf[Float]
- case TypeRef(_, DoubleClass, _) => typeOf[Double]
- case TypeRef(_, BooleanClass, _) => typeOf[Boolean]
- case TypeRef(_, UnitClass, _) => typeOf[Unit]
- case TypeRef(_, NullClass, _) => typeOf[Null]
- case TypeRef(_, AnyClass, _) => typeOf[Any]
- case TypeRef(_, NothingClass, _) => typeOf[Nothing]
- case TypeRef(_, AnyRefClass, _) => typeOf[AnyRef]
- case TypeRef(_, ByNameParamClass, List(resultType)) => unwrap(resultType)
- case t: Type => t
- }
-
- // Gives the names of the parameters to a method
- def paramNames(signature: Type): Seq[TermName] = signature match {
- case PolyType(_, resultType) => paramNames(resultType)
- case MethodType(params, _) => params.map(_.name.asInstanceOf[TermName])
- case NullaryMethodType(_) => Seq.empty
- }
-
- def valParams(signature: Type): Seq[TermSymbol] = signature match {
- case PolyType(_, resultType) => valParams(resultType)
- case MethodType(params, _) => params.map(_.asTermSymbol)
- case NullaryMethodType(_) => Seq.empty
- }
-
- // Returns a map from parameter index to default argument type
- def defaultTypes(method: MethodSymbol): Map[Int, Type] = {
- val typeSig = substituteTypeParams(method)
- val owner = method.owner
- valParams(typeSig).zipWithIndex.filter(_._1.hasFlag(Flag.DEFAULTPARAM)).map { case(_, index) =>
- val name = nme.defaultGetterName(method.name.decodedName, index + 1)
- val default = owner.asType member name
- index -> default.typeSignature.asInstanceOf[NullaryMethodType].resultType
- }.toMap
- }
-
- // True if any of method's parameters have default values. False otherwise.
- def usesDefault(method: MethodSymbol): Boolean = valParams(method.typeSignature) drop(posVargTypes).length exists { param =>
- (param hasFlag Flag.DEFAULTPARAM) && nameVargTypes.forall { case (argName, _) =>
- param.name != argName
- }
- }
-
- // The number of type parameters that the method takes
- def numTypeParams(x: MethodSymbol): Int = {
- x.typeSignature.typeParams.length
- }
-
- def substituteTypeParams(m: MethodSymbol): Type = {
- (pre memberType m) match {
- case m: MethodType => m
- case n: NullaryMethodType => n
- case PolyType(tparams, rest) => rest.substituteTypes(tparams, targs.toList)
- }
- }
-
- // Begin Selection Helpers
-
- def select(
- alternatives: Seq[MethodSymbol],
- filters: Seq[Seq[MethodSymbol] => Seq[MethodSymbol]]
- ): Seq[MethodSymbol] =
- filters.foldLeft(alternatives)((a, f) => {
- if (a.size > 1) f(a) else a
- })
-
- // Drop arguments that take the wrong number of type
- // arguments.
- val posTargLength: Seq[MethodSymbol] => Seq[MethodSymbol] = _.filter { alt =>
- numTypeParams(alt) == targs.length
- }
-
- // Drop methods that are not applicable to the arguments
- val applicable: Seq[MethodSymbol] => Seq[MethodSymbol] = _.filter { alt =>
- // Note: combine returns None if a is not applicable and
- // None.exists(_ => true) == false
- val paramTypes =
- valParams(substituteTypeParams(alt)).map(p => unwrap(p.typeSignature))
- val variadic = isVarArgTypes(paramTypes)
- val maybeArgTypes =
- combineInto(variadic)(posVargTypes, nameVargTypes)(paramNames(alt.typeSignature), defaultTypes(alt))
- maybeArgTypes exists { argTypes =>
- if (isVarArgTypes(argTypes) && !isVarArgTypes(paramTypes)) false
- else {
- val a = argTypes
- val p = extend(paramTypes, argTypes.length)
- (a corresponds p)(_ weak_<:< _)
- }
- }
- }
-
- // Always prefer methods that don't need to use default
- // arguments over those that do.
- // e.g. when resolving foo(1), prefer def foo(x: Int) over
- // def foo(x: Int, y: Int = 4)
- val noDefaults: Seq[MethodSymbol] => Seq[MethodSymbol] =
- _ filterNot usesDefault
-
- // Try to select the most specific method. If that's not possible,
- // return all of the candidates (this will likely cause an error
- // higher up in the call stack)
- val mostSpecific: Seq[MethodSymbol] => Seq[MethodSymbol] = { alts =>
- val sorted = alts.sortWith(moreSpecific)
- val mostSpecific = sorted.head
- val agreeTest: MethodSymbol => Boolean =
- moreSpecific(mostSpecific, _)
- val disagreeTest: MethodSymbol => Boolean =
- moreSpecific(_, mostSpecific)
- if (!sorted.tail.forall(agreeTest)) {
- mostSpecific +: sorted.tail.filterNot(agreeTest)
- } else if (sorted.tail.exists(disagreeTest)) {
- mostSpecific +: sorted.tail.filter(disagreeTest)
- } else {
- Seq(mostSpecific)
- }
- }
-
- def finalResult(t: Type): Type = t match {
- case PolyType(_, rest) => finalResult(rest)
- case MethodType(_, result) => finalResult(result)
- case NullaryMethodType(result) => finalResult(result)
- case t: Type => t
- }
-
- // If a result type is given, drop alternatives that don't meet it
- val resultType: Seq[MethodSymbol] => Seq[MethodSymbol] =
- if (expected == NoType) identity
- else _.filter { alt =>
- finalResult(substituteTypeParams(alt)) <:< expected
- }
-
- def defaultFilteringOps =
- Seq(posTargLength, resultType, applicable, noDefaults, mostSpecific)
-
- // Begin Method Proper
-
-
- val alts = alternatives.map(_.asMethodSymbol)
-
- val selection = select(alts, defaultFilteringOps)
-
- val knownApplicable = applicable(selection)
-
- if (knownApplicable.size == 1) knownApplicable.head
- else NoSymbol
- }
}
/** The class for all symbols */
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index c3a6fce164..285700f9ff 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -143,6 +143,8 @@ abstract class TreeGen extends makro.TreeBuilder {
/** Computes stable type for a tree if possible */
def stableTypeFor(tree: Tree): Option[Type] = tree match {
+ case This(_) if tree.symbol != null && !tree.symbol.isError =>
+ Some(ThisType(tree.symbol))
case Ident(_) if tree.symbol.isStable =>
Some(singleType(tree.symbol.owner.thisType, tree.symbol))
case Select(qual, _) if ((tree.symbol ne null) && (qual.tpe ne null)) && // turned assert into guard for #4064
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index e92d644f4a..619e3bc170 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -469,7 +469,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
private var orig: Tree = null
private[scala] var wasEmpty: Boolean = false
- override def symbol = if (tpe == null) null else tpe.typeSymbol
+ override def symbol = typeTreeSymbol(this) // if (tpe == null) null else tpe.typeSymbol
override def isEmpty = (tpe eq null) || tpe == NoType
def original: Tree = orig
@@ -1024,6 +1024,14 @@ trait Trees extends api.Trees { self: SymbolTable =>
}
}
+
+ /** Delegate for a TypeTree symbol. This operation is unsafe because
+ * it may trigger type checking when forcing the type symbol of the
+ * underlying type.
+ */
+ protected def typeTreeSymbol(tree: TypeTree): Symbol =
+ if (tree.tpe == null) null else tree.tpe.typeSymbol
+
// --- generic traversers and transformers
override protected def itraverse(traverser: Traverser, tree: Tree): Unit = {
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 01679a777d..3a218c18f1 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -600,7 +600,7 @@ trait Types extends api.Types { self: SymbolTable =>
def decl(name: Name): Symbol = findDecl(name, 0)
/** A list of all non-private members defined or declared in this type. */
- def nonPrivateDecls: List[Symbol] = decls filter (x => !x.isPrivate) toList
+ def nonPrivateDecls: List[Symbol] = decls.filterNot(_.isPrivate).toList
/** The non-private defined or declared members with name `name` in this type;
* an OverloadedSymbol if several exist, NoSymbol if none exist.
@@ -1392,11 +1392,9 @@ trait Types extends api.Types { self: SymbolTable =>
final class UniqueThisType(sym: Symbol) extends ThisType(sym) with UniqueType { }
object ThisType extends ThisTypeExtractor {
- def apply(sym: Symbol): Type = {
- if (!phase.erasedTypes) unique(new UniqueThisType(sym))
- else if (sym.isImplClass) sym.typeOfThis
- else sym.tpe
- }
+ def apply(sym: Symbol): Type =
+ if (phase.erasedTypes) sym.tpe
+ else unique(new UniqueThisType(sym))
}
/** A class for singleton types of the form `<prefix>.<sym.name>.type`.
@@ -2613,7 +2611,7 @@ trait Types extends api.Types { self: SymbolTable =>
case class PolyType(override val typeParams: List[Symbol], override val resultType: Type)
extends Type with PolyTypeApi {
//assert(!(typeParams contains NoSymbol), this)
- assert(typeParams nonEmpty, this) // used to be a marker for nullary method type, illegal now (see @NullaryMethodType)
+ assert(typeParams.nonEmpty, this) // used to be a marker for nullary method type, illegal now (see @NullaryMethodType)
override def paramSectionCount: Int = resultType.paramSectionCount
override def paramss: List[List[Symbol]] = resultType.paramss
@@ -3275,7 +3273,7 @@ trait Types extends api.Types { self: SymbolTable =>
// to never be resumed with the current implementation
assert(!suspended, this)
TypeVar.trace("clone", originLocation)(
- TypeVar(origin, constr cloneInternal, typeArgs, params) // @M TODO: clone args/params?
+ TypeVar(origin, constr.cloneInternal, typeArgs, params) // @M TODO: clone args/params?
)
}
}
@@ -3637,7 +3635,7 @@ trait Types extends api.Types { self: SymbolTable =>
*/
object GenPolyType {
def apply(tparams: List[Symbol], tpe: Type): Type = (
- if (tparams nonEmpty) typeFun(tparams, tpe)
+ if (tparams.nonEmpty) typeFun(tparams, tpe)
else tpe // it's okay to be forgiving here
)
def unapply(tpe: Type): Option[(List[Symbol], Type)] = tpe match {
@@ -4652,14 +4650,14 @@ trait Types extends api.Types { self: SymbolTable =>
// dependent method types
object IsDependentCollector extends TypeCollector(false) {
def traverse(tp: Type) {
- if(tp isImmediatelyDependent) result = true
+ if (tp.isImmediatelyDependent) result = true
else if (!result) mapOver(tp)
}
}
object ApproximateDependentMap extends TypeMap {
def apply(tp: Type): Type =
- if(tp isImmediatelyDependent) WildcardType
+ if (tp.isImmediatelyDependent) WildcardType
else mapOver(tp)
}
@@ -6159,7 +6157,7 @@ trait Types extends api.Types { self: SymbolTable =>
}
val sorted = btsMap.toList.sortWith((x, y) => x._1.typeSymbol isLess y._1.typeSymbol)
- val maxSeqLength = sorted map (_._2.size) max
+ val maxSeqLength = sorted.map(_._2.size).max
val padded = sorted map (_._2.padTo(maxSeqLength, NoType))
val transposed = padded.transpose
@@ -6265,7 +6263,7 @@ trait Types extends api.Types { self: SymbolTable =>
}).mkString("")
println("Frontier(\n" + str + ")")
- printLubMatrix(ts zip tsBts toMap, lubListDepth)
+ printLubMatrix((ts zip tsBts).toMap, lubListDepth)
}
loop(newtps)
@@ -6275,7 +6273,7 @@ trait Types extends api.Types { self: SymbolTable =>
val initialBTSes = ts map (_.baseTypeSeq.toList)
if (printLubs)
- printLubMatrix(ts zip initialBTSes toMap, depth)
+ printLubMatrix((ts zip initialBTSes).toMap, depth)
loop(initialBTSes)
}
@@ -6483,7 +6481,7 @@ trait Types extends api.Types { self: SymbolTable =>
map2(narrowts, syms)((t, sym) => t.memberInfo(sym).substThis(t.typeSymbol, lubThisType))
if (proto.isTerm) // possible problem: owner of info is still the old one, instead of new refinement class
proto.cloneSymbol(lubRefined.typeSymbol).setInfoOwnerAdjusted(lub(symtypes, decr(depth)))
- else if (symtypes.tail forall (symtypes.head =:=))
+ else if (symtypes.tail forall (symtypes.head =:= _))
proto.cloneSymbol(lubRefined.typeSymbol).setInfoOwnerAdjusted(symtypes.head)
else {
def lubBounds(bnds: List[TypeBounds]): TypeBounds =
@@ -6857,7 +6855,7 @@ trait Types extends api.Types { self: SymbolTable =>
tps map {
case MethodType(params1, res) if (isSameTypes(params1 map (_.tpe), pts)) =>
res
- case NullaryMethodType(res) if pts isEmpty =>
+ case NullaryMethodType(res) if pts.isEmpty =>
res
case _ =>
throw new NoCommonType(tps)
diff --git a/src/reflect/scala/reflect/internal/util/Origins.scala b/src/reflect/scala/reflect/internal/util/Origins.scala
index 0bd5ad55ca..3111730f76 100644
--- a/src/reflect/scala/reflect/internal/util/Origins.scala
+++ b/src/reflect/scala/reflect/internal/util/Origins.scala
@@ -96,7 +96,7 @@ object Origins {
|| (el.getClassName startsWith "java.lang.")
)
private def findCutoff() = {
- val cutoff = Thread.currentThread.getStackTrace dropWhile preCutoff head;
+ val cutoff = (Thread.currentThread.getStackTrace dropWhile preCutoff).head
OriginId(cutoff.getClassName, cutoff.getMethodName)
}
diff --git a/src/reflect/scala/reflect/internal/util/SourceFile.scala b/src/reflect/scala/reflect/internal/util/SourceFile.scala
index df4a3336c3..793ef0ac22 100644
--- a/src/reflect/scala/reflect/internal/util/SourceFile.scala
+++ b/src/reflect/scala/reflect/internal/util/SourceFile.scala
@@ -41,7 +41,7 @@ abstract class SourceFile {
(content drop offset) startsWith text
def lineToString(index: Int): String =
- content drop lineToOffset(index) takeWhile (c => !isLineBreakChar(c.toChar)) mkString
+ content drop lineToOffset(index) takeWhile (c => !isLineBreakChar(c.toChar)) mkString ""
@tailrec
final def skipWhitespace(offset: Int): Int =
@@ -98,7 +98,7 @@ class ScriptSourceFile(underlying: BatchSourceFile, content: Array[Char], overri
override def positionInUltimateSource(pos: Position) =
if (!pos.isDefined) super.positionInUltimateSource(pos)
- else new OffsetPosition(underlying, pos.point + start)
+ else pos.withSource(underlying, start)
}
/** a file whose contents do not change over time */
diff --git a/src/reflect/scala/reflect/internal/util/TableDef.scala b/src/reflect/scala/reflect/internal/util/TableDef.scala
index d692a6d8f5..2e60ce3bcc 100644
--- a/src/reflect/scala/reflect/internal/util/TableDef.scala
+++ b/src/reflect/scala/reflect/internal/util/TableDef.scala
@@ -1,6 +1,7 @@
package scala.reflect.internal.util
import TableDef._
+import language.postfixOps
/** A class for representing tabular data in a way that preserves
* its inner beauty. See Exceptional for an example usage.
diff --git a/src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala b/src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala
index 5fbeb5f576..cecf8e4658 100644
--- a/src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala
+++ b/src/reflect/scala/reflect/internal/util/TraceSymbolActivity.scala
@@ -8,7 +8,8 @@ trait TraceSymbolActivity {
val global: SymbolTable
import global._
- if (traceSymbolActivity && global.isCompilerUniverse)
+ private[this] var enabled = traceSymbolActivity
+ if (enabled && global.isCompilerUniverse)
scala.sys addShutdownHook showAllSymbols()
private type Set[T] = scala.collection.immutable.Set[T]
@@ -21,23 +22,26 @@ trait TraceSymbolActivity {
val allTrees = mutable.Set[Tree]()
def recordSymbolsInTree(tree: Tree) {
- allTrees += tree
+ if (enabled)
+ allTrees += tree
}
def recordNewSymbol(sym: Symbol) {
- if (sym.id > 1) {
+ if (enabled && sym.id > 1) {
allSymbols(sym.id) = sym
allChildren(sym.owner.id) ::= sym.id
}
}
def recordNewSymbolOwner(sym: Symbol, newOwner: Symbol) {
- val sid = sym.id
- val oid = sym.owner.id
- val nid = newOwner.id
-
- prevOwners(sid) ::= (oid -> phase)
- allChildren(oid) = allChildren(oid) filterNot (_ == sid)
- allChildren(nid) ::= sid
+ if (enabled) {
+ val sid = sym.id
+ val oid = sym.owner.id
+ val nid = newOwner.id
+
+ prevOwners(sid) ::= (oid -> phase)
+ allChildren(oid) = allChildren(oid) filterNot (_ == sid)
+ allChildren(nid) ::= sid
+ }
}
/** TODO.
@@ -86,7 +90,7 @@ trait TraceSymbolActivity {
def prefix = (" " * (sym.ownerChain.length - 1)) + sym.id
try println("%s#%s %s".format(prefix, sym.accurateKindString, sym.name.decode))
catch {
- case x => println(prefix + " failed: " + x)
+ case x: Throwable => println(prefix + " failed: " + x)
}
allChildren(sym.id).sorted foreach showIdAndRemove
}
@@ -128,7 +132,8 @@ trait TraceSymbolActivity {
private def runBeforeErasure[T](body: => T): T = atPhase(findErasurePhase)(body)
def showAllSymbols() {
- if (!traceSymbolActivity) return
+ if (!enabled) return
+ enabled = false
allSymbols(1) = NoSymbol
println("" + allSymbols.size + " symbols created.")
diff --git a/src/reflect/scala/reflect/makro/Universe.scala b/src/reflect/scala/reflect/makro/Universe.scala
index a676f7f1de..d88e7e0bb8 100644
--- a/src/reflect/scala/reflect/makro/Universe.scala
+++ b/src/reflect/scala/reflect/makro/Universe.scala
@@ -24,8 +24,15 @@ abstract class Universe extends scala.reflect.api.Universe {
*/
trait SymbolContextApi extends SymbolApi with AttachableApi { this: Symbol =>
- // [Eugene++ to Martin] should we also add mutability methods here (similarly to what's done below for trees)?
- // I'm talking about `setAnnotations` and friends
+ def setFlags(flags: FlagSet): this.type
+
+ def setTypeSignature(tpe: Type): this.type
+
+ def setAnnotations(annots: AnnotationInfo*): this.type
+
+ def setName(name: Name): this.type
+
+ def setPrivateWithin(sym: Symbol): this.type
}
// Tree extensions ---------------------------------------------------------------
diff --git a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
index 7839850529..f696aceb93 100644
--- a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
+++ b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
@@ -38,6 +38,8 @@ object ReflectionUtils {
)
def show(cl: ClassLoader): String = {
+ import language.reflectiveCalls
+
def isAbstractFileClassLoader(clazz: Class[_]): Boolean = {
if (clazz == null) return false
if (clazz.getName == "scala.tools.nsc.interpreter.AbstractFileClassLoader") return true
diff --git a/src/reflect/scala/reflect/runtime/TwoWayCache.scala b/src/reflect/scala/reflect/runtime/TwoWayCache.scala
index c7bfb3435d..e2bf5773d2 100644
--- a/src/reflect/scala/reflect/runtime/TwoWayCache.scala
+++ b/src/reflect/scala/reflect/runtime/TwoWayCache.scala
@@ -1,27 +1,40 @@
package scala.reflect
package runtime
+import collection.mutable.WeakHashMap
+import java.lang.ref.WeakReference
+
/** A cache that maintains a bijection between Java reflection type `J`
* and Scala reflection type `S`.
+ *
+ * The cache is two-way weak (i.e. is powered by weak references),
+ * so that neither Java artifacts prevent Scala artifacts from being garbage collected,
+ * nor the other way around.
*/
-import collection.mutable.HashMap
-
private[runtime] class TwoWayCache[J, S] {
- private val toScalaMap = new HashMap[J, S]
- private val toJavaMap = new HashMap[S, J]
+ private val toScalaMap = new WeakHashMap[J, WeakReference[S]]
+ private val toJavaMap = new WeakHashMap[S, WeakReference[J]]
def enter(j: J, s: S) = synchronized {
// debugInfo("cached: "+j+"/"+s)
- toScalaMap(j) = s
- toJavaMap(s) = j
+ toScalaMap(j) = new WeakReference(s)
+ toJavaMap(s) = new WeakReference(j)
+ }
+
+ private object SomeRef {
+ def unapply[T](optRef: Option[WeakReference[T]]): Option[T] =
+ if (optRef.nonEmpty) {
+ val result = optRef.get.get
+ if (result != null) Some(result) else None
+ } else None
}
def toScala(key: J)(body: => S): S = synchronized {
toScalaMap get key match {
- case Some(v) =>
+ case SomeRef(v) =>
v
- case none =>
+ case _ =>
val result = body
enter(key, result)
result
@@ -30,9 +43,9 @@ private[runtime] class TwoWayCache[J, S] {
def toJava(key: S)(body: => J): J = synchronized {
toJavaMap get key match {
- case Some(v) =>
+ case SomeRef(v) =>
v
- case none =>
+ case _ =>
val result = body
enter(result, key)
result
@@ -41,11 +54,12 @@ private[runtime] class TwoWayCache[J, S] {
def toJavaOption(key: S)(body: => Option[J]): Option[J] = synchronized {
toJavaMap get key match {
- case None =>
+ case SomeRef(v) =>
+ Some(v)
+ case _ =>
val result = body
for (value <- result) enter(value, key)
result
- case some => some
}
}
}
diff --git a/src/reflect/scala/tools/nsc/io/File.scala b/src/reflect/scala/tools/nsc/io/File.scala
index eedf92ef98..1f3cac7ee1 100644
--- a/src/reflect/scala/tools/nsc/io/File.scala
+++ b/src/reflect/scala/tools/nsc/io/File.scala
@@ -120,13 +120,13 @@ class File(jfile: JFile)(implicit constructorCodec: Codec) extends Path(jfile) w
def writeAll(strings: String*): Unit = {
val out = bufferedWriter()
try strings foreach (out write _)
- finally out close
+ finally out.close()
}
def writeBytes(bytes: Array[Byte]): Unit = {
val out = bufferedOutput()
try out write bytes
- finally out close
+ finally out.close()
}
def appendAll(strings: String*): Unit = {
@@ -139,7 +139,7 @@ class File(jfile: JFile)(implicit constructorCodec: Codec) extends Path(jfile) w
def printlnAll(strings: String*): Unit = {
val out = printWriter()
try strings foreach (out println _)
- finally out close
+ finally out.close()
}
def safeSlurp(): Option[String] =
diff --git a/src/reflect/scala/tools/nsc/io/Path.scala b/src/reflect/scala/tools/nsc/io/Path.scala
index 984c96dfbb..74bd6cf16b 100644
--- a/src/reflect/scala/tools/nsc/io/Path.scala
+++ b/src/reflect/scala/tools/nsc/io/Path.scala
@@ -78,7 +78,7 @@ object Path {
else new Path(jfile)
/** Avoiding any shell/path issues by only using alphanumerics. */
- private[io] def randomPrefix = alphanumeric take 6 mkString
+ private[io] def randomPrefix = alphanumeric take 6 mkString ""
private[io] def fail(msg: String) = throw FileOperationException(msg)
}
import Path._
diff --git a/src/reflect/scala/tools/nsc/io/Streamable.scala b/src/reflect/scala/tools/nsc/io/Streamable.scala
index 03318674ee..4d872c0221 100644
--- a/src/reflect/scala/tools/nsc/io/Streamable.scala
+++ b/src/reflect/scala/tools/nsc/io/Streamable.scala
@@ -112,7 +112,7 @@ object Streamable {
finally stream.close()
def bytes(is: => InputStream): Array[Byte] =
- new Bytes { def inputStream() = is } toByteArray
+ (new Bytes { def inputStream() = is }).toByteArray
def slurp(is: => InputStream)(implicit codec: Codec): String =
new Chars { def inputStream() = is } slurp codec
diff --git a/src/reflect/scala/tools/nsc/io/VirtualDirectory.scala b/src/reflect/scala/tools/nsc/io/VirtualDirectory.scala
index 0bcb2de43f..7272921054 100644
--- a/src/reflect/scala/tools/nsc/io/VirtualDirectory.scala
+++ b/src/reflect/scala/tools/nsc/io/VirtualDirectory.scala
@@ -48,7 +48,7 @@ extends AbstractFile {
def iterator = files.values.toList.iterator
override def lookupName(name: String, directory: Boolean): AbstractFile =
- files get name filter (_.isDirectory == directory) orNull
+ (files get name filter (_.isDirectory == directory)).orNull
override def fileNamed(name: String): AbstractFile =
Option(lookupName(name, false)) getOrElse {
diff --git a/src/scalap/scala/tools/scalap/Arguments.scala b/src/scalap/scala/tools/scalap/Arguments.scala
index 37f6cd84ac..53f722994d 100644
--- a/src/scalap/scala/tools/scalap/Arguments.scala
+++ b/src/scalap/scala/tools/scalap/Arguments.scala
@@ -48,7 +48,7 @@ object Arguments {
def parseBinding(str: String, separator: Char): (String, String) = (str indexOf separator) match {
case -1 => argumentError("missing '" + separator + "' in binding '" + str + "'") ; Pair("", "")
- case idx => Pair(str take idx trim, str drop (idx + 1) trim)
+ case idx => Pair((str take idx).trim, (str drop (idx + 1)).trim)
}
def parse(args: Array[String]): Arguments = {
diff --git a/src/scalap/scala/tools/scalap/CodeWriter.scala b/src/scalap/scala/tools/scalap/CodeWriter.scala
index d895ce3836..f5db183abb 100644
--- a/src/scalap/scala/tools/scalap/CodeWriter.scala
+++ b/src/scalap/scala/tools/scalap/CodeWriter.scala
@@ -58,7 +58,7 @@ class CodeWriter(writer: Writer) {
try {
writer.write(nl)
} catch {
- case e => sys.error("IO error")
+ case e: Exception => sys.error("IO error")
}
line = align
align = true
@@ -127,7 +127,7 @@ class CodeWriter(writer: Writer) {
line = false
this
} catch {
- case e => sys.error("IO error")
+ case e: Exception => sys.error("IO error")
}
override def toString(): String = writer.toString()
diff --git a/src/scalap/scala/tools/scalap/Decode.scala b/src/scalap/scala/tools/scalap/Decode.scala
index 4e12075541..26cea76893 100644
--- a/src/scalap/scala/tools/scalap/Decode.scala
+++ b/src/scalap/scala/tools/scalap/Decode.scala
@@ -49,7 +49,7 @@ object Decode {
import classFile._
classFile annotation SCALA_SIG_ANNOTATION map { case Annotation(_, els) =>
- val bytesElem = els find (x => constant(x.elementNameIndex) == BYTES_VALUE) get
+ val bytesElem = els find (x => constant(x.elementNameIndex) == BYTES_VALUE) getOrElse null
val _bytes = bytesElem.elementValue match { case ConstValueIndex(x) => constantWrapped(x) }
val bytes = _bytes.asInstanceOf[StringBytesPair].bytes
val length = ByteCodecs.decode(bytes)
@@ -81,7 +81,7 @@ object Decode {
xs.toList map (_.name dropRight 1)
}
- (ssig.symbols collect f).flatten toList
+ (ssig.symbols collect f).flatten.toList
}
}
diff --git a/src/scalap/scala/tools/scalap/MetaParser.scala b/src/scalap/scala/tools/scalap/MetaParser.scala
index ca9bd93f86..036738c5e9 100644
--- a/src/scalap/scala/tools/scalap/MetaParser.scala
+++ b/src/scalap/scala/tools/scalap/MetaParser.scala
@@ -61,7 +61,7 @@ class MetaParser(meta: String) {
else
None
} catch {
- case _ => None
+ case _: Exception => None
}
} else
None;
diff --git a/src/scalap/scala/tools/scalap/scalax/rules/package.scala b/src/scalap/scala/tools/scalap/scalax/rules/package.scala
new file mode 100644
index 0000000000..324e87435e
--- /dev/null
+++ b/src/scalap/scala/tools/scalap/scalax/rules/package.scala
@@ -0,0 +1,9 @@
+package scala.tools.scalap
+package scalax
+
+package object rules {
+ implicit lazy val higherKinds = language.higherKinds
+ implicit lazy val postfixOps = language.postfixOps
+ implicit lazy val implicitConversions = language.implicitConversions
+ implicit lazy val reflectiveCalls = language.reflectiveCalls
+}
diff --git a/src/swing/scala/swing/Action.scala b/src/swing/scala/swing/Action.scala
index 9deea0f3d4..a609329510 100644
--- a/src/swing/scala/swing/Action.scala
+++ b/src/swing/scala/swing/Action.scala
@@ -135,7 +135,7 @@ abstract class Action(title0: String) {
def accelerator: Option[KeyStroke] =
toOption(peer.getValue(javax.swing.Action.ACCELERATOR_KEY))
def accelerator_=(k: Option[KeyStroke]) {
- peer.putValue(javax.swing.Action.ACCELERATOR_KEY, k orNull)
+ peer.putValue(javax.swing.Action.ACCELERATOR_KEY, k.orNull)
}
/**
diff --git a/src/swing/scala/swing/ComboBox.scala b/src/swing/scala/swing/ComboBox.scala
index 75f981064b..c7a457d082 100644
--- a/src/swing/scala/swing/ComboBox.scala
+++ b/src/swing/scala/swing/ComboBox.scala
@@ -6,8 +6,6 @@
** |/ **
\* */
-
-
package scala.swing
import event._
@@ -205,6 +203,6 @@ class ComboBox[A](items: Seq[A]) extends Component with Publisher {
def prototypeDisplayValue: Option[A] = toOption[A](peer.getPrototypeDisplayValue)
def prototypeDisplayValue_=(v: Option[A]) {
- peer.setPrototypeDisplayValue(v map toAnyRef orNull)
+ peer.setPrototypeDisplayValue((v map toAnyRef).orNull)
}
}
diff --git a/src/swing/scala/swing/GridBagPanel.scala b/src/swing/scala/swing/GridBagPanel.scala
index d5b2472e38..dd4cbe3bcf 100644
--- a/src/swing/scala/swing/GridBagPanel.scala
+++ b/src/swing/scala/swing/GridBagPanel.scala
@@ -6,13 +6,10 @@
** |/ **
\* */
-
-
package scala.swing
import java.awt.{GridBagConstraints, GridBagLayout}
-
object GridBagPanel {
object Fill extends Enumeration {
val None = Value(GridBagConstraints.NONE)
diff --git a/src/swing/scala/swing/RichWindow.scala b/src/swing/scala/swing/RichWindow.scala
index 977aab300a..8eb58d56c9 100644
--- a/src/swing/scala/swing/RichWindow.scala
+++ b/src/swing/scala/swing/RichWindow.scala
@@ -145,7 +145,7 @@ object Dialog {
initial: Int): Result.Value = {
val r = JOptionPane.showOptionDialog(nullPeer(parent), message, title,
optionType.id, messageType.id, Swing.wrapIcon(icon),
- entries map toAnyRef toArray, entries(initial))
+ (entries map toAnyRef).toArray, entries(initial))
Result(r)
}
@@ -157,7 +157,7 @@ object Dialog {
entries: Seq[A] = Nil,
initial: A): Option[A] = {
val e = if (entries.isEmpty) null
- else entries map toAnyRef toArray
+ else (entries map toAnyRef).toArray
val r = JOptionPane.showInputDialog(nullPeer(parent), message, title,
messageType.id, Swing.wrapIcon(icon),
e, initial)
diff --git a/src/swing/scala/swing/ScrollPane.scala b/src/swing/scala/swing/ScrollPane.scala
index 5c18bb138a..966d5889e2 100644
--- a/src/swing/scala/swing/ScrollPane.scala
+++ b/src/swing/scala/swing/ScrollPane.scala
@@ -65,17 +65,17 @@ class ScrollPane extends Component with Container {
def rowHeaderView: Option[Component] =
Option(peer.getRowHeader.getView) map UIElement.cachedWrapper[Component]
def rowHeaderView_=(c: Component) = peer.setRowHeaderView(c.peer)
- def rowHeaderView_=(c: Option[Component]) = peer.setRowHeaderView(c map (_.peer) orNull)
+ def rowHeaderView_=(c: Option[Component]) = peer.setRowHeaderView(c.map(_.peer).orNull)
def columnHeaderView: Option[Component] =
Option(peer.getColumnHeader.getView) map UIElement.cachedWrapper[Component]
def columnHeaderView_=(c: Component) = peer.setColumnHeaderView(c.peer)
- def columnHeaderView_=(c: Option[Component]) = peer.setColumnHeaderView(c map (_.peer) orNull)
+ def columnHeaderView_=(c: Option[Component]) = peer.setColumnHeaderView(c.map(_.peer).orNull)
def viewportView: Option[Component] =
Option(peer.getViewport.getView) map UIElement.cachedWrapper[Component]
def viewportView_=(c: Component) = peer.setViewportView(c.peer)
- def viewportView_=(c: Option[Component]) = peer.setViewportView(c map (_.peer) orNull)
+ def viewportView_=(c: Option[Component]) = peer.setViewportView(c.map(_.peer).orNull)
def verticalScrollBarPolicy = BarPolicy.wrap(peer.getVerticalScrollBarPolicy)
def verticalScrollBarPolicy_=(p: BarPolicy.Value) = peer.setVerticalScrollBarPolicy(p.verticalPeer)
diff --git a/src/swing/scala/swing/Swing.scala b/src/swing/scala/swing/Swing.scala
index 519ccbaf33..05291f9aee 100644
--- a/src/swing/scala/swing/Swing.scala
+++ b/src/swing/scala/swing/Swing.scala
@@ -15,6 +15,7 @@ import javax.swing.event._
import javax.swing.border._
import javax.swing.{JComponent, Icon, BorderFactory, SwingUtilities}
+
/**
* Helpers for this package.
*/
diff --git a/src/swing/scala/swing/UIElement.scala b/src/swing/scala/swing/UIElement.scala
index 04e2217943..a83496fff0 100644
--- a/src/swing/scala/swing/UIElement.scala
+++ b/src/swing/scala/swing/UIElement.scala
@@ -37,7 +37,7 @@ object UIElement {
case c: javax.swing.JComponent => c.getClientProperty(ClientKey)
case _ => wrapperCache.get(c)
}
- try { w.asInstanceOf[C] } catch { case _ => null }
+ try { w.asInstanceOf[C] } catch { case _: Exception => null }
}
/**
diff --git a/src/swing/scala/swing/Window.scala b/src/swing/scala/swing/Window.scala
index 7991026a69..db911be0d7 100644
--- a/src/swing/scala/swing/Window.scala
+++ b/src/swing/scala/swing/Window.scala
@@ -51,7 +51,7 @@ abstract class Window extends UIElement with RootPanel with Publisher { outer =>
peer.getRootPane.setDefaultButton(b.peer)
}
def defaultButton_=(b: Option[Button]) {
- peer.getRootPane.setDefaultButton(b map (_.peer) orNull)
+ peer.getRootPane.setDefaultButton(b.map(_.peer).orNull)
}
def dispose() { peer.dispose() }
diff --git a/src/swing/scala/swing/package.scala b/src/swing/scala/swing/package.scala
index d5095f021b..96530e2e94 100644
--- a/src/swing/scala/swing/package.scala
+++ b/src/swing/scala/swing/package.scala
@@ -14,6 +14,9 @@ package object swing {
type Image = java.awt.Image
type Font = java.awt.Font
+ implicit lazy val reflectiveCalls = language.reflectiveCalls
+ implicit lazy val implicitConversions = language.implicitConversions
+
private[swing] def ifNull[A](o: Object, a: A): A = if(o eq null) a else o.asInstanceOf[A]
private[swing] def toOption[A](o: Object): Option[A] = if(o eq null) None else Some(o.asInstanceOf[A])
private[swing] def toAnyRef(x: Any): AnyRef = x.asInstanceOf[AnyRef]