summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-08-17 09:14:09 -0700
committerPaul Phillips <paulp@improving.org>2012-08-17 09:14:09 -0700
commitb794f4a87f5217fd381f129cd75946a2ced6eb44 (patch)
tree872c1c5b20effcc499a3b1141ab4d9c1900bf2a9 /src
parent62d319e46ff672f523e266009025fe3723651229 (diff)
parent7fc860963a4f76cb18e44c20f2bdfb49641033f3 (diff)
downloadscala-b794f4a87f5217fd381f129cd75946a2ced6eb44.tar.gz
scala-b794f4a87f5217fd381f129cd75946a2ced6eb44.tar.bz2
scala-b794f4a87f5217fd381f129cd75946a2ced6eb44.zip
Merge remote-tracking branch 'origin/2.10.x' into merge-210
# By Eugene Burmako (12) and others # Via Paul Phillips (4) and others * origin/2.10.x: Fixes SI-6236. Fixes SI-6189. Hunting down eliminable :: allocations. Absolutize tools.nsc => scala.tools.nsc. more cleanup for typedMacroBody shaves more than 150 lines off typedMacroBody Optimization in SubstMap. removes dead code pull request feedback more macro cleanup further cleanup of transformTypeTagEvidenceParams macroImplSigs => macroImplSig Dominik's comments on api.Mirrors phaseId(currentPeriod) >= erasurePhase.id materializeImplicit and implicitsOfExpectedType cleanup of reflection- and macro-related stuff adds the `skipPackage` attribute to Scaladoc Fixes backend crash due to incorrect consumedTypes Fix SI-6208. mutable.Queue now returns mutable.Queue for collection methods rather than MutableList.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/macros/runtime/FrontEnds.scala4
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Infrastructure.scala14
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Settings.scala7
-rw-r--r--src/compiler/scala/reflect/macros/util/Traces.scala9
-rw-r--r--src/compiler/scala/reflect/reify/Reifier.scala8
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenSymbols.scala1
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenTypes.scala3
-rw-r--r--src/compiler/scala/reflect/reify/phases/Calculate.scala2
-rw-r--r--src/compiler/scala/reflect/reify/phases/Reshape.scala3
-rw-r--r--src/compiler/scala/reflect/reify/utils/NodePrinters.scala1
-rw-r--r--src/compiler/scala/tools/ant/Scaladoc.scala13
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala14
-rw-r--r--src/compiler/scala/tools/nsc/ast/NodePrinters.scala3
-rw-r--r--src/compiler/scala/tools/nsc/ast/Positions.scala7
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeDSL.scala4
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala4
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala7
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala22
-rwxr-xr-xsrc/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala9
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala25
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/ICodes.scala5
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala159
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala14
-rw-r--r--src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/IMain.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/Imports.scala2
-rw-r--r--src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala2
-rw-r--r--src/compiler/scala/tools/nsc/javac/JavaParsers.scala6
-rw-r--r--src/compiler/scala/tools/nsc/package.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/CleanUp.scala51
-rw-r--r--src/compiler/scala/tools/nsc/transform/Constructors.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala18
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala12
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala164
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala16
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala24
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Macros.scala636
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala18
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala1
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala29
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Unapplies.scala4
-rw-r--r--src/compiler/scala/tools/reflect/MacroImplementations.scala7
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala8
-rw-r--r--src/library/scala/Option.scala2
-rw-r--r--src/library/scala/collection/GenTraversableLike.scala12
-rw-r--r--src/library/scala/collection/mutable/Queue.scala12
-rw-r--r--src/library/scala/reflect/ScalaLongSignature.java3
-rw-r--r--src/library/scala/reflect/ScalaSignature.java2
-rw-r--r--src/library/scala/reflect/base/Base.scala36
-rw-r--r--src/library/scala/reflect/base/BuildUtils.scala8
-rw-r--r--src/library/scala/reflect/base/Exprs.scala5
-rw-r--r--src/library/scala/reflect/base/MirrorOf.scala2
-rw-r--r--src/library/scala/reflect/base/Positions.scala5
-rw-r--r--src/library/scala/reflect/base/StandardDefinitions.scala54
-rw-r--r--src/library/scala/reflect/base/Symbols.scala5
-rw-r--r--src/library/scala/reflect/base/TagInterop.scala5
-rw-r--r--src/library/scala/reflect/base/Trees.scala6
-rw-r--r--src/library/scala/reflect/base/TypeTags.scala5
-rw-r--r--src/library/scala/reflect/base/Types.scala2
-rw-r--r--src/library/scala/reflect/macros/internal/package.scala2
-rw-r--r--src/library/scala/util/Marshal.scala2
-rw-r--r--src/reflect/scala/reflect/api/FrontEnds.scala2
-rw-r--r--src/reflect/scala/reflect/api/Importers.scala2
-rw-r--r--src/reflect/scala/reflect/api/JavaUniverse.scala2
-rw-r--r--src/reflect/scala/reflect/api/Mirrors.scala20
-rw-r--r--src/reflect/scala/reflect/api/Positions.scala12
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala3
-rw-r--r--src/reflect/scala/reflect/api/TagInterop.scala8
-rw-r--r--src/reflect/scala/reflect/api/Types.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala95
-rw-r--r--src/reflect/scala/reflect/internal/Importers.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala9
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala44
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala2
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala33
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala13
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala30
-rw-r--r--src/reflect/scala/reflect/internal/util/Collections.scala4
-rw-r--r--src/reflect/scala/reflect/macros/Infrastructure.scala4
-rw-r--r--src/reflect/scala/reflect/macros/Settings.scala8
-rw-r--r--src/reflect/scala/reflect/macros/TreeBuilder.scala4
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala57
-rw-r--r--src/reflect/scala/reflect/runtime/SymbolLoaders.scala6
-rw-r--r--src/reflect/scala/reflect/runtime/SynchronizedOps.scala1
-rw-r--r--src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala2
-rw-r--r--src/reflect/scala/reflect/runtime/package.scala2
-rw-r--r--src/reflect/scala/tools/nsc/io/Path.scala2
-rw-r--r--src/scalap/scala/tools/scalap/Main.scala6
96 files changed, 823 insertions, 1095 deletions
diff --git a/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala b/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala
index 69fa416f8f..c5c1c84cde 100644
--- a/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala
+++ b/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala
@@ -41,7 +41,7 @@ trait FrontEnds extends scala.tools.reflect.FrontEnds {
}
def interactive(): Unit = universe.reporter match {
- case reporter: tools.nsc.reporters.AbstractReporter => reporter.displayPrompt()
+ case reporter: scala.tools.nsc.reporters.AbstractReporter => reporter.displayPrompt()
case _ => ()
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala b/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala
index 19fb03364e..0a8a8d015d 100644
--- a/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala
@@ -18,19 +18,7 @@ trait Infrastructure {
val libraryClassPath: List[java.net.URL] = universe.classPath.asURLs
- lazy val libraryClassLoader: ClassLoader = {
- val classpath = libraryClassPath
- var loader: ClassLoader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader)
-
- // [Eugene] a heuristic to detect REPL
- if (universe.settings.exposeEmptyPackage.value) {
- import scala.tools.nsc.interpreter._
- val virtualDirectory = universe.settings.outputDirs.getSingleOutput.get
- loader = new AbstractFileClassLoader(virtualDirectory, loader) {}
- }
-
- loader
- }
+ lazy val libraryClassLoader: ClassLoader = universe.analyzer.macroClassloader
type Run = universe.Run
diff --git a/src/compiler/scala/reflect/macros/runtime/Settings.scala b/src/compiler/scala/reflect/macros/runtime/Settings.scala
index 9c24273cd7..e9d9a17b81 100644
--- a/src/compiler/scala/reflect/macros/runtime/Settings.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Settings.scala
@@ -13,18 +13,17 @@ trait Settings {
def compilerSettings: List[String] = universe.settings.recreateArgs
def setCompilerSettings(options: String): this.type =
- // todo. is not going to work with quoted arguments with embedded whitespaces
+ // SI-5925: doesn't work with arguments that contains whitespaces
setCompilerSettings(options.split(" ").toList)
def setCompilerSettings(options: List[String]): this.type = {
- val settings = new tools.nsc.Settings(_ => ())
- // [Eugene] what settings should we exclude?
+ val settings = new scala.tools.nsc.Settings(_ => ())
settings.copyInto(universe.settings)
this
}
def withCompilerSettings[T](options: String)(op: => T): T =
- // todo. is not going to work with quoted arguments with embedded whitespaces
+ // SI-5925: doesn't work with arguments that contains whitespaces
withCompilerSettings(options.split(" ").toList)(op)
def withCompilerSettings[T](options: List[String])(op: => T): T = {
diff --git a/src/compiler/scala/reflect/macros/util/Traces.scala b/src/compiler/scala/reflect/macros/util/Traces.scala
index 6c2f115994..d16916b753 100644
--- a/src/compiler/scala/reflect/macros/util/Traces.scala
+++ b/src/compiler/scala/reflect/macros/util/Traces.scala
@@ -2,17 +2,12 @@ package scala.reflect.macros
package util
trait Traces {
- def globalSettings: tools.nsc.Settings
+ def globalSettings: scala.tools.nsc.Settings
- // [Eugene] lots of ways to log:
- // 1) trace(...)
- // 2) log(...)
- // 3) if (foo) { doStuff(); includingSomeLogs(); }
- // what is the conventional way of unifying this?
val macroDebugLite = globalSettings.YmacrodebugLite.value
val macroDebugVerbose = globalSettings.YmacrodebugVerbose.value
val macroTraceLite = scala.tools.nsc.util.trace when (macroDebugLite || macroDebugVerbose)
val macroTraceVerbose = scala.tools.nsc.util.trace when macroDebugVerbose
@inline final def macroLogLite(msg: => Any) { if (macroDebugLite || macroDebugVerbose) println(msg) }
@inline final def macroLogVerbose(msg: => Any) { if (macroDebugVerbose) println(msg) }
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala
index 30b232c779..2b6ce23d57 100644
--- a/src/compiler/scala/reflect/reify/Reifier.scala
+++ b/src/compiler/scala/reflect/reify/Reifier.scala
@@ -52,7 +52,6 @@ abstract class Reifier extends States
*/
lazy val reification: Tree = {
try {
- // [Eugene] conventional way of doing this?
if (universe exists (_.isErroneous)) CannotReifyErroneousPrefix(universe)
if (universe.tpe == null) CannotReifyUntypedPrefix(universe)
@@ -62,7 +61,6 @@ abstract class Reifier extends States
reifyTrace("reifee is located at: ")(tree.pos)
reifyTrace("universe = ")(universe)
reifyTrace("mirror = ")(mirror)
- // [Eugene] conventional way of doing this?
if (tree exists (_.isErroneous)) CannotReifyErroneousReifee(tree)
if (tree.tpe == null) CannotReifyUntypedReifee(tree)
val pipeline = mkReificationPipeline
@@ -108,11 +106,7 @@ abstract class Reifier extends States
//
// todo. this is a common problem with non-trivial macros in our current macro system
// needs to be solved some day
- //
- // list of non-hygienic transformations:
- // todo. to be updated
- // [Eugene++] yeah, ugly and extremely brittle, but we do need to do resetAttrs. will be fixed later
- // todo. maybe try `resetLocalAttrs` once the dust settles
+ // maybe try `resetLocalAttrs` once the dust settles
var importantSymbols = Set[Symbol](
NothingClass, AnyClass, SingletonClass, PredefModule, ScalaRunTimeModule, TypeCreatorClass, TreeCreatorClass, MirrorOfClass,
BaseUniverseClass, JavaUniverseClass, ReflectRuntimePackage, ReflectRuntimeCurrentMirror)
diff --git a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
index 7f066a2cc3..ca6e14cfd3 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
@@ -72,6 +72,7 @@ trait GenSymbols {
*/
val hasPackagelessParent = sym.ownerChain.tail.tail exists (_.isEmptyPackageClass)
if (sym.isStatic && (sym.isClass || sym.isModule) && !hasPackagelessParent) {
+ // SI-6238: if applicable, emit references to StandardDefinitions instead of staticClass/staticModule calls
val resolver = if (sym.isType) nme.staticClass else nme.staticModule
mirrorMirrorCall(resolver, reify(sym.fullName))
} else {
diff --git a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala
index c762a28f99..1d2e177688 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala
@@ -23,7 +23,7 @@ trait GenTypes {
if (isSemiConcreteTypeMember(tpe))
return reifySemiConcreteTypeMember(tpe)
- // [Eugene] how do I check that the substitution is legal w.r.t tpe.info?
+ // SI-6242: splicing might violate type bounds
val spliced = spliceType(tpe)
if (spliced != EmptyTree)
return spliced
@@ -69,7 +69,6 @@ trait GenTypes {
def reificationIsConcrete: Boolean = state.reificationIsConcrete
def spliceType(tpe: Type): Tree = {
- // [Eugene] it seems that depending on the context the very same symbol can be either a spliceable tparam or a quantified existential. very weird!
val quantified = currentQuantified
if (tpe.isSpliceable && !(quantified contains tpe.typeSymbol)) {
if (reifyDebug) println("splicing " + tpe)
diff --git a/src/compiler/scala/reflect/reify/phases/Calculate.scala b/src/compiler/scala/reflect/reify/phases/Calculate.scala
index 41cf6c066a..4d1e22abe7 100644
--- a/src/compiler/scala/reflect/reify/phases/Calculate.scala
+++ b/src/compiler/scala/reflect/reify/phases/Calculate.scala
@@ -9,7 +9,7 @@ trait Calculate {
implicit class RichCalculateSymbol(sym: Symbol) {
def metalevel: Int = { assert(sym != null && sym != NoSymbol); localSymbols.getOrElse(sym, 0) }
- def isLocalToReifee = (localSymbols contains sym) // [Eugene] how do I account for local skolems?
+ def isLocalToReifee = (localSymbols contains sym) // todo. how do I account for local skolems?
}
implicit class RichCalculateType(tpe: Type) {
diff --git a/src/compiler/scala/reflect/reify/phases/Reshape.scala b/src/compiler/scala/reflect/reify/phases/Reshape.scala
index e26dd7e227..fcf3c0e65c 100644
--- a/src/compiler/scala/reflect/reify/phases/Reshape.scala
+++ b/src/compiler/scala/reflect/reify/phases/Reshape.scala
@@ -248,7 +248,6 @@ trait Reshape {
New(TypeTree(ann.atp) setOriginal extractOriginal(ann.original), List(args))
}
- // [Eugene] is this implemented correctly?
private def trimAccessors(deff: Tree, stats: List[Tree]): List[Tree] = {
val symdefs = (stats collect { case vodef: ValOrDefDef => vodef } map (vodeff => vodeff.symbol -> vodeff)).toMap
val accessors = collection.mutable.Map[ValDef, List[DefDef]]()
@@ -287,7 +286,7 @@ trait Reshape {
val name1 = nme.dropLocalSuffix(name)
val vdef1 = ValDef(mods2, name1, tpt, rhs)
if (reifyDebug) println("resetting visibility of field: %s => %s".format(vdef, vdef1))
- Some(vdef1) // no copyAttrs here, because new ValDef and old symbols are not out of sync
+ Some(vdef1) // no copyAttrs here, because new ValDef and old symbols are now out of sync
case ddef @ DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
if (accessors.values.exists(_.contains(ddef))) {
if (reifyDebug) println("discarding accessor method: " + ddef)
diff --git a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
index 420f55c0e0..ec1f132c1b 100644
--- a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
+++ b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
@@ -23,6 +23,7 @@ trait NodePrinters {
// depended upon. Of more fragile code I cannot conceive.
// @Eugene: This stuff is only needed to debug-print out reifications in human-readable format
// Rolling a full-fledged, robust TreePrinter would be several times more code.
+ // Also as of late we have tests that ensure that UX won't be broken by random changes to the reifier.
val lines = (tree.toString.split(EOL) drop 1 dropRight 1).toList splitAt 2
var (List(universe, mirror), reification) = lines
reification = (for (line <- reification) yield {
diff --git a/src/compiler/scala/tools/ant/Scaladoc.scala b/src/compiler/scala/tools/ant/Scaladoc.scala
index b96ac6f29b..b2c6441222 100644
--- a/src/compiler/scala/tools/ant/Scaladoc.scala
+++ b/src/compiler/scala/tools/ant/Scaladoc.scala
@@ -44,7 +44,8 @@ import scala.tools.nsc.reporters.{Reporter, ConsoleReporter}
* - `docgenerator`,
* - `docrootcontent`,
* - `unchecked`,
- * - `nofail`.
+ * - `nofail`,
+ * - `skipPackages`.
*
* It also takes the following parameters as nested elements:
* - `src` (for srcdir),
@@ -159,6 +160,9 @@ class Scaladoc extends ScalaMatchingTask {
/** Instruct the scaladoc tool to group similar functions together */
private var docGroups: Boolean = false
+ /** Instruct the scaladoc tool to skip certain packages */
+ private var docSkipPackages: String = ""
+
/*============================================================================*\
** Properties setters **
\*============================================================================*/
@@ -442,6 +446,12 @@ class Scaladoc extends ScalaMatchingTask {
def setGroups(input: String) =
docGroups = Flag.getBooleanValue(input, "groups")
+ /** Instruct the scaladoc tool to skip certain packages.
+ * @param input A colon-delimited list of fully qualified package names that will be skipped from scaladoc.
+ */
+ def setSkipPackages(input: String) =
+ docSkipPackages = input
+
/*============================================================================*\
** Properties getters **
\*============================================================================*/
@@ -642,6 +652,7 @@ class Scaladoc extends ScalaMatchingTask {
docSettings.docRawOutput.value = docRawOutput
docSettings.docNoPrefixes.value = docNoPrefixes
docSettings.docGroups.value = docGroups
+ docSettings.docSkipPackages.value = docSkipPackages
if(!docDiagramsDotPath.isEmpty) docSettings.docDiagramsDotPath.value = docDiagramsDotPath.get
if (!docgenerator.isEmpty) docSettings.docgenerator.value = docgenerator.get
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 6ecdbf1f3f..ce9153e70a 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -42,8 +42,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
with DocComments
with Positions { self =>
- // [Eugene++] would love to find better homes for the new things dumped into Global
-
// the mirror --------------------------------------------------
override def isCompilerUniverse = true
@@ -61,16 +59,14 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
}
def RootClass: ClassSymbol = rootMirror.RootClass
def EmptyPackageClass: ClassSymbol = rootMirror.EmptyPackageClass
- // [Eugene++] this little inconvenience gives us precise types for Expr.mirror and TypeTag.mirror
- // by the way, is it possible to define variant type members?
-
- override def settings = currentSettings
import definitions.findNamedMember
def findMemberFromRoot(fullName: Name): Symbol = rootMirror.findMemberFromRoot(fullName)
// alternate constructors ------------------------------------------
+ override def settings = currentSettings
+
def this(reporter: Reporter) =
this(new Settings(err => reporter.error(null, err)), reporter)
@@ -827,8 +823,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** Is given package class a system package class that cannot be invalidated?
*/
private def isSystemPackageClass(pkg: Symbol) =
- // [Eugene++ to Martin] please, verify
-// was: pkg == definitions.RootClass ||
pkg == RootClass ||
pkg == definitions.ScalaPackageClass || {
val pkgname = pkg.fullName
@@ -891,8 +885,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
else new MergedClassPath(elems, classPath.context)
val oldEntries = mkClassPath(subst.keys)
val newEntries = mkClassPath(subst.values)
- // [Eugene++ to Martin] please, verify
-// was: reSync(definitions.RootClass, Some(classPath), Some(oldEntries), Some(newEntries), invalidated, failed)
reSync(RootClass, Some(classPath), Some(oldEntries), Some(newEntries), invalidated, failed)
}
}
@@ -952,8 +944,6 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
invalidateOrRemove(root)
} else {
if (classesFound) {
- // [Eugene++ to Martin] please, verify
-// was: if (root.isRoot) invalidateOrRemove(definitions.EmptyPackageClass)
if (root.isRoot) invalidateOrRemove(EmptyPackageClass)
else failed += root
}
diff --git a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
index 1fdf4c631e..0b54eda66d 100644
--- a/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
+++ b/src/compiler/scala/tools/nsc/ast/NodePrinters.scala
@@ -145,8 +145,7 @@ abstract class NodePrinters {
str.toString
}
def printModifiers(tree: MemberDef) {
- // [Eugene++] there's most likely a bug here (?)
- // see `Printers.printAnnotations` for more information
+ // SI-5885: by default this won't print annotations of not yet initialized symbols
val annots0 = tree.symbol.annotations match {
case Nil => tree.mods.annotations
case xs => xs map annotationInfoToString
diff --git a/src/compiler/scala/tools/nsc/ast/Positions.scala b/src/compiler/scala/tools/nsc/ast/Positions.scala
index 74d1f8ab4b..d8fb632f73 100644
--- a/src/compiler/scala/tools/nsc/ast/Positions.scala
+++ b/src/compiler/scala/tools/nsc/ast/Positions.scala
@@ -11,13 +11,6 @@ trait Positions extends scala.reflect.internal.Positions {
def validatePositions(tree: Tree) {}
- // [Eugene] disabling this for now. imo it doesn't justify pollution of the public API
- // override def _checkSetAnnotation(tree: Tree, annot: TreeAnnotation): Unit = {
- // if (tree.pos != NoPosition && tree.pos != annot.pos) debugwarn("Overwriting annotation "+ tree.annotation +" of tree "+ tree +" with annotation "+ annot)
- // // if ((tree.annotation.isInstanceOf[scala.reflect.internal.util.Position] || !annot.isInstanceOf[scala.reflect.internal.util.Position]) && tree.isInstanceOf[Block])
- // // println("Updating block from "+ tree.annotation +" to "+ annot)
- // }
-
class ValidatingPosAssigner extends PosAssigner {
var pos: Position = _
override def traverse(t: Tree) {
diff --git a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
index 2ee38d4b91..e90d779885 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeDSL.scala
@@ -95,7 +95,7 @@ trait TreeDSL {
def INT_>= (other: Tree) = fn(target, getMember(IntClass, nme.GE), other)
def INT_== (other: Tree) = fn(target, getMember(IntClass, nme.EQ), other)
def INT_!= (other: Tree) = fn(target, getMember(IntClass, nme.NE), other)
-
+
// generic operations on ByteClass, IntClass, LongClass
def GEN_| (other: Tree, kind: ClassSymbol) = fn(target, getMember(kind, nme.OR), other)
def GEN_& (other: Tree, kind: ClassSymbol) = fn(target, getMember(kind, nme.AND), other)
@@ -234,7 +234,7 @@ trait TreeDSL {
}
class DefTreeStart(val name: Name) extends TreeVODDStart with DefCreator {
def tparams: List[TypeDef] = Nil
- def vparamss: List[List[ValDef]] = List(Nil)
+ def vparamss: List[List[ValDef]] = ListOfNil
}
class IfStart(cond: Tree, thenp: Tree) {
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index d7352045f5..3ccd8ec4ae 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -44,7 +44,7 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
setInfo analyzer.ImportType(qual)
)
val importTree = (
- Import(qual, List(ImportSelector(nme.WILDCARD, -1, null, -1)))
+ Import(qual, ImportSelector.wildList)
setSymbol importSym
setType NoType
)
@@ -58,7 +58,7 @@ abstract class TreeGen extends reflect.internal.TreeGen with TreeDSL {
def mkUnchecked(expr: Tree): Tree = atPos(expr.pos) {
// This can't be "Annotated(New(UncheckedClass), expr)" because annotations
// are very picky about things and it crashes the compiler with "unexpected new".
- Annotated(New(scalaDot(UncheckedClass.name), List(Nil)), expr)
+ Annotated(New(scalaDot(UncheckedClass.name), ListOfNil), expr)
}
// if it's a Match, mark the selector unchecked; otherwise nothing.
def mkUncheckedMatch(tree: Tree) = tree match {
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 381b834a0c..b703a90ebf 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -111,16 +111,13 @@ trait Trees extends reflect.internal.Trees { self: Global =>
if (body forall treeInfo.isInterfaceMember) List()
else List(
atPos(wrappingPos(superPos, lvdefs)) (
- DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, List(), List(List()), TypeTree(), Block(lvdefs, Literal(Constant())))))
+ DefDef(NoMods, nme.MIXIN_CONSTRUCTOR, List(), ListOfNil, TypeTree(), Block(lvdefs, Literal(Constant())))))
} else {
// convert (implicit ... ) to ()(implicit ... ) if its the only parameter section
if (vparamss1.isEmpty || !vparamss1.head.isEmpty && vparamss1.head.head.mods.isImplicit)
vparamss1 = List() :: vparamss1;
val superRef: Tree = atPos(superPos)(gen.mkSuperSelect)
- def mkApply(fun: Tree, args: List[Tree]) = Apply(fun, args)
- val superCall = (superRef /: argss) (mkApply)
- // [Eugene++] no longer compiles after I moved the `Apply` case class into scala.reflect.internal
- // val superCall = (superRef /: argss) (Apply)
+ val superCall = (superRef /: argss) (Apply.apply)
List(
atPos(wrappingPos(superPos, lvdefs ::: argss.flatten)) (
DefDef(constrMods, nme.CONSTRUCTOR, List(), vparamss1, TypeTree(), Block(lvdefs ::: List(superCall), Literal(Constant())))))
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 391874c488..cbe9d96e4d 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -192,7 +192,7 @@ self =>
override def blockExpr(): Tree = skipBraces(EmptyTree)
- override def templateBody(isPre: Boolean) = skipBraces((emptyValDef, List(EmptyTree)))
+ override def templateBody(isPre: Boolean) = skipBraces((emptyValDef, EmptyTree.asList))
}
class UnitParser(val unit: global.CompilationUnit, patches: List[BracePatch]) extends SourceFileParser(unit.source) {
@@ -395,7 +395,7 @@ self =>
NoMods,
nme.CONSTRUCTOR,
Nil,
- List(Nil),
+ ListOfNil,
TypeTree(),
Block(List(Apply(gen.mkSuperSelect, Nil)), Literal(Constant(())))
)
@@ -404,7 +404,7 @@ self =>
def mainParamType = AppliedTypeTree(Ident(tpnme.Array), List(Ident(tpnme.String)))
def mainParameter = List(ValDef(Modifiers(Flags.PARAM), nme.argv, mainParamType, EmptyTree))
def mainSetArgv = List(ValDef(NoMods, nme.args, TypeTree(), Ident(nme.argv)))
- def mainNew = makeNew(Nil, emptyValDef, stmts, List(Nil), NoPosition, NoPosition)
+ def mainNew = makeNew(Nil, emptyValDef, stmts, ListOfNil, NoPosition, NoPosition)
def mainDef = DefDef(NoMods, nme.main, Nil, List(mainParameter), scalaDot(tpnme.Unit), Block(mainSetArgv, mainNew))
// object Main
@@ -2093,7 +2093,7 @@ self =>
def annotationExpr(): Tree = atPos(in.offset) {
val t = exprSimpleType()
if (in.token == LPAREN) New(t, multipleArgumentExprs())
- else New(t, List(Nil))
+ else New(t, ListOfNil)
}
/* -------- PARAMETERS ------------------------------------------- */
@@ -2732,10 +2732,10 @@ self =>
def templateParents(isTrait: Boolean): (List[Tree], List[List[Tree]]) = {
val parents = new ListBuffer[Tree] += startAnnotType()
val argss = (
- // TODO: the insertion of List(Nil) here is where "new Foo" becomes
+ // TODO: the insertion of ListOfNil here is where "new Foo" becomes
// indistinguishable from "new Foo()".
if (in.token == LPAREN && !isTrait) multipleArgumentExprs()
- else List(Nil)
+ else ListOfNil
)
while (in.token == WITH) {
@@ -2773,7 +2773,7 @@ self =>
val (self1, body1) = templateBodyOpt(traitParentSeen = isTrait)
(parents, argss, self1, earlyDefs ::: body1)
} else {
- (List(), List(List()), self, body)
+ (List(), ListOfNil, self, body)
}
} else {
val (parents, argss) = templateParents(isTrait = isTrait)
@@ -2800,7 +2800,7 @@ self =>
else {
newLineOptWhenFollowedBy(LBRACE)
val (self, body) = templateBodyOpt(traitParentSeen = false)
- (List(), List(List()), self, body)
+ (List(), ListOfNil, self, body)
}
)
def anyrefParents() = {
@@ -2813,7 +2813,7 @@ self =>
def anyvalConstructor() = (
// Not a well-formed constructor, has to be finished later - see note
// regarding AnyVal constructor in AddInterfaces.
- DefDef(NoMods, nme.CONSTRUCTOR, Nil, List(Nil), TypeTree(), Block(Nil, Literal(Constant())))
+ DefDef(NoMods, nme.CONSTRUCTOR, Nil, ListOfNil, TypeTree(), Block(Nil, Literal(Constant())))
)
val tstart0 = if (body.isEmpty && in.lastOffset < tstart) in.lastOffset else tstart
@@ -2834,7 +2834,7 @@ self =>
* @param isPre specifies whether in early initializer (true) or not (false)
*/
def templateBody(isPre: Boolean) = inBraces(templateStatSeq(isPre = isPre)) match {
- case (self, Nil) => (self, List(EmptyTree))
+ case (self, Nil) => (self, EmptyTree.asList)
case result => result
}
def templateBodyOpt(traitParentSeen: Boolean): (ValDef, List[Tree]) = {
@@ -2938,7 +2938,7 @@ self =>
/** Informal - for the repl and other direct parser accessors.
*/
def templateStats(): List[Tree] = templateStatSeq(isPre = false)._2 match {
- case Nil => List(EmptyTree)
+ case Nil => EmptyTree.asList
case stats => stats
}
diff --git a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
index 5afec611e9..146329183c 100755
--- a/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/SymbolicXMLBuilder.scala
@@ -162,7 +162,7 @@ abstract class SymbolicXMLBuilder(p: Parsers#Parser, preserveWS: Boolean) {
/** could optimize if args.length == 0, args.length == 1 AND args(0) is <: Node. */
def makeXMLseq(pos: Position, args: Seq[Tree]) = {
- val buffer = ValDef(NoMods, _buf, TypeTree(), New(_scala_xml_NodeBuffer, List(Nil)))
+ val buffer = ValDef(NoMods, _buf, TypeTree(), New(_scala_xml_NodeBuffer, ListOfNil))
val applies = args filterNot isEmptyText map (t => Apply(Select(Ident(_buf), _plus), List(t)))
atPos(pos)( Block(buffer :: applies.toList, Ident(_buf)) )
diff --git a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
index 73f5ec7b3c..1cd1b63691 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/TreeBuilder.scala
@@ -217,12 +217,12 @@ abstract class TreeBuilder {
atPos(cpos) {
ClassDef(
Modifiers(FINAL), x, Nil,
- Template(parents, self, NoMods, List(Nil), argss, stats, cpos.focus))
+ Template(parents, self, NoMods, ListOfNil, argss, stats, cpos.focus))
}),
atPos(npos) {
New(
Ident(x) setPos npos.focus,
- List(Nil))
+ ListOfNil)
}
)
}
@@ -546,10 +546,7 @@ abstract class TreeBuilder {
rhs1,
List(
atPos(pat1.pos) {
- def mkIdent(name: Name) = Ident(name)
- CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map mkIdent, true))
- // [Eugene++] no longer compiles after I moved the `Ident` case class into scala.reflect.internal
- // CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map Ident, true))
+ CaseDef(pat1, EmptyTree, makeTupleTerm(vars map (_._1) map Ident.apply, true))
}
))
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index a480429026..a40d8c1a06 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -880,14 +880,29 @@ abstract class GenICode extends SubComponent {
case app @ Apply(fun @ Select(qual, _), args)
if !ctx.method.symbol.isStaticConstructor
- && fun.symbol.isAccessor && fun.symbol.accessed.hasStaticAnnotation =>
+ && fun.symbol.isAccessor && fun.symbol.accessed.hasStaticAnnotation
+ && qual.tpe.typeSymbol.orElse(fun.symbol.owner).companionClass != NoSymbol =>
// bypass the accessor to the companion object and load the static field directly
- // the only place were this bypass is not done, is the static intializer for the static field itself
+ // this bypass is not done:
+ // - if the static intializer for the static field itself
+ // - if there is no companion class of the object owner - this happens in the REPL
val sym = fun.symbol
generatedType = toTypeKind(sym.accessed.info)
- val hostClass = qual.tpe.typeSymbol.orElse(sym.owner).companionClass
- val staticfield = hostClass.info.findMember(sym.accessed.name, NoFlags, NoFlags, false)
-
+ val hostOwner = qual.tpe.typeSymbol.orElse(sym.owner)
+ val hostClass = hostOwner.companionClass
+ val staticfield = hostClass.info.findMember(sym.accessed.name, NoFlags, NoFlags, false) orElse {
+ if (!currentRun.compiles(hostOwner)) {
+ // hostOwner was separately compiled -- the static field symbol needs to be recreated in hostClass
+ import Flags._
+ debuglog("recreating sym.accessed.name: " + sym.accessed.name)
+ val objectfield = hostOwner.info.findMember(sym.accessed.name, NoFlags, NoFlags, false)
+ val staticfield = hostClass.newVariable(newTermName(sym.accessed.name.toString), tree.pos, STATIC | SYNTHETIC | FINAL) setInfo objectfield.tpe
+ staticfield.addAnnotation(definitions.StaticClass)
+ hostClass.info.decls enter staticfield
+ staticfield
+ } else NoSymbol
+ }
+
if (sym.isGetter) {
ctx.bb.emit(LOAD_FIELD(staticfield, true) setHostClass hostClass, tree.pos)
ctx
diff --git a/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala b/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala
index a8d517aa74..ffe8c8afe3 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala
@@ -2,11 +2,6 @@
* Copyright 2005-2012 LAMP/EPFL
* @author Martin Odersky
*/
-/* NSC -- new scala compiler
- * Copyright 2005-2012 LAMP/EPFL
- * @author Martin Odersky
- */
-
package scala.tools.nsc
package backend
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala
index 4311fe9df5..1fcb406e96 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Opcodes.scala
@@ -82,10 +82,17 @@ trait Opcodes { self: ICodes =>
final val jumpsCat = 10
final val retCat = 11
+ private lazy val ObjectReferenceList = ObjectReference :: Nil
+
/** This class represents an instruction of the intermediate code.
* Each case subclass will represent a specific operation.
*/
abstract class Instruction extends Cloneable {
+ // Vlad: I used these for checking the quality of the implementation, and we should regularely run a build with them
+ // enabled. But for production these should definitely be disabled, unless we enjoy getting angry emails from Greg :)
+ //if (!this.isInstanceOf[opcodes.LOAD_EXCEPTION])
+ // assert(consumed == consumedTypes.length)
+ //assert(produced == producedTypes.length)
def category: Int = 0 // undefined
@@ -101,6 +108,7 @@ trait Opcodes { self: ICodes =>
def consumedTypes: List[TypeKind] = Nil
/** This instruction produces these types on top of the stack. */
+ // Vlad: I wonder why we keep producedTypes around -- it looks like an useless thing to have
def producedTypes: List[TypeKind] = Nil
/** This method returns the difference of size of the stack when the instruction is used */
@@ -143,7 +151,12 @@ trait Opcodes { self: ICodes =>
override def consumed = 0
override def produced = 1
- override def producedTypes = List(REFERENCE(clasz))
+ override def producedTypes =
+ // we're not allowed to have REFERENCE(Array), but what about compiling the Array class? Well, we use object for it.
+ if (clasz != global.definitions.ArrayClass)
+ REFERENCE(clasz) :: Nil
+ else
+ ObjectReference :: Nil
override def category = localsCat
}
@@ -157,7 +170,7 @@ trait Opcodes { self: ICodes =>
override def consumed = 0
override def produced = 1
- override def producedTypes = List(toTypeKind(constant.tpe))
+ override def producedTypes = toTypeKind(constant.tpe) :: Nil
override def category = constCat
}
@@ -171,8 +184,8 @@ trait Opcodes { self: ICodes =>
override def consumed = 2
override def produced = 1
- override def consumedTypes = List(ARRAY(kind), INT)
- override def producedTypes = List(kind)
+ override def consumedTypes = ARRAY(kind) :: INT :: Nil
+ override def producedTypes = kind :: Nil
override def category = arraysCat
}
@@ -185,7 +198,7 @@ trait Opcodes { self: ICodes =>
override def consumed = 0
override def produced = 1
- override def producedTypes = List(local.kind)
+ override def producedTypes = local.kind :: Nil
override def category = localsCat
}
@@ -203,8 +216,8 @@ trait Opcodes { self: ICodes =>
override def consumed = if (isStatic) 0 else 1
override def produced = 1
- override def consumedTypes = if (isStatic) Nil else List(REFERENCE(field.owner));
- override def producedTypes = List(toTypeKind(field.tpe));
+ override def consumedTypes = if (isStatic) Nil else REFERENCE(field.owner) :: Nil
+ override def producedTypes = toTypeKind(field.tpe) :: Nil
// more precise information about how to load this field
// see #4283
@@ -222,7 +235,7 @@ trait Opcodes { self: ICodes =>
override def consumed = 0
override def produced = 1
- override def producedTypes = List(REFERENCE(module))
+ override def producedTypes = REFERENCE(module) :: Nil
override def category = stackCat
}
@@ -235,7 +248,7 @@ trait Opcodes { self: ICodes =>
override def consumed = 3
override def produced = 0
- override def consumedTypes = List(ARRAY(kind), INT, kind)
+ override def consumedTypes = ARRAY(kind) :: INT :: kind :: Nil
override def category = arraysCat
}
@@ -248,7 +261,7 @@ trait Opcodes { self: ICodes =>
override def consumed = 1
override def produced = 0
- override def consumedTypes = List(local.kind)
+ override def consumedTypes = local.kind :: Nil
override def category = localsCat
}
@@ -267,9 +280,9 @@ trait Opcodes { self: ICodes =>
override def consumedTypes =
if (isStatic)
- List(toTypeKind(field.tpe))
+ toTypeKind(field.tpe) :: Nil
else
- List(REFERENCE(field.owner), toTypeKind(field.tpe));
+ REFERENCE(field.owner) :: toTypeKind(field.tpe) :: Nil;
override def category = fldsCat
}
@@ -281,7 +294,7 @@ trait Opcodes { self: ICodes =>
case class STORE_THIS(kind: TypeKind) extends Instruction {
override def consumed = 1
override def produced = 0
- override def consumedTypes = List(kind)
+ override def consumedTypes = kind :: Nil
override def category = localsCat
}
@@ -308,34 +321,34 @@ trait Opcodes { self: ICodes =>
override def produced = 1
override def consumedTypes = primitive match {
- case Negation(kind) => List(kind)
- case Test(_, kind, true) => List(kind)
- case Test(_, kind, false) => List(kind, kind)
- case Comparison(_, kind) => List(kind, kind)
- case Arithmetic(NOT, kind) => List(kind)
- case Arithmetic(_, kind) => List(kind, kind)
- case Logical(_, kind) => List(kind, kind)
- case Shift(_, kind) => List(kind, INT)
- case Conversion(from, _) => List(from)
- case ArrayLength(kind) => List(ARRAY(kind))
- case StringConcat(kind) => List(ConcatClass, kind)
+ case Negation(kind) => kind :: Nil
+ case Test(_, kind, true) => kind :: Nil
+ case Test(_, kind, false) => kind :: kind :: Nil
+ case Comparison(_, kind) => kind :: kind :: Nil
+ case Arithmetic(NOT, kind) => kind :: Nil
+ case Arithmetic(_, kind) => kind :: kind :: Nil
+ case Logical(_, kind) => kind :: kind :: Nil
+ case Shift(_, kind) => kind :: INT :: Nil
+ case Conversion(from, _) => from :: Nil
+ case ArrayLength(kind) => ARRAY(kind) :: Nil
+ case StringConcat(kind) => ConcatClass :: kind :: Nil
case StartConcat => Nil
- case EndConcat => List(ConcatClass)
+ case EndConcat => ConcatClass :: Nil
}
override def producedTypes = primitive match {
- case Negation(kind) => List(kind)
- case Test(_, _, true) => List(BOOL)
- case Test(_, _, false) => List(BOOL)
- case Comparison(_, _) => List(INT)
- case Arithmetic(_, kind) => List(kind)
- case Logical(_, kind) => List(kind)
- case Shift(_, kind) => List(kind)
- case Conversion(_, to) => List(to)
- case ArrayLength(_) => List(INT)
- case StringConcat(_) => List(ConcatClass)
- case StartConcat => List(ConcatClass)
- case EndConcat => List(REFERENCE(global.definitions.StringClass))
+ case Negation(kind) => kind :: Nil
+ case Test(_, _, true) => BOOL :: Nil
+ case Test(_, _, false) => BOOL :: Nil
+ case Comparison(_, _) => INT :: Nil
+ case Arithmetic(_, kind) => kind :: Nil
+ case Logical(_, kind) => kind :: Nil
+ case Shift(_, kind) => kind :: Nil
+ case Conversion(_, to) => to :: Nil
+ case ArrayLength(_) => INT :: Nil
+ case StringConcat(_) => ConcatClass :: Nil
+ case StartConcat => ConcatClass :: Nil
+ case EndConcat => REFERENCE(global.definitions.StringClass) :: Nil
}
override def category = arilogCat
@@ -381,14 +394,13 @@ trait Opcodes { self: ICodes =>
else args
}
- override def produced =
- if (producedType == UNIT || method.isConstructor) 0
- else 1
-
- private def producedType: TypeKind = toTypeKind(method.info.resultType)
- override def producedTypes =
- if (produced == 0) Nil
- else List(producedType)
+ private val producedList = toTypeKind(method.info.resultType) match {
+ case UNIT => Nil
+ case _ if method.isConstructor => Nil
+ case kind => kind :: Nil
+ }
+ override def produced = producedList.size
+ override def producedTypes = producedList
/** object identity is equality for CALL_METHODs. Needed for
* being able to store such instructions into maps, when more
@@ -404,15 +416,17 @@ trait Opcodes { self: ICodes =>
override def consumed = 1
override def consumedTypes = boxType :: Nil
override def produced = 1
+ override def producedTypes = BOXED(boxType) :: Nil
override def category = objsCat
}
case class UNBOX(boxType: TypeKind) extends Instruction {
- assert(boxType.isValueType && (boxType ne UNIT)) // documentation
+ assert(boxType.isValueType && !boxType.isInstanceOf[BOXED] && (boxType ne UNIT)) // documentation
override def toString(): String = "UNBOX " + boxType
override def consumed = 1
- override def consumedTypes = ObjectReference :: Nil
+ override def consumedTypes = ObjectReferenceList
override def produced = 1
+ override def producedTypes = boxType :: Nil
override def category = objsCat
}
@@ -426,6 +440,7 @@ trait Opcodes { self: ICodes =>
override def consumed = 0;
override def produced = 1;
+ override def producedTypes = kind :: Nil
/** The corresponding constructor call. */
var init: CALL_METHOD = _
@@ -445,6 +460,7 @@ trait Opcodes { self: ICodes =>
override def consumed = dims;
override def consumedTypes = List.fill(dims)(INT)
override def produced = 1;
+ override def producedTypes = ARRAY(elem) :: Nil
override def category = arraysCat
}
@@ -458,8 +474,9 @@ trait Opcodes { self: ICodes =>
override def toString(): String ="IS_INSTANCE "+typ
override def consumed = 1
- override def consumedTypes = ObjectReference :: Nil
override def produced = 1
+ override def consumedTypes = ObjectReferenceList
+ override def producedTypes = BOOL :: Nil
override def category = castsCat
}
@@ -474,8 +491,8 @@ trait Opcodes { self: ICodes =>
override def consumed = 1
override def produced = 1
- override val consumedTypes = List(ObjectReference)
- override def producedTypes = List(typ)
+ override def consumedTypes = ObjectReferenceList
+ override def producedTypes = typ :: Nil
override def category = castsCat
}
@@ -495,7 +512,7 @@ trait Opcodes { self: ICodes =>
override def consumed = 1
override def produced = 0
- override val consumedTypes = List(INT)
+ override def consumedTypes = INT :: Nil
def flatTagsCount: Int = { var acc = 0; var rest = tags; while(rest.nonEmpty) { acc += rest.head.length; rest = rest.tail }; acc } // a one-liner
@@ -536,7 +553,7 @@ trait Opcodes { self: ICodes =>
override def consumed = 2
override def produced = 0
- override val consumedTypes = List(kind, kind)
+ override def consumedTypes = kind :: kind :: Nil
override def category = jumpsCat
}
@@ -559,8 +576,7 @@ trait Opcodes { self: ICodes =>
override def consumed = 1
override def produced = 0
- override val consumedTypes = List(kind)
-
+ override def consumedTypes = kind :: Nil
override def category = jumpsCat
}
@@ -573,7 +589,7 @@ trait Opcodes { self: ICodes =>
override def consumed = if (kind == UNIT) 0 else 1
override def produced = 0
- // TODO override val consumedTypes = List(kind)
+ override def consumedTypes = if (kind == UNIT) Nil else kind :: Nil
override def category = retCat
}
@@ -592,6 +608,8 @@ trait Opcodes { self: ICodes =>
override def consumed = 1
override def produced = 0
+ override def consumedTypes = toTypeKind(clasz.tpe) :: Nil
+
override def category = retCat
}
@@ -606,6 +624,8 @@ trait Opcodes { self: ICodes =>
override def consumed = 1
override def produced = 0
+ override def consumedTypes = typ :: Nil
+
override def category = stackCat
}
@@ -616,6 +636,8 @@ trait Opcodes { self: ICodes =>
case class DUP (typ: TypeKind) extends Instruction {
override def consumed = 1
override def produced = 2
+ override def consumedTypes = typ :: Nil
+ override def producedTypes = typ :: typ :: Nil
override def category = stackCat
}
@@ -630,6 +652,8 @@ trait Opcodes { self: ICodes =>
override def consumed = 1
override def produced = 0
+ override def consumedTypes = ObjectReference :: Nil
+
override def category = objsCat
}
@@ -644,6 +668,8 @@ trait Opcodes { self: ICodes =>
override def consumed = 1;
override def produced = 0;
+ override def consumedTypes = ObjectReference :: Nil
+
override def category = objsCat
}
@@ -738,10 +764,10 @@ trait Opcodes { self: ICodes =>
override def consumed = 0
override def produced = 1
- override def producedTypes = List(msil_mgdptr(local.kind))
+ override def producedTypes = msil_mgdptr(local.kind) :: Nil
override def category = localsCat
- }
+ }
case class CIL_LOAD_FIELD_ADDRESS(field: Symbol, isStatic: Boolean) extends Instruction {
/** Returns a string representation of this instruction */
@@ -751,11 +777,11 @@ trait Opcodes { self: ICodes =>
override def consumed = if (isStatic) 0 else 1
override def produced = 1
- override def consumedTypes = if (isStatic) Nil else List(REFERENCE(field.owner));
- override def producedTypes = List(msil_mgdptr(REFERENCE(field.owner)));
+ override def consumedTypes = if (isStatic) Nil else REFERENCE(field.owner) :: Nil;
+ override def producedTypes = msil_mgdptr(REFERENCE(field.owner)) :: Nil;
override def category = fldsCat
-}
+ }
case class CIL_LOAD_ARRAY_ITEM_ADDRESS(kind: TypeKind) extends Instruction {
/** Returns a string representation of this instruction */
@@ -764,8 +790,8 @@ trait Opcodes { self: ICodes =>
override def consumed = 2
override def produced = 1
- override def consumedTypes = List(ARRAY(kind), INT)
- override def producedTypes = List(msil_mgdptr(kind))
+ override def consumedTypes = ARRAY(kind) :: INT :: Nil
+ override def producedTypes = msil_mgdptr(kind) :: Nil
override def category = arraysCat
}
@@ -773,16 +799,16 @@ trait Opcodes { self: ICodes =>
case class CIL_UNBOX(valueType: TypeKind) extends Instruction {
override def toString(): String = "CIL_UNBOX " + valueType
override def consumed = 1
- override def consumedTypes = ObjectReference :: Nil // actually consumes a 'boxed valueType'
+ override def consumedTypes = ObjectReferenceList // actually consumes a 'boxed valueType'
override def produced = 1
- override def producedTypes = List(msil_mgdptr(valueType))
+ override def producedTypes = msil_mgdptr(valueType) :: Nil
override def category = objsCat
}
case class CIL_INITOBJ(valueType: TypeKind) extends Instruction {
override def toString(): String = "CIL_INITOBJ " + valueType
override def consumed = 1
- override def consumedTypes = ObjectReference :: Nil // actually consumes a managed pointer
+ override def consumedTypes = ObjectReferenceList // actually consumes a managed pointer
override def produced = 0
override def category = objsCat
}
@@ -793,9 +819,8 @@ trait Opcodes { self: ICodes =>
override def consumed = method.tpe.paramTypes.length
override def consumedTypes = method.tpe.paramTypes map toTypeKind
override def produced = 1
- override def producedTypes = List(toTypeKind(method.tpe.resultType))
+ override def producedTypes = toTypeKind(method.tpe.resultType) :: Nil
override def category = objsCat
}
-
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 1a9201fd67..96a88b1b0e 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -2217,15 +2217,11 @@ abstract class GenASM extends SubComponent with BytecodeWriters {
def getMerged(): collection.Map[Local, List[Interval]] = {
// TODO should but isn't: unbalanced start(s) of scope(s)
val shouldBeEmpty = pending filter { p => val Pair(k, st) = p; st.nonEmpty };
-
- val merged = mutable.Map.empty[Local, List[Interval]]
-
- def addToMerged(lv: Local, start: Label, end: Label) {
- val ranges = merged.getOrElseUpdate(lv, Nil)
- val coalesced = fuse(ranges, Interval(start, end))
- merged.update(lv, coalesced)
- }
-
+ val merged = mutable.Map[Local, List[Interval]]()
+ def addToMerged(lv: Local, start: Label, end: Label) {
+ val intv = Interval(start, end)
+ merged(lv) = if (merged contains lv) fuse(merged(lv), intv) else intv :: Nil
+ }
for(LocVarEntry(lv, start, end) <- seen) { addToMerged(lv, start, end) }
/* for each var with unbalanced start(s) of scope(s):
diff --git a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
index 327436ed20..89195020c4 100644
--- a/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
+++ b/src/compiler/scala/tools/nsc/doc/model/ModelFactoryImplicitSupport.scala
@@ -176,7 +176,7 @@ trait ModelFactoryImplicitSupport {
val appliedTree = new ApplyImplicitView(viewTree, List(Ident("<argument>") setType viewTree.tpe.paramTypes.head))
val appliedTreeTyped: Tree = {
val newContext = context.makeImplicit(context.ambiguousErrors)
- newContext.macrosEnabled = false // [Eugene] I assume you want macro signature, not macro expansion
+ newContext.macrosEnabled = false
val newTyper = global.analyzer.newTyper(newContext)
newTyper.silent(_.typed(appliedTree, global.analyzer.EXPRmode, WildcardType), false) match {
diff --git a/src/compiler/scala/tools/nsc/interpreter/IMain.scala b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
index 1626985823..c340b72ec3 100644
--- a/src/compiler/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/IMain.scala
@@ -145,7 +145,7 @@ class IMain(initialSettings: Settings, protected val out: JPrintWriter) extends
private def _initSources = List(new BatchSourceFile("<init>", "class $repl_$init { }"))
private def _initialize() = {
try {
- // [Eugene] todo. if this crashes, REPL will hang
+ // todo. if this crashes, REPL will hang
new _compiler.Run() compileSources _initSources
_initializeComplete = true
true
diff --git a/src/compiler/scala/tools/nsc/interpreter/Imports.scala b/src/compiler/scala/tools/nsc/interpreter/Imports.scala
index 6a14e1ea12..91b70726c2 100644
--- a/src/compiler/scala/tools/nsc/interpreter/Imports.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/Imports.scala
@@ -23,7 +23,7 @@ trait Imports {
val hd :: tl = sym.fullName.split('.').toList map newTermName
val tree = Import(
tl.foldLeft(Ident(hd): Tree)((x, y) => Select(x, y)),
- List(ImportSelector(nme.WILDCARD, -1, null, -1))
+ ImportSelector.wildList
)
tree setSymbol sym
new ImportHandler(tree)
diff --git a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
index a7ceda176e..04ccb87389 100644
--- a/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
+++ b/src/compiler/scala/tools/nsc/interpreter/TypeStrings.scala
@@ -213,7 +213,7 @@ trait TypeStrings {
private def tparamString[T: ru.TypeTag] : String = {
def typeArguments: List[ru.Type] = ru.typeOf[T] match { case ru.TypeRef(_, _, args) => args; case _ => Nil }
- // [Eugene++] todo. need to use not the `rootMirror`, but a mirror with the REPL's classloader
+ // [Eugene to Paul] need to use not the `rootMirror`, but a mirror with the REPL's classloader
// how do I get to it? acquiring context classloader seems unreliable because of multithreading
def typeVariables: List[java.lang.Class[_]] = typeArguments map (targ => ru.rootMirror.runtimeClass(targ))
brackets(typeArguments map (jc => tvarString(List(jc))): _*)
diff --git a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
index d1c404b3e3..c5da8822d5 100644
--- a/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
+++ b/src/compiler/scala/tools/nsc/javac/JavaParsers.scala
@@ -551,7 +551,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
if (parentToken == AT && in.token == DEFAULT) {
val annot =
atPos(pos) {
- New(Select(scalaDot(nme.runtime), tpnme.AnnotationDefaultATTR), List(List()))
+ New(Select(scalaDot(nme.runtime), tpnme.AnnotationDefaultATTR), ListOfNil)
}
mods1 = mods1 withAnnotations List(annot)
skipTo(SEMI)
@@ -640,7 +640,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
def importCompanionObject(cdef: ClassDef): Tree =
atPos(cdef.pos) {
- Import(Ident(cdef.name.toTermName), List(ImportSelector(nme.WILDCARD, -1, null, -1)))
+ Import(Ident(cdef.name.toTermName), ImportSelector.wildList)
}
// Importing the companion object members cannot be done uncritically: see
@@ -841,7 +841,7 @@ trait JavaParsers extends ast.parser.ParsersCommon with JavaScanners {
val predefs = List(
DefDef(
Modifiers(Flags.JAVA | Flags.STATIC), nme.values, List(),
- List(List()),
+ ListOfNil,
arrayOf(enumType),
blankExpr),
DefDef(
diff --git a/src/compiler/scala/tools/nsc/package.scala b/src/compiler/scala/tools/nsc/package.scala
index 9ad0d9ba1f..9d593e5acc 100644
--- a/src/compiler/scala/tools/nsc/package.scala
+++ b/src/compiler/scala/tools/nsc/package.scala
@@ -14,4 +14,6 @@ package object nsc {
type MissingRequirementError = scala.reflect.internal.MissingRequirementError
val MissingRequirementError = scala.reflect.internal.MissingRequirementError
+
+ val ListOfNil = List(Nil)
}
diff --git a/src/compiler/scala/tools/nsc/transform/CleanUp.scala b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
index 436867257a..300bf833a8 100644
--- a/src/compiler/scala/tools/nsc/transform/CleanUp.scala
+++ b/src/compiler/scala/tools/nsc/transform/CleanUp.scala
@@ -50,14 +50,14 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
private def transformTemplate(tree: Tree) = {
val t @ Template(parents, self, body) = tree
clearStatics()
-
+
val newBody = transformTrees(body)
val templ = deriveTemplate(tree)(_ => transformTrees(newStaticMembers.toList) ::: newBody)
try addStaticInits(templ) // postprocess to include static ctors
finally clearStatics()
}
private def mkTerm(prefix: String): TermName = unit.freshTermName(prefix)
-
+
//private val classConstantMeth = new HashMap[String, Symbol]
//private val symbolStaticFields = new HashMap[String, (Symbol, Tree, Tree)]
@@ -542,12 +542,12 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
else tree
}
-
+
case ValDef(mods, name, tpt, rhs) if tree.symbol.hasStaticAnnotation =>
log("moving @static valdef field: " + name + ", in: " + tree.symbol.owner)
val sym = tree.symbol
val owner = sym.owner
-
+
val staticBeforeLifting = atPhase(currentRun.erasurePhase) { owner.isStatic }
val isPrivate = atPhase(currentRun.typerPhase) { sym.getter(owner).hasFlag(PRIVATE) }
val isProtected = atPhase(currentRun.typerPhase) { sym.getter(owner).hasFlag(PROTECTED) }
@@ -574,19 +574,19 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
val compclass = enclosing.newClass(newTypeName(owner.name.toString))
compclass setInfo ClassInfoType(List(ObjectClass.tpe), newScope, compclass)
enclosing.info.decls enter compclass
-
- val compclstree = ClassDef(compclass, NoMods, List(List()), List(List()), List(), tree.pos)
-
+
+ val compclstree = ClassDef(compclass, NoMods, ListOfNil, ListOfNil, List(), tree.pos)
+
syntheticClasses.getOrElseUpdate(enclosing, mutable.Set()) += compclstree
-
+
compclass
case comp => comp
}
-
+
// create a static field in the companion class for this @static field
val stfieldSym = linkedClass.newVariable(newTermName(name), tree.pos, STATIC | SYNTHETIC | FINAL) setInfo sym.tpe
stfieldSym.addAnnotation(StaticClass)
-
+
val names = classNames.getOrElseUpdate(linkedClass, linkedClass.info.decls.collect {
case sym if sym.name.isTermName => sym.name
} toSet)
@@ -597,9 +597,9 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
)
} else {
linkedClass.info.decls enter stfieldSym
-
+
val initializerBody = rhs
-
+
// static field was previously initialized in the companion object itself, like this:
// staticBodies((linkedClass, stfieldSym)) = Select(This(owner), sym.getter(owner))
// instead, we move the initializer to the static ctor of the companion class
@@ -608,7 +608,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
}
}
super.transform(tree)
-
+
/* MSIL requires that the stack is empty at the end of a try-block.
* Hence, we here rewrite all try blocks with a result != {Unit, All} such that they
* store their result in a local variable. The catch blocks are adjusted as well.
@@ -722,7 +722,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
case Block(stats, expr) => stats :+ expr
case t => List(t)
}
-
+
val newCtor = findStaticCtor(template) match {
// in case there already were static ctors - augment existing ones
// currently, however, static ctors aren't being generated anywhere else
@@ -746,7 +746,7 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
deriveTemplate(template)(newCtor :: _)
}
}
-
+
private def addStaticDeclarations(tree: Template, clazz: Symbol) {
// add static field initializer statements for each static field in clazz
if (!clazz.isModuleClass) for {
@@ -757,22 +757,23 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
val valdef = staticBodies((clazz, stfieldSym))
val ValDef(_, _, _, rhs) = valdef
val fixedrhs = rhs.changeOwner((valdef.symbol, clazz.info.decl(nme.CONSTRUCTOR)))
-
+
val stfieldDef = localTyper.typedPos(tree.pos)(VAL(stfieldSym) === EmptyTree)
val flattenedInit = fixedrhs match {
case Block(stats, expr) => Block(stats, REF(stfieldSym) === expr)
case rhs => REF(stfieldSym) === rhs
}
val stfieldInit = localTyper.typedPos(tree.pos)(flattenedInit)
-
+
// add field definition to new defs
newStaticMembers append stfieldDef
newStaticInits append stfieldInit
+ case _ => // ignore @static on other members
}
}
-
-
-
+
+
+
override def transformStats(stats: List[Tree], exprOwner: Symbol): List[Tree] = {
super.transformStats(stats, exprOwner) ++ {
// flush pending synthetic classes created in this owner
@@ -785,22 +786,22 @@ abstract class CleanUp extends Transform with ast.TreeDSL {
case clsdef @ ClassDef(mods, name, tparams, t @ Template(parent, self, body)) =>
// process all classes in the package again to add static initializers
clearStatics()
-
+
addStaticDeclarations(t, clsdef.symbol)
-
+
val templ = deriveTemplate(t)(_ => transformTrees(newStaticMembers.toList) ::: body)
val ntempl =
try addStaticInits(templ)
finally clearStatics()
-
+
val derived = deriveClassDef(clsdef)(_ => ntempl)
classNames.remove(clsdef.symbol)
derived
-
+
case stat => stat
}
}
-
+
} // CleanUpTransformer
}
diff --git a/src/compiler/scala/tools/nsc/transform/Constructors.scala b/src/compiler/scala/tools/nsc/transform/Constructors.scala
index f2f4a44b02..afc109c47a 100644
--- a/src/compiler/scala/tools/nsc/transform/Constructors.scala
+++ b/src/compiler/scala/tools/nsc/transform/Constructors.scala
@@ -506,14 +506,14 @@ abstract class Constructors extends Transform with ast.TreeDSL {
val applyMethodDef = DefDef(
sym = applyMethod,
- vparamss = List(List()),
+ vparamss = ListOfNil,
rhs = Block(applyMethodStats, gen.mkAttributedRef(BoxedUnit_UNIT)))
ClassDef(
sym = closureClass,
constrMods = Modifiers(0),
vparamss = List(List(outerFieldDef)),
- argss = List(List()),
+ argss = ListOfNil,
body = List(applyMethodDef),
superPos = impl.pos)
}
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index c884a9a0c5..717d9209ae 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -966,7 +966,7 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL {
stats flatMap {
case stat @ Assign(lhs @ Select(This(_), _), rhs) => stat :: checkedGetter(lhs)
// remove initialization for default values
- case Apply(lhs @ Select(Ident(self), _), List(EmptyTree)) if lhs.symbol.isSetter => Nil
+ case Apply(lhs @ Select(Ident(self), _), EmptyTree.asList) if lhs.symbol.isSetter => Nil
case stat => List(stat)
},
exprOwner
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index 58914b61d8..3366244bc6 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -111,7 +111,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
case TypeRef(_, GroupOfSpecializable, arg :: Nil) =>
arg.typeArgs map (_.typeSymbol)
case _ =>
- List(tp.typeSymbol)
+ tp.typeSymbol :: Nil
}
}
}
@@ -362,7 +362,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// creating each permutation of concrete types
def loop(ctypes: List[List[Type]]): List[List[Type]] = ctypes match {
case Nil => Nil
- case set :: Nil => set map (x => List(x))
+ case set :: Nil => set map (_ :: Nil)
case set :: sets => for (x <- set ; xs <- loop(sets)) yield x :: xs
}
// zip the keys with each permutation to create a TypeEnv.
@@ -424,7 +424,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
case MethodType(argSyms, resTpe) => specializedTypeVars(resTpe :: argSyms.map(_.tpe))
case ExistentialType(_, res) => specializedTypeVars(res)
case AnnotatedType(_, tp, _) => specializedTypeVars(tp)
- case TypeBounds(lo, hi) => specializedTypeVars(List(lo, hi))
+ case TypeBounds(lo, hi) => specializedTypeVars(lo :: hi :: Nil)
case RefinedType(parents, _) => parents flatMap specializedTypeVars toSet
case _ => Set()
}
@@ -436,7 +436,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val sClassMap = anyrefSpecCache.getOrElseUpdate(sClass, mutable.Map[Symbol, Symbol]())
sClassMap.getOrElseUpdate(tparam,
- tparam.cloneSymbol(sClass, tparam.flags, (tparam.name append tpnme.SPECIALIZED_SUFFIX).asInstanceOf[Name]) // [Eugene++] why do we need this cast?
+ tparam.cloneSymbol(sClass, tparam.flags, (tparam.name append tpnme.SPECIALIZED_SUFFIX).asInstanceOf[Name]) // [Eugene] why do we need this cast?
modifyInfo (info => TypeBounds(info.bounds.lo, AnyRefClass.tpe))
).tpe
}
@@ -1772,10 +1772,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
private def forwardCall(pos: scala.reflect.internal.util.Position, receiver: Tree, paramss: List[List[ValDef]]): Tree = {
val argss = mmap(paramss)(x => Ident(x.symbol))
- def mkApply(fun: Tree, args: List[Tree]) = Apply(fun, args)
- atPos(pos) { (receiver /: argss) (mkApply) }
- // [Eugene++] no longer compiles after I moved the `Apply` case class into scala.reflect.internal
- // atPos(pos) { (receiver /: argss) (Apply) }
+ atPos(pos) { (receiver /: argss) (Apply.apply) }
}
/** Forward to the generic class constructor. If the current class initializes
@@ -1817,10 +1814,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
else
Ident(x.symbol)
)
- def mkApply(fun: Tree, args: List[Tree]) = Apply(fun, args)
- atPos(pos) { (receiver /: argss) (mkApply) }
- // [Eugene++] no longer compiles after I moved the `Apply` case class into scala.reflect.internal
- // atPos(pos) { (receiver /: argss) (Apply) }
+ atPos(pos) { (receiver /: argss) (Apply.apply) }
}
/** Add method m to the set of symbols for which we need an implementation tree
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index fc61997cd5..81b8427f18 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -277,7 +277,7 @@ abstract class UnCurry extends InfoTransform
localTyper.typedPos(fun.pos) {
Block(
- List(ClassDef(anonClass, NoMods, List(List()), List(List()), List(applyMethodDef), fun.pos)),
+ List(ClassDef(anonClass, NoMods, ListOfNil, ListOfNil, List(applyMethodDef), fun.pos)),
Typed(New(anonClass.tpe), TypeTree(fun.tpe)))
}
@@ -402,7 +402,7 @@ abstract class UnCurry extends InfoTransform
localTyper.typedPos(fun.pos) {
Block(
- List(ClassDef(anonClass, NoMods, List(List()), List(List()), List(applyOrElseMethodDef, isDefinedAtMethodDef), fun.pos)),
+ List(ClassDef(anonClass, NoMods, ListOfNil, ListOfNil, List(applyOrElseMethodDef, isDefinedAtMethodDef), fun.pos)),
Typed(New(anonClass.tpe), TypeTree(fun.tpe)))
}
}
@@ -564,7 +564,7 @@ abstract class UnCurry extends InfoTransform
sym.setInfo(MethodType(List(), tree.tpe))
tree.changeOwner(currentOwner -> sym)
localTyper.typedPos(tree.pos)(Block(
- List(DefDef(sym, List(Nil), tree)),
+ List(DefDef(sym, ListOfNil, tree)),
Apply(Ident(sym), Nil)
))
}
@@ -717,8 +717,12 @@ abstract class UnCurry extends InfoTransform
}
case dd @ DefDef(_, _, _, vparamss0, _, rhs0) =>
+ val vparamss1 = vparamss0 match {
+ case _ :: Nil => vparamss0
+ case _ => vparamss0.flatten :: Nil
+ }
val flatdd = copyDefDef(dd)(
- vparamss = List(vparamss0.flatten),
+ vparamss = vparamss1,
rhs = nonLocalReturnKeys get dd.symbol match {
case Some(k) => atPos(rhs0.pos)(nonLocalReturnTry(rhs0, k, dd.symbol))
case None => rhs0
diff --git a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
index 632f30b3a6..d0716e1a35 100644
--- a/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/ContextErrors.scala
@@ -8,12 +8,15 @@ package typechecker
import scala.collection.{ mutable, immutable }
import scala.reflect.internal.util.StringOps.{ countElementsAsString, countAsString }
-import symtab.Flags.{ PRIVATE, PROTECTED }
+import symtab.Flags.{ PRIVATE, PROTECTED, IS_ERROR }
+import scala.compat.Platform.EOL
trait ContextErrors {
self: Analyzer =>
import global._
+ import definitions._
+ import treeInfo._
object ErrorKinds extends Enumeration {
type ErrorKind = Value
@@ -424,8 +427,11 @@ trait ContextErrors {
def AbstractionFromVolatileTypeError(vd: ValDef) =
issueNormalTypeError(vd, "illegal abstraction from value with volatile type "+vd.symbol.tpe)
+ private[ContextErrors] def TypedApplyWrongNumberOfTpeParametersErrorMessage(fun: Tree) =
+ "wrong number of type parameters for "+treeSymTypeMsg(fun)
+
def TypedApplyWrongNumberOfTpeParametersError(tree: Tree, fun: Tree) = {
- issueNormalTypeError(tree, "wrong number of type parameters for "+treeSymTypeMsg(fun))
+ issueNormalTypeError(tree, TypedApplyWrongNumberOfTpeParametersErrorMessage(fun))
setError(tree)
}
@@ -622,11 +628,11 @@ trait ContextErrors {
}
// cyclic errors
- def CyclicAliasingOrSubtypingError(errPos: Position, sym0: Symbol) =
- issueTypeError(PosAndMsgTypeError(errPos, "cyclic aliasing or subtyping involving "+sym0))
+ def CyclicAliasingOrSubtypingError(errPos: Position, sym0: Symbol) =
+ issueTypeError(PosAndMsgTypeError(errPos, "cyclic aliasing or subtyping involving "+sym0))
- def CyclicReferenceError(errPos: Position, lockedSym: Symbol) =
- issueTypeError(PosAndMsgTypeError(errPos, "illegal cyclic reference involving " + lockedSym))
+ def CyclicReferenceError(errPos: Position, lockedSym: Symbol) =
+ issueTypeError(PosAndMsgTypeError(errPos, "illegal cyclic reference involving " + lockedSym))
}
}
@@ -750,21 +756,24 @@ trait ContextErrors {
kindErrors.toList.mkString("\n", ", ", ""))
}
- def NotWithinBounds(tree: Tree, prefix: String, targs: List[Type],
- tparams: List[Symbol], kindErrors: List[String]) = {
- if (settings.explaintypes.value) {
+ private[ContextErrors] def NotWithinBoundsErrorMessage(prefix: String, targs: List[Type], tparams: List[Symbol], explaintypes: Boolean) = {
+ if (explaintypes) {
val bounds = tparams map (tp => tp.info.instantiateTypeParams(tparams, targs).bounds)
(targs, bounds).zipped foreach ((targ, bound) => explainTypes(bound.lo, targ))
(targs, bounds).zipped foreach ((targ, bound) => explainTypes(targ, bound.hi))
()
}
- issueNormalTypeError(tree,
- prefix + "type arguments " + targs.mkString("[", ",", "]") +
- " do not conform to " + tparams.head.owner + "'s type parameter bounds " +
- (tparams map (_.defString)).mkString("[", ",", "]"))
+ prefix + "type arguments " + targs.mkString("[", ",", "]") +
+ " do not conform to " + tparams.head.owner + "'s type parameter bounds " +
+ (tparams map (_.defString)).mkString("[", ",", "]")
}
+ def NotWithinBounds(tree: Tree, prefix: String, targs: List[Type],
+ tparams: List[Symbol], kindErrors: List[String]) =
+ issueNormalTypeError(tree,
+ NotWithinBoundsErrorMessage(prefix, targs, tparams, settings.explaintypes.value))
+
//substExpr
def PolymorphicExpressionInstantiationError(tree: Tree, undetparams: List[Symbol], pt: Type) =
issueNormalTypeError(tree,
@@ -1084,4 +1093,133 @@ trait ContextErrors {
setError(arg)
}
}
+
+ // using an exception here is actually a good idea
+ // because the lifespan of this exception is extremely small and controlled
+ // moreover exceptions let us avoid an avalanche of "if (!hasError) do stuff" checks
+ case object MacroBodyTypecheckException extends Exception with scala.util.control.ControlThrowable
+
+ trait MacroErrors {
+ self: MacroTyper =>
+
+ private implicit val context0 = typer.context
+ val context = typer.context
+
+ // helpers
+
+ private def lengthMsg(flavor: String, violation: String, extra: Symbol) = {
+ val noun = if (flavor == "value") "parameter" else "type parameter"
+ val message = noun + " lists have different length, " + violation + " extra " + noun
+ val suffix = if (extra ne NoSymbol) " " + extra.defString else ""
+ message + suffix
+ }
+
+ private def abbreviateCoreAliases(s: String): String = List("AbsTypeTag", "Expr").foldLeft(s)((res, x) => res.replace("c.universe." + x, "c." + x))
+
+ private def showMeth(pss: List[List[Symbol]], restpe: Type, abbreviate: Boolean) = {
+ var argsPart = (pss map (ps => ps map (_.defString) mkString ("(", ", ", ")"))).mkString
+ if (abbreviate) argsPart = abbreviateCoreAliases(argsPart)
+ var retPart = restpe.toString
+ if (abbreviate || macroDdef.tpt.tpe == null) retPart = abbreviateCoreAliases(retPart)
+ argsPart + ": " + retPart
+ }
+
+ // not exactly an error generator, but very related
+ // and I dearly wanted to push it away from Macros.scala
+ private def checkSubType(slot: String, rtpe: Type, atpe: Type) = {
+ val ok = if (macroDebugVerbose || settings.explaintypes.value) {
+ if (rtpe eq atpe) println(rtpe + " <: " + atpe + "?" + EOL + "true")
+ withTypesExplained(rtpe <:< atpe)
+ } else rtpe <:< atpe
+ if (!ok) {
+ compatibilityError("type mismatch for %s: %s does not conform to %s".format(slot, abbreviateCoreAliases(rtpe.toString), abbreviateCoreAliases(atpe.toString)))
+ }
+ }
+
+ // errors
+
+ private def fail() = {
+ // need to set the IS_ERROR flag to prohibit spurious expansions
+ if (macroDef != null) macroDef setFlag IS_ERROR
+ // not setting ErrorSymbol as in `infer.setError`, because we still need to know that it's a macro
+ // otherwise assignTypeToTree in Namers might fail if macroDdef.tpt == EmptyTree
+ macroDdef setType ErrorType
+ throw MacroBodyTypecheckException
+ }
+
+ private def genericError(tree: Tree, message: String) = {
+ issueNormalTypeError(tree, message)
+ fail()
+ }
+
+ private def implRefError(message: String) = genericError(methPart(macroDdef.rhs), message)
+
+ private def compatibilityError(message: String) =
+ implRefError(
+ "macro implementation has wrong shape:"+
+ "\n required: " + showMeth(rparamss, rret, abbreviate = true) +
+ "\n found : " + showMeth(aparamss, aret, abbreviate = false) +
+ "\n" + message)
+
+ // Phase I: sanity checks
+
+ def MacroDefIsFastTrack() = {
+ macroLogVerbose("typecheck terminated unexpectedly: macro is fast track")
+ assert(!macroDdef.tpt.isEmpty, "fast track macros must provide result type")
+ throw MacroBodyTypecheckException // don't call fail, because we don't need IS_ERROR
+ }
+
+ def MacroFeatureNotEnabled() = {
+ macroLogVerbose("typecheck terminated unexpectedly: language.experimental.macros feature is not enabled")
+ fail()
+ }
+
+ // Phase II: typecheck the right-hand side of the macro def
+
+ // do nothing, just fail. relevant typecheck errors have already been reported
+ def MacroDefUntypeableBodyError() = fail()
+
+ def MacroDefInvalidBodyError() = genericError(macroDdef, "macro body has wrong shape:\n required: macro [<implementation object>].<method name>[[<type args>]]")
+
+ def MacroImplNotPublicError() = implRefError("macro implementation must be public")
+
+ def MacroImplOverloadedError() = implRefError("macro implementation cannot be overloaded")
+
+ def MacroImplWrongNumberOfTypeArgumentsError(macroImplRef: Tree) = implRefError(typer.TyperErrorGen.TypedApplyWrongNumberOfTpeParametersErrorMessage(macroImplRef))
+
+ def MacroImplNotStaticError() = implRefError("macro implementation must be in statically accessible object")
+
+ // Phase III: check compatibility between the macro def and its macro impl
+ // aXXX (e.g. aparams) => characteristics of the macro impl ("a" stands for "actual")
+ // rXXX (e.g. rparams) => characteristics of a reference macro impl signature synthesized from the macro def ("r" stands for "reference")
+
+ def MacroImplNonTagImplicitParameters(params: List[Symbol]) = compatibilityError("macro implementations cannot have implicit parameters other than AbsTypeTag evidences")
+
+ def MacroImplParamssMismatchError() = compatibilityError("number of parameter sections differ")
+
+ def MacroImplExtraParamsError(aparams: List[Symbol], rparams: List[Symbol]) = compatibilityError(lengthMsg("value", "found", aparams(rparams.length)))
+
+ def MacroImplMissingParamsError(aparams: List[Symbol], rparams: List[Symbol]) = compatibilityError(abbreviateCoreAliases(lengthMsg("value", "required", rparams(aparams.length))))
+
+ def checkMacroImplParamTypeMismatch(atpe: Type, rparam: Symbol) = checkSubType("parameter " + rparam.name, rparam.tpe, atpe)
+
+ def checkMacroImplResultTypeMismatch(atpe: Type, rret: Type) = checkSubType("return type", atpe, rret)
+
+ def MacroImplParamNameMismatchError(aparam: Symbol, rparam: Symbol) = compatibilityError("parameter names differ: " + rparam.name + " != " + aparam.name)
+
+ def MacroImplVarargMismatchError(aparam: Symbol, rparam: Symbol) = {
+ if (isRepeated(rparam) && !isRepeated(aparam))
+ compatibilityError("types incompatible for parameter " + rparam.name + ": corresponding is not a vararg parameter")
+ if (!isRepeated(rparam) && isRepeated(aparam))
+ compatibilityError("types incompatible for parameter " + aparam.name + ": corresponding is not a vararg parameter")
+ }
+
+ def MacroImplTargMismatchError(atargs: List[Type], atparams: List[Symbol]) =
+ compatibilityError(typer.infer.InferErrorGen.NotWithinBoundsErrorMessage("", atargs, atparams, macroDebugVerbose || settings.explaintypes.value))
+
+ def MacroImplTparamInstantiationError(atparams: List[Symbol], ex: NoInstance) =
+ compatibilityError(
+ "type parameters "+(atparams map (_.defString) mkString ", ")+" cannot be instantiated\n"+
+ ex.getMessage)
+ }
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index dd5588e9a6..6a908c6c65 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -27,6 +27,13 @@ trait Contexts { self: Analyzer =>
override def implicitss: List[List[ImplicitInfo]] = Nil
override def toString = "NoContext"
}
+ private object RootImports {
+ import definitions._
+ // Possible lists of root imports
+ val javaList = JavaLangPackage :: Nil
+ val javaAndScalaList = JavaLangPackage :: ScalaPackage :: Nil
+ val completeList = JavaLangPackage :: ScalaPackage :: PredefModule :: Nil
+ }
private val startContext = {
NoContext.make(
@@ -46,13 +53,12 @@ trait Contexts { self: Analyzer =>
* among its leading imports, or if the tree is [[scala.Predef]], `Predef` is not imported.
*/
protected def rootImports(unit: CompilationUnit): List[Symbol] = {
- import definitions._
- assert(isDefinitionsInitialized, "definitions uninitialized")
+ assert(definitions.isDefinitionsInitialized, "definitions uninitialized")
if (settings.noimports.value) Nil
- else if (unit.isJava) List(JavaLangPackage)
- else if (settings.nopredef.value || treeInfo.noPredefImportForUnit(unit.body)) List(JavaLangPackage, ScalaPackage)
- else List(JavaLangPackage, ScalaPackage, PredefModule)
+ else if (unit.isJava) RootImports.javaList
+ else if (settings.nopredef.value || treeInfo.noPredefImportForUnit(unit.body)) RootImports.javaAndScalaList
+ else RootImports.completeList
}
def rootContext(unit: CompilationUnit): Context = rootContext(unit, EmptyTree, false)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index f9035f26b9..a34fc71b8f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -1185,10 +1185,6 @@ trait Implicits {
// ClassTags are not path-dependent, so their materializer doesn't care about prefixes
if (tagClass eq ClassTagClass) gen.mkBasisUniverseRef
else pre match {
- // [Eugene to Martin] this is the crux of the interaction between
- // implicits and reifiers here we need to turn a (supposedly
- // path-dependent) type into a tree that will be used as a prefix I'm
- // not sure if I've done this right - please, review
case SingleType(prePre, preSym) =>
gen.mkAttributedRef(prePre, preSym) setType pre
// necessary only to compile typetags used inside the Universe cake
@@ -1341,13 +1337,7 @@ trait Implicits {
/** Materializes implicits of magic types (currently, manifests and tags).
* Will be replaced by implicit macros once we fix them.
*/
- private def materializeImplicit(pt: Type): SearchResult = {
- def fallback = {
- searchImplicit(implicitsOfExpectedType, false)
- // shouldn't we pass `pt` to `implicitsOfExpectedType`, or is the recursive case
- // for an abstract type really only meant for tags?
- }
-
+ private def materializeImplicit(pt: Type): SearchResult =
pt match {
case TypeRef(_, sym, _) if sym.isAbstractType =>
materializeImplicit(pt.dealias.bounds.lo) // #3977: use pt.dealias, not pt (if pt is a type alias, pt.bounds.lo == pt)
@@ -1363,17 +1353,17 @@ trait Implicits {
// unlike `dealias`, `betaReduce` performs at most one step of dealiasing
// while dealias pops all aliases in a single invocation
case sym if sym.isAliasType => materializeImplicit(pt.betaReduce)
- case _ => fallback
+ case _ => SearchFailure
}
case _ =>
- fallback
+ SearchFailure
}
- }
/** The result of the implicit search:
* First search implicits visible in current context.
* If that fails, search implicits in expected type `pt`.
- * // [Eugene] the following lines should be deleted after we migrate delegate tag materialization to implicit macros
+ *
+ * todo. the following lines should be deleted after we migrate delegate tag materialization to implicit macros
* If that fails, and `pt` is an instance of a ClassTag, try to construct a class tag.
* If that fails, and `pt` is an instance of a TypeTag, try to construct a type tag.
* If that fails, and `pt` is an instance of a ClassManifest, try to construct a class manifest.
@@ -1400,6 +1390,10 @@ trait Implicits {
result = materializeImplicit(pt)
+ // `materializeImplicit` does some preprocessing for `pt`
+ // is it only meant for manifests/tags or we need to do the same for `implicitsOfExpectedType`?
+ if (result == SearchFailure) result = searchImplicit(implicitsOfExpectedType, false)
+
if (result == SearchFailure) {
context.updateBuffer(previousErrs)
Statistics.stopTimer(oftypeFailNanos, failstart)
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index 032212e3c0..5673a724d1 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -1661,7 +1661,7 @@ trait Infer {
// for functional values, the `apply` method might be overloaded
val mtypes = followApply(alt.tpe) match {
case OverloadedType(_, alts) => alts map (_.tpe)
- case t => List(t)
+ case t => t :: Nil
}
// Drop those that use a default; keep those that use vararg/tupling conversion.
mtypes exists (t =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/Macros.scala b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
index c8bf70e9e0..4601f63809 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Macros.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Macros.scala
@@ -24,7 +24,7 @@ import scala.reflect.internal.util.Collections._
*
* Then fooBar needs to point to a static method of the following form:
*
- * def fooBar[T: c.AbsTypeTag]
+ * def fooBar[T: c.AbsTypeTag] // type tag annotation is optional
* (c: scala.reflect.macros.Context)
* (xs: c.Expr[List[T]])
* : c.Expr[T] = {
@@ -32,7 +32,7 @@ import scala.reflect.internal.util.Collections._
* }
*
* Then, if foo is called in qual.foo[Int](elems), where qual: D,
- * the macro application is expanded to a reflective invocation of fooBar with parameters
+ * the macro application is expanded to a reflective invocation of fooBar with parameters:
*
* (simpleMacroContext{ type PrefixType = D; val prefix = qual })
* (Expr(elems))
@@ -43,6 +43,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
import global._
import definitions._
+ import treeInfo.{isRepeatedParamType => _, _}
import MacrosStats._
def globalSettings = global.settings
@@ -132,9 +133,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
// there are some more clever cases when seemingly non-static method ends up being statically accessible
// however, the code below doesn't account for these guys, because it'd take a look of time to get it right
// for now I leave it as a todo and move along to more the important stuff
- // [Eugene] relies on the fact that macro implementations can only be defined in static classes
- // [Martin to Eugene++] There's similar logic buried in Symbol#flatname. Maybe we can refactor?
- // [Eugene] we will refactor once I get my hands on https://issues.scala-lang.org/browse/SI-5498
+ // todo. refactor when fixing SI-5498
def className: String = {
def loop(sym: Symbol): String = sym match {
case sym if sym.owner.isPackageClass =>
@@ -214,46 +213,110 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
MacroImplBinding.unpickle(pickle)
}
- /** A list of compatible macro implementation signatures.
+ /** Transforms parameters lists of a macro impl.
+ * The `transform` function is invoked only for AbsTypeTag evidence parameters.
*
- * In the example above:
+ * The transformer takes two arguments: a value parameter from the parameter list
+ * and a type parameter that is witnesses by the value parameter.
+ *
+ * If the transformer returns a NoSymbol, the value parameter is not included from the result.
+ * If the transformer returns something else, this something else is included in the result instead of the value parameter.
+ *
+ * Despite of being highly esoteric, this function significantly simplifies signature analysis.
+ * For example, it can be used to strip macroImpl.paramss from the evidences (necessary when checking def <-> impl correspondence)
+ * or to streamline creation of the list of macro arguments.
+ */
+ private def transformTypeTagEvidenceParams(paramss: List[List[Symbol]], transform: (Symbol, Symbol) => Symbol): List[List[Symbol]] = {
+ if (paramss.isEmpty || paramss.last.isEmpty) return paramss // no implicit parameters in the signature => nothing to do
+ if (paramss.head.isEmpty || !(paramss.head.head.tpe <:< MacroContextClass.tpe)) return paramss // no context parameter in the signature => nothing to do
+ def transformTag(param: Symbol): Symbol = param.tpe.dealias match {
+ case TypeRef(SingleType(SingleType(NoPrefix, c), universe), AbsTypeTagClass, targ :: Nil)
+ if c == paramss.head.head && universe == MacroContextUniverse =>
+ transform(param, targ.typeSymbol)
+ case _ =>
+ param
+ }
+ val transformed = paramss.last map transformTag filter (_ ne NoSymbol)
+ if (transformed.isEmpty) paramss.init else paramss.init :+ transformed
+ }
+
+ def computeMacroDefTypeFromMacroImpl(macroDdef: DefDef, macroImpl: Symbol): Type = {
+ // Step I. Transform c.Expr[T] to T
+ var runtimeType = macroImpl.tpe.finalResultType.dealias match {
+ case TypeRef(_, ExprClass, runtimeType :: Nil) => runtimeType
+ case _ => AnyTpe // so that macro impls with rhs = ??? don't screw up our inference
+ }
+
+ // Step II. Transform type parameters of a macro implementation into type arguments in a macro definition's body
+ runtimeType = runtimeType.substituteTypes(macroImpl.typeParams, loadMacroImplBinding(macroDdef.symbol).targs.map(_.tpe))
+
+ // Step III. Transform c.prefix.value.XXX to this.XXX and implParam.value.YYY to defParam.YYY
+ def unsigma(tpe: Type): Type =
+ transformTypeTagEvidenceParams(macroImpl.paramss, (param, tparam) => NoSymbol) match {
+ case (implCtxParam :: Nil) :: implParamss =>
+ val implToDef = flatMap2(implParamss, macroDdef.vparamss)(map2(_, _)((_, _))).toMap
+ object UnsigmaTypeMap extends TypeMap {
+ def apply(tp: Type): Type = tp match {
+ case TypeRef(pre, sym, args) =>
+ val pre1 = pre match {
+ case SingleType(SingleType(SingleType(NoPrefix, c), prefix), value) if c == implCtxParam && prefix == MacroContextPrefix && value == ExprValue =>
+ ThisType(macroDdef.symbol.owner)
+ case SingleType(SingleType(NoPrefix, implParam), value) if value == ExprValue =>
+ implToDef get implParam map (defParam => SingleType(NoPrefix, defParam.symbol)) getOrElse pre
+ case _ =>
+ pre
+ }
+ val args1 = args map mapOver
+ TypeRef(pre1, sym, args1)
+ case _ =>
+ mapOver(tp)
+ }
+ }
+
+ UnsigmaTypeMap(tpe)
+ case _ =>
+ tpe
+ }
+
+ unsigma(runtimeType)
+ }
+
+ /** A reference macro implementation signature compatible with a given macro definition.
+ *
+ * In the example above for the following macro def:
+ * def foo[T](xs: List[T]): T = macro fooBar
+ *
+ * This function will return:
* (c: scala.reflect.macros.Context)(xs: c.Expr[List[T]]): c.Expr[T]
*
+ * Note that type tag evidence parameters are not included into the result.
+ * Type tag context bounds for macro impl tparams are optional.
+ * Therefore compatibility checks ignore such parameters, and we don't need to bother about them here.
+ *
* @param macroDef The macro definition symbol
* @param tparams The type parameters of the macro definition
* @param vparamss The value parameters of the macro definition
* @param retTpe The return type of the macro definition
*/
- private def macroImplSigs(macroDef: Symbol, tparams: List[TypeDef], vparamss: List[List[ValDef]], retTpe: Type): (List[List[List[Symbol]]], Type) = {
+ private def macroImplSig(macroDef: Symbol, tparams: List[TypeDef], vparamss: List[List[ValDef]], retTpe: Type): (List[List[Symbol]], Type) = {
// had to move method's body to an object because of the recursive dependencies between sigma and param
object SigGenerator {
- val hasThis = macroDef.owner.isClass
- val ownerTpe = macroDef.owner match {
- case owner if owner.isModuleClass => new UniqueThisType(macroDef.owner)
- case owner if owner.isClass => macroDef.owner.tpe
- case _ => NoType
- }
- val hasTparams = !tparams.isEmpty
-
def sigma(tpe: Type): Type = {
class SigmaTypeMap extends TypeMap {
def apply(tp: Type): Type = tp match {
case TypeRef(pre, sym, args) =>
val pre1 = pre match {
case ThisType(sym) if sym == macroDef.owner =>
- SingleType(SingleType(SingleType(NoPrefix, paramsCtx(0)), MacroContextPrefix), ExprValue)
+ SingleType(SingleType(SingleType(NoPrefix, ctxParam), MacroContextPrefix), ExprValue)
case SingleType(NoPrefix, sym) =>
mfind(vparamss)(_.symbol == sym) match {
- case Some(macroDefParam) =>
- SingleType(SingleType(NoPrefix, param(macroDefParam)), ExprValue)
- case _ =>
- pre
+ case Some(macroDefParam) => SingleType(SingleType(NoPrefix, param(macroDefParam)), ExprValue)
+ case _ => pre
}
case _ =>
pre
}
- val args1 = args map mapOver
- TypeRef(pre1, sym, args1)
+ TypeRef(pre1, sym, args map mapOver)
case _ =>
mapOver(tp)
}
@@ -277,29 +340,14 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
val paramCache = collection.mutable.Map[Symbol, Symbol]()
def param(tree: Tree): Symbol =
paramCache.getOrElseUpdate(tree.symbol, {
- // [Eugene] deskolemization became necessary once I implemented inference of macro def return type
- // please, verify this solution, but for now I'll leave it here - cargo cult for the win
- val sym = tree.symbol.deSkolemize
+ val sym = tree.symbol
val sigParam = makeParam(sym.name, sym.pos, implType(sym.isType, sym.tpe))
if (sym.isSynthetic) sigParam.flags |= SYNTHETIC
sigParam
})
- val paramsCtx = List(ctxParam)
- val paramsThis = List(makeParam(nme.macroThis, macroDef.pos, implType(false, ownerTpe), SYNTHETIC))
- val paramsTparams = tparams map param
- val paramssParams = mmap(vparamss)(param)
-
- var paramsss = List[List[List[Symbol]]]()
- // tparams are no longer part of a signature, they get into macro implementations via context bounds
-// if (hasTparams && hasThis) paramsss :+= paramsCtx :: paramsThis :: paramsTparams :: paramssParams
-// if (hasTparams) paramsss :+= paramsCtx :: paramsTparams :: paramssParams
- // _this params are no longer part of a signature, its gets into macro implementations via Context.prefix
-// if (hasThis) paramsss :+= paramsCtx :: paramsThis :: paramssParams
- paramsss :+= paramsCtx :: paramssParams
-
- val tsym = getMember(MacroContextClass, tpnme.Expr)
- val implRetTpe = typeRef(singleType(NoPrefix, ctxParam), tsym, List(sigma(retTpe)))
+ val paramss = List(ctxParam) :: mmap(vparamss)(param)
+ val implRetTpe = typeRef(singleType(NoPrefix, ctxParam), getMember(MacroContextClass, tpnme.Expr), List(sigma(retTpe)))
}
import SigGenerator._
@@ -307,137 +355,26 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
macroTraceVerbose("tparams are: ")(tparams)
macroTraceVerbose("vparamss are: ")(vparamss)
macroTraceVerbose("retTpe is: ")(retTpe)
- macroTraceVerbose("macroImplSigs are: ")(paramsss, implRetTpe)
+ macroTraceVerbose("macroImplSig is: ")(paramss, implRetTpe)
}
- private def transformTypeTagEvidenceParams(paramss: List[List[Symbol]], transform: (Symbol, Symbol) => Symbol): List[List[Symbol]] = {
- import definitions.{ AbsTypeTagClass, MacroContextClass }
- if (paramss.isEmpty || paramss.last.isEmpty)
- return paramss
-
- val ContextParam = paramss.head match {
- case p :: Nil => p filter (_.tpe <:< definitions.MacroContextClass.tpe)
- case _ => NoSymbol
- }
- def isTag(sym: Symbol): Boolean = (sym == AbsTypeTagClass) || (sym.isAliasType && isTag(sym.info.typeSymbol))
- def transformTag(param: Symbol): Symbol = param.tpe match {
- case TypeRef(SingleType(NoPrefix, ContextParam), sym, tp :: Nil) if isTag(sym) => transform(param, tp.typeSymbol)
- case _ => param
- }
- val last = paramss.last map transformTag filterNot (_ eq NoSymbol)
- if (last.isEmpty) paramss.init else paramss.init :+ last
- }
-
- /** As specified above, body of a macro definition must reference its implementation.
- * This function verifies that the body indeed refers to a method, and that
- * the referenced macro implementation is compatible with the given macro definition.
+ /** Verifies that the body of a macro def typechecks to a reference to a static public non-overloaded method,
+ * and that that method is signature-wise compatible with the given macro definition.
*
- * This means that macro implementation (fooBar in example above) must:
- * 1) Refer to a statically accessible, non-overloaded method.
- * 2) Have the right parameter lists as outlined in the SIP / in the doc comment of this class.
- *
- * @return typechecked rhs of the given macro definition
+ * @return Typechecked rhs of the given macro definition if everything is okay.
+ * EmptyTree if an error occurs.
*/
- def typedMacroBody(typer: Typer, ddef: DefDef): Tree = {
- import typer.context
- macroLogVerbose("typechecking macro def %s at %s".format(ddef.symbol, ddef.pos))
-
- val macroDef = ddef.symbol
- val defpos = macroDef.pos
- val implpos = ddef.rhs.pos
- assert(macroDef.isTermMacro, ddef)
-
- if (fastTrack contains ddef.symbol) {
- macroLogVerbose("typecheck terminated unexpectedly: macro is hardwired")
- assert(!ddef.tpt.isEmpty, "hardwired macros must provide result type")
- return EmptyTree
- }
-
- if (!typer.checkFeature(ddef.pos, MacrosFeature, immediate = true)) {
- macroLogVerbose("typecheck terminated unexpectedly: language.experimental.macros feature is not enabled")
- ddef.symbol setFlag IS_ERROR
- return EmptyTree
- }
-
- implicit class AugmentedString(s: String) {
- def abbreviateCoreAliases: String = { // hack!
- var result = s
- result = result.replace("c.universe.AbsTypeTag", "c.AbsTypeTag")
- result = result.replace("c.universe.Expr", "c.Expr")
- result
- }
- }
-
- var _hasError = false
- def hasError = _hasError
- def setError(): Unit = {
- _hasError = true
- macroDef setFlag IS_ERROR
- }
- def reportError(pos: Position, msg: String) = {
- setError()
- context.error(pos, msg)
- macroDef setFlag IS_ERROR
- }
-
- def invalidBodyError() =
- reportError(defpos,
- "macro body has wrong shape:" +
- "\n required: macro <reference to implementation object>.<implementation method name>" +
- "\n or : macro <implementation method name>")
- def validatePreTyper(rhs: Tree): Unit = rhs match {
- // we do allow macro invocations inside macro bodies
- // personally I don't mind if pre-typer tree is a macro invocation
- // that later resolves to a valid reference to a macro implementation
- // however, I don't think that invalidBodyError() should hint at that
- // let this be an Easter Egg :)
- case Apply(_, _) => ;
- case TypeApply(_, _) => ;
- case Super(_, _) => ;
- case This(_) => ;
- case Ident(_) => ;
- case Select(_, _) => ;
- case _ => invalidBodyError()
- }
- def validatePostTyper(rhs1: Tree): Unit = {
- def loop(tree: Tree): Unit = {
- def errorNotStatic() =
- reportError(implpos, "macro implementation must be in statically accessible object")
-
- def ensureRoot(sym: Symbol) =
- if (!sym.isModule && !sym.isModuleClass) errorNotStatic()
-
- def ensureModule(sym: Symbol) =
- if (!sym.isModule) errorNotStatic()
-
- tree match {
- case TypeApply(fun, _) =>
- loop(fun)
- case Super(qual, _) =>
- ensureRoot(macroDef.owner)
- loop(qual)
- case This(_) =>
- ensureRoot(tree.symbol)
- case Select(qual, name) if name.isTypeName =>
- loop(qual)
- case Select(qual, name) if name.isTermName =>
- if (tree.symbol != rhs1.symbol) ensureModule(tree.symbol)
- loop(qual)
- case Ident(name) if name.isTypeName =>
- ;
- case Ident(name) if name.isTermName =>
- if (tree.symbol != rhs1.symbol) ensureModule(tree.symbol)
- case _ =>
- invalidBodyError()
- }
- }
-
- loop(rhs1)
- }
-
- val rhs = ddef.rhs
- validatePreTyper(rhs)
- if (hasError) macroTraceVerbose("macro def failed to satisfy trivial preconditions: ")(macroDef)
+ def typedMacroBody(typer: Typer, macroDdef: DefDef): Tree =
+ try new MacroTyper(typer, macroDdef).typed
+ catch { case MacroBodyTypecheckException => EmptyTree }
+
+ class MacroTyper(val typer: Typer, val macroDdef: DefDef) extends MacroErrors {
+ // Phase I: sanity checks
+ val macroDef = macroDdef.symbol
+ macroLogVerbose("typechecking macro def %s at %s".format(macroDef, macroDdef.pos))
+ assert(macroDef.isTermMacro, macroDdef)
+ if (fastTrack contains macroDef) MacroDefIsFastTrack()
+ if (!typer.checkFeature(macroDdef.pos, MacrosFeature, immediate = true)) MacroFeatureNotEnabled()
// we use typed1 instead of typed, because otherwise adapt is going to mess us up
// if adapt sees <qualifier>.<method>, it will want to perform eta-expansion and will fail
@@ -445,11 +382,13 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
// because it's adapt which is responsible for automatic expansion during typechecking
def typecheckRhs(rhs: Tree): Tree = {
try {
- val prevNumErrors = reporter.ERROR.count // [Eugene] funnily enough, the isErroneous check is not enough
- var rhs1 = if (hasError) EmptyTree else typer.typed1(rhs, EXPRmode, WildcardType)
- def typecheckedWithErrors = (rhs1 exists (_.isErroneous)) || reporter.ERROR.count != prevNumErrors
+ // interestingly enough, just checking isErroneous doesn't cut it
+ // e.g. a "type arguments [U] do not conform to method foo's type parameter bounds" error
+ // doesn't manifest itself as an error in the resulting tree
+ val prevNumErrors = reporter.ERROR.count
+ var rhs1 = typer.typed1(rhs, EXPRmode, WildcardType)
def rhsNeedsMacroExpansion = rhs1.symbol != null && rhs1.symbol.isTermMacro && !rhs1.symbol.isErroneous
- while (!typecheckedWithErrors && rhsNeedsMacroExpansion) {
+ while (rhsNeedsMacroExpansion) {
rhs1 = macroExpand1(typer, rhs1) match {
case Success(expanded) =>
try {
@@ -465,287 +404,83 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
result
}
}
+ val typecheckedWithErrors = (rhs1 exists (_.isErroneous)) || reporter.ERROR.count != prevNumErrors
+ if (typecheckedWithErrors) MacroDefUntypeableBodyError()
rhs1
} catch {
case ex: TypeError =>
typer.reportTypeError(context, rhs.pos, ex)
- typer.infer.setError(rhs)
- }
- }
-
- val prevNumErrors = reporter.ERROR.count // funnily enough, the isErroneous check is not enough
- var rhs1 = typecheckRhs(rhs)
- val macroImpl = rhs1.symbol
- def typecheckedWithErrors = (rhs1 exists (_.isErroneous)) || reporter.ERROR.count != prevNumErrors
- if (typecheckedWithErrors) {
- setError()
- macroTraceVerbose("body of a macro def failed to typecheck: ")(ddef)
- } else {
- if (!hasError) {
- if (macroImpl == null) {
- invalidBodyError()
- } else {
- if (!macroImpl.isMethod)
- invalidBodyError()
- if (!macroImpl.isPublic)
- reportError(implpos, "macro implementation must be public")
- if (macroImpl.isOverloaded)
- reportError(implpos, "macro implementation cannot be overloaded")
- if (!macroImpl.typeParams.isEmpty && (!rhs1.isInstanceOf[TypeApply]))
- reportError(implpos, "macro implementation reference needs type arguments")
- if (!hasError)
- validatePostTyper(rhs1)
- }
- if (hasError)
- macroTraceVerbose("macro def failed to satisfy trivial preconditions: ")(macroDef)
- }
- if (!hasError) {
- bindMacroImpl(macroDef, rhs1) // we must bind right over here, because return type inference needs this info
+ MacroDefUntypeableBodyError()
}
}
- if (!hasError) {
- def checkCompatibility(reqparamss: List[List[Symbol]], actparamss: List[List[Symbol]], reqres: Type, actres: Type): List[String] = {
- var hasError = false
- var errors = List[String]()
- def compatibilityError(msg: String) {
- hasError = true
- errors :+= msg
- }
-
- val flatreqparams = reqparamss.flatten
- val flatactparams = actparamss.flatten
- val tparams = macroImpl.typeParams
- val tvars = tparams map freshVar
- def lengthMsg(which: String, extra: Symbol) =
- "parameter lists have different length, "+which+" extra parameter "+extra.defString
- if (actparamss.length != reqparamss.length)
- compatibilityError("number of parameter sections differ")
-
- def checkSubType(slot: String, reqtpe: Type, acttpe: Type): Unit = {
- val ok = if (macroDebugVerbose) {
- if (reqtpe eq acttpe) println(reqtpe + " <: " + acttpe + "?" + EOL + "true")
- withTypesExplained(reqtpe <:< acttpe)
- } else reqtpe <:< acttpe
- if (!ok) {
- compatibilityError("type mismatch for %s: %s does not conform to %s".format(slot, reqtpe.toString.abbreviateCoreAliases, acttpe.toString.abbreviateCoreAliases))
- }
- }
-
- if (!hasError) {
- try {
- for ((rparams, aparams) <- reqparamss zip actparamss) {
- if (rparams.length < aparams.length)
- compatibilityError(lengthMsg("found", aparams(rparams.length)))
- if (aparams.length < rparams.length)
- compatibilityError(lengthMsg("required", rparams(aparams.length)).abbreviateCoreAliases)
- }
- // if the implementation signature is already deemed to be incompatible, we bail out
- // otherwise, high-order type magic employed below might crash in weird ways
- if (!hasError) {
- for ((rparams, aparams) <- reqparamss zip actparamss) {
- for ((rparam, aparam) <- rparams zip aparams) {
- def isRepeated(param: Symbol) = param.tpe.typeSymbol == RepeatedParamClass
- if (rparam.name != aparam.name && !rparam.isSynthetic) {
- val rparam1 = rparam
- val aparam1 = aparam
- compatibilityError("parameter names differ: "+rparam.name+" != "+aparam.name)
- }
- if (isRepeated(rparam) && !isRepeated(aparam))
- compatibilityError("types incompatible for parameter "+rparam.name+": corresponding is not a vararg parameter")
- if (!isRepeated(rparam) && isRepeated(aparam))
- compatibilityError("types incompatible for parameter "+aparam.name+": corresponding is not a vararg parameter")
- if (!hasError) {
- var atpe = aparam.tpe.substSym(flatactparams, flatreqparams).instantiateTypeParams(tparams, tvars)
- atpe = atpe.dealias // SI-5706
- // strip the { type PrefixType = ... } refinement off the Context or otherwise we get compatibility errors
- atpe = atpe match {
- case RefinedType(List(tpe), Scope(sym)) if tpe == MacroContextClass.tpe && sym.allOverriddenSymbols.contains(MacroContextPrefixType) => tpe
- case _ => atpe
- }
- checkSubType("parameter " + rparam.name, rparam.tpe, atpe)
- }
- }
- }
- }
- if (!hasError) {
- val atpe = actres.substSym(flatactparams, flatreqparams).instantiateTypeParams(tparams, tvars)
- checkSubType("return type", atpe, reqres)
- }
- if (!hasError) {
- val targs = solvedTypes(tvars, tparams, tparams map varianceInType(actres), false,
- lubDepth(flatactparams map (_.tpe)) max lubDepth(flatreqparams map (_.tpe)))
- val boundsOk = typer.silent(_.infer.checkBounds(ddef, NoPrefix, NoSymbol, tparams, targs, ""))
- boundsOk match {
- case SilentResultValue(true) => ;
- case SilentResultValue(false) | SilentTypeError(_) =>
- val bounds = tparams map (tp => tp.info.instantiateTypeParams(tparams, targs).bounds)
- compatibilityError("type arguments " + targs.mkString("[", ",", "]") +
- " do not conform to " + tparams.head.owner + "'s type parameter bounds " +
- (tparams map (_.defString)).mkString("[", ",", "]"))
- }
- }
- } catch {
- case ex: NoInstance =>
- compatibilityError(
- "type parameters "+(tparams map (_.defString) mkString ", ")+" cannot be instantiated\n"+
- ex.getMessage)
- }
- }
-
- errors.toList
- }
-
- var actparamss = macroImpl.paramss
- actparamss = transformTypeTagEvidenceParams(actparamss, (param, tparam) => NoSymbol)
-
- val rettpe = if (!ddef.tpt.isEmpty) typer.typedType(ddef.tpt).tpe else computeMacroDefTypeFromMacroImpl(ddef, macroDef, macroImpl)
- val (reqparamsss0, reqres0) = macroImplSigs(macroDef, ddef.tparams, ddef.vparamss, rettpe)
- var reqparamsss = reqparamsss0
-
- // prohibit implicit params on macro implementations
- // we don't have to do this, but it appears to be more clear than allowing them
- val implicitParams = actparamss.flatten filter (_.isImplicit)
- if (implicitParams.length > 0) {
- reportError(implicitParams.head.pos, "macro implementations cannot have implicit parameters other than AbsTypeTag evidences")
- macroTraceVerbose("macro def failed to satisfy trivial preconditions: ")(macroDef)
- }
-
- if (!hasError) {
- val reqres = reqres0
- val actres = macroImpl.tpe.finalResultType
- def showMeth(pss: List[List[Symbol]], restpe: Type, abbreviate: Boolean) = {
- var argsPart = (pss map (ps => ps map (_.defString) mkString ("(", ", ", ")"))).mkString
- if (abbreviate) argsPart = argsPart.abbreviateCoreAliases
- var retPart = restpe.toString
- if (abbreviate || ddef.tpt.tpe == null) retPart = retPart.abbreviateCoreAliases
- argsPart + ": " + retPart
- }
- def compatibilityError(addendum: String) =
- reportError(implpos,
- "macro implementation has wrong shape:"+
- "\n required: "+showMeth(reqparamsss.head, reqres, true) +
- (reqparamsss.tail map (paramss => "\n or : "+showMeth(paramss, reqres, true)) mkString "")+
- "\n found : "+showMeth(actparamss, actres, false)+
- "\n"+addendum)
-
- macroTraceVerbose("considering " + reqparamsss.length + " possibilities of compatible macro impl signatures for macro def: ")(ddef.name)
- val results = reqparamsss map (checkCompatibility(_, actparamss, reqres, actres))
- if (macroDebugVerbose) (reqparamsss zip results) foreach { case (reqparamss, result) =>
- println("%s %s".format(if (result.isEmpty) "[ OK ]" else "[FAILED]", reqparamss))
- result foreach (errorMsg => println(" " + errorMsg))
- }
-
- if (results forall (!_.isEmpty)) {
- var index = reqparamsss indexWhere (_.length == actparamss.length)
- if (index == -1) index = 0
- val mostRelevantMessage = results(index).head
- compatibilityError(mostRelevantMessage)
- } else {
- assert((results filter (_.isEmpty)).length == 1, results)
- if (macroDebugVerbose) (reqparamsss zip results) filter (_._2.isEmpty) foreach { case (reqparamss, result) =>
- println("typechecked macro impl as: " + reqparamss)
- }
- }
- }
+ // Phase II: typecheck the right-hand side of the macro def
+ val typed = typecheckRhs(macroDdef.rhs)
+ typed match {
+ case MacroImplReference(owner, meth, targs) =>
+ if (!meth.isMethod) MacroDefInvalidBodyError()
+ if (!meth.isPublic) MacroImplNotPublicError()
+ if (meth.isOverloaded) MacroImplOverloadedError()
+ if (!owner.isStaticOwner && !owner.moduleClass.isStaticOwner) MacroImplNotStaticError()
+ if (meth.typeParams.length != targs.length) MacroImplWrongNumberOfTypeArgumentsError(typed)
+ bindMacroImpl(macroDef, typed)
+ case _ =>
+ MacroDefInvalidBodyError()
}
- rhs1
- }
-
- def computeMacroDefTypeFromMacroImpl(macroDdef: DefDef, macroDef: Symbol, macroImpl: Symbol): Type = {
- // get return type from method type
- def unwrapRet(tpe: Type): Type = {
- def loop(tpe: Type) = tpe match {
- case NullaryMethodType(ret) => ret
- case mtpe @ MethodType(_, ret) => unwrapRet(ret)
- case _ => tpe
- }
+ // Phase III: check compatibility between the macro def and its macro impl
+ // this check ignores type tag evidence parameters, because type tag context bounds are optional
+ // aXXX (e.g. aparamss) => characteristics of the macro impl ("a" stands for "actual")
+ // rXXX (e.g. rparamss) => characteristics of a reference macro impl signature synthesized from the macro def ("r" stands for "reference")
+ val macroImpl = typed.symbol
+ val aparamss = transformTypeTagEvidenceParams(macroImpl.paramss, (param, tparam) => NoSymbol)
+ val aret = macroImpl.tpe.finalResultType
+ val macroDefRet =
+ if (!macroDdef.tpt.isEmpty) typer.typedType(macroDdef.tpt).tpe
+ else computeMacroDefTypeFromMacroImpl(macroDdef, macroImpl)
+ val (rparamss, rret) = macroImplSig(macroDef, macroDdef.tparams, macroDdef.vparamss, macroDefRet)
+
+ val implicitParams = aparamss.flatten filter (_.isImplicit)
+ if (implicitParams.nonEmpty) MacroImplNonTagImplicitParameters(implicitParams)
+ if (aparamss.length != rparamss.length) MacroImplParamssMismatchError()
+
+ val atparams = macroImpl.typeParams
+ val atvars = atparams map freshVar
+ def atpeToRtpe(atpe: Type) = atpe.substSym(aparamss.flatten, rparamss.flatten).instantiateTypeParams(atparams, atvars)
- tpe match {
- case PolyType(_, tpe) => loop(tpe)
- case _ => loop(tpe)
- }
- }
- var metaType = unwrapRet(macroImpl.tpe)
+ try {
+ map2(aparamss, rparamss)((aparams, rparams) => {
+ if (aparams.length < rparams.length) MacroImplMissingParamsError(aparams, rparams)
+ if (rparams.length < aparams.length) MacroImplExtraParamsError(aparams, rparams)
+ })
- // downgrade from metalevel-0 to metalevel-1
- def inferRuntimeType(metaType: Type): Type = metaType match {
- case TypeRef(pre, sym, args) if sym.name == tpnme.Expr && args.length == 1 =>
- args.head
- case _ =>
- AnyClass.tpe
- }
- var runtimeType = inferRuntimeType(metaType)
-
- // transform type parameters of a macro implementation into type parameters of a macro definition
- runtimeType = runtimeType map {
- case TypeRef(pre, sym, args) =>
- // [Eugene] not sure which of these deSkolemizes are necessary
- // sym.paramPos is unreliable (see another case below)
- val tparams = macroImpl.typeParams map (_.deSkolemize)
- val paramPos = tparams indexOf sym.deSkolemize
- val sym1 =
- if (paramPos == -1) sym
- else loadMacroImplBinding(macroDef).targs(paramPos).tpe.typeSymbol
- TypeRef(pre, sym1, args)
- case tpe =>
- tpe
- }
+ // cannot fuse these loops because if aparamss.flatten != rparamss.flatten
+ // then `atpeToRtpe` is going to fail with an unsound substitution
+ map2(aparamss.flatten, rparamss.flatten)((aparam, rparam) => {
+ if (aparam.name != rparam.name && !rparam.isSynthetic) MacroImplParamNameMismatchError(aparam, rparam)
+ if (isRepeated(aparam) ^ isRepeated(rparam)) MacroImplVarargMismatchError(aparam, rparam)
+ checkMacroImplParamTypeMismatch(stripOffPrefixTypeRefinement(atpeToRtpe(aparam.tpe)), rparam)
+ })
- // as stated in the spec, before being matched to macroimpl, type and value parameters of macrodef
- // undergo a special transformation, sigma, that adapts them to the different metalevel macroimpl lives in
- // as a result, we need to reverse this transformation when inferring macrodef ret from macroimpl ret
- def unsigma(tpe: Type): Type = {
- // unfortunately, we cannot dereference ``paramss'', because we're in the middle of inferring a type for ``macroDef''
-// val defParamss = macroDef.paramss
- val defParamss = mmap(macroDdef.vparamss)(_.symbol)
- var implParamss = macroImpl.paramss
- implParamss = transformTypeTagEvidenceParams(implParamss, (param, tparam) => NoSymbol)
-
- val implCtxParam = if (implParamss.length > 0 && implParamss(0).length > 0) implParamss(0)(0) else null
- def implParamToDefParam(implParam: Symbol): Symbol = {
- val indices = (((implParamss drop 1).zipWithIndex) map { case (implParams, index) => (index, implParams indexOf implParam) } filter (_._2 != -1)).headOption
- val defParam = indices flatMap {
- case (plistIndex, pIndex) =>
- if (defParamss.length <= plistIndex) None
- else if (defParamss(plistIndex).length <= pIndex) None
- else Some(defParamss(plistIndex)(pIndex))
- }
- defParam.orNull
- }
+ checkMacroImplResultTypeMismatch(atpeToRtpe(aret), rret)
- class UnsigmaTypeMap extends TypeMap {
- def apply(tp: Type): Type = tp match {
- case TypeRef(pre, sym, args) =>
- val pre1 = pre match {
- case SingleType(SingleType(SingleType(NoPrefix, param), prefix), value) if param == implCtxParam && prefix == MacroContextPrefix && value == ExprValue =>
- ThisType(macroDef.owner)
- case SingleType(SingleType(NoPrefix, param), value) if implParamToDefParam(param) != null && value == ExprValue =>
- val macroDefParam = implParamToDefParam(param)
- SingleType(NoPrefix, macroDefParam)
- case _ =>
- pre
- }
- val args1 = args map mapOver
- TypeRef(pre1, sym, args1)
- case _ =>
- mapOver(tp)
- }
+ val maxLubDepth = lubDepth(aparamss.flatten map (_.tpe)) max lubDepth(rparamss.flatten map (_.tpe))
+ val atargs = solvedTypes(atvars, atparams, atparams map varianceInType(aret), upper = false, depth = maxLubDepth)
+ val boundsOk = typer.silent(_.infer.checkBounds(macroDdef, NoPrefix, NoSymbol, atparams, atargs, ""))
+ boundsOk match {
+ case SilentResultValue(true) => // do nothing, success
+ case SilentResultValue(false) | SilentTypeError(_) => MacroImplTargMismatchError(atargs, atparams)
}
-
- new UnsigmaTypeMap() apply tpe
+ } catch {
+ case ex: NoInstance => MacroImplTparamInstantiationError(atparams, ex)
}
- runtimeType = unsigma(runtimeType)
-
- runtimeType
}
/** Macro classloader that is used to resolve and run macro implementations.
* Loads classes from from -cp (aka the library classpath).
* Is also capable of detecting REPL and reusing its classloader.
*/
- private lazy val macroClassloader: ClassLoader = {
+ lazy val macroClassloader: ClassLoader = {
if (global.forMSIL)
throw new UnsupportedOperationException("Scala reflection not available on this platform")
@@ -753,7 +488,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
macroLogVerbose("macro classloader: initializing from -cp: %s".format(classpath))
val loader = ScalaClassLoader.fromURLs(classpath, self.getClass.getClassLoader)
- // [Eugene] a heuristic to detect the REPL
+ // a heuristic to detect the REPL
if (global.settings.exposeEmptyPackage.value) {
macroLogVerbose("macro classloader: initializing from a REPL classloader".format(global.classPath.asURLs))
import scala.tools.nsc.interpreter._
@@ -771,7 +506,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
* 4) Resolves macro implementation within the loaded companion.
*
* @return Requested runtime if macro implementation can be loaded successfully from either of the mirrors,
- * null otherwise.
+ * `null` otherwise.
*/
type MacroRuntime = List[Any] => Any
private val macroRuntimesCache = perRunCaches.newWeakMap[Symbol, MacroRuntime]
@@ -787,9 +522,11 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
val methName = binding.methName
macroLogVerbose(s"resolved implementation as $className.$methName")
- // [Eugene++] I don't use Scala reflection here, because it seems to interfere with JIT magic
+ // I don't use Scala reflection here, because it seems to interfere with JIT magic
// whenever you instantiate a mirror (and not do anything with in, just instantiate), performance drops by 15-20%
// I'm not sure what's the reason - for me it's pure voodoo
+ // upd. my latest experiments show that everything's okay
+ // it seems that in 2.10.1 we can easily switch to Scala reflection
try {
macroTraceVerbose("loading implementation class: ")(className)
macroTraceVerbose("classloader is: ")(ReflectionUtils.show(macroClassloader))
@@ -824,9 +561,9 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
/** Calculate the arguments to pass to a macro implementation when expanding the provided tree.
*
* This includes inferring the exact type and instance of the macro context to pass, and also
- * allowing for missing parameter sections in macro implementation (see ``macroImplParamsss'' for more info).
+ * allowing for missing parameter sections in macro implementation (see `macroImplParamsss` for more info).
*
- * @return list of runtime objects to pass to the implementation obtained by ``macroRuntime''
+ * @return list of runtime objects to pass to the implementation obtained by `macroRuntime`
*/
private def macroArgs(typer: Typer, expandee: Tree): Option[List[Any]] = {
val macroDef = expandee.symbol
@@ -847,7 +584,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
collectMacroArgs(expandee)
val argcDoesntMatch = macroDef.paramss.length != exprArgs.length
- val nullaryArgsEmptyParams = exprArgs.isEmpty && macroDef.paramss == List(List())
+ val nullaryArgsEmptyParams = exprArgs.isEmpty && macroDef.paramss == ListOfNil
if (argcDoesntMatch && !nullaryArgsEmptyParams) { typer.TyperErrorGen.MacroPartialApplicationError(expandee); return None }
var argss: List[List[Any]] = List(context) :: exprArgs.toList
@@ -882,14 +619,14 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
// val outer2 = new outer1.C[String]
// outer2.foo[Boolean]
//
- // then T and U need to be inferred from the lexical scope of the call using ``asSeenFrom''
- // whereas V won't be resolved by asSeenFrom and need to be loaded directly from ``expandee'' which needs to contain a TypeApply node
+ // then T and U need to be inferred from the lexical scope of the call using `asSeenFrom`
+ // whereas V won't be resolved by asSeenFrom and need to be loaded directly from `expandee` which needs to contain a TypeApply node
// also, macro implementation reference may contain a regular type as a type argument, then we pass it verbatim
val tags = binding.signature filter (_ != -1) map (paramPos => {
val targ = binding.targs(paramPos).tpe.typeSymbol
val tpe = if (targ.isTypeParameterOrSkolem) {
if (targ.owner == macroDef) {
- // [Eugene] doesn't work when macro def is compiled separately from its usages
+ // doesn't work when macro def is compiled separately from its usages
// then targ is not a skolem and isn't equal to any of macroDef.typeParams
// val argPos = targ.deSkolemize.paramPos
val argPos = macroDef.typeParams.indexWhere(_.name == targ.name)
@@ -927,14 +664,14 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
}
/** Keeps track of macros in-flight.
- * See more informations in comments to ``openMacros'' in ``scala.reflect.macros.Context''.
+ * See more informations in comments to `openMacros` in `scala.reflect.macros.Context`.
*/
var openMacros = List[MacroContext]()
def enclosingMacroPosition = openMacros map (_.macroApplication.pos) find (_ ne NoPosition) getOrElse NoPosition
/** Performs macro expansion:
- * 1) Checks whether the expansion needs to be delayed (see ``mustDelayMacroExpansion'')
- * 2) Loads macro implementation using ``macroMirror''
+ * 1) Checks whether the expansion needs to be delayed (see `mustDelayMacroExpansion`)
+ * 2) Loads macro implementation using `macroMirror`
* 3) Synthesizes invocation arguments for the macro implementation
* 4) Checks that the result is a tree bound to this universe
* 5) Typechecks the result against the return type of the macro definition
@@ -970,7 +707,6 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
// so I added this dummy local for the ease of debugging
var expectedTpe = expandee.tpe
- // [Eugene] weird situation. what's the conventional way to deal with it?
val isNullaryInvocation = expandee match {
case TypeApply(Select(_, _), _) => true
case TypeApply(Ident(_), _) => true
@@ -1029,7 +765,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
Failure(expandee)
}
- /** Does the same as ``macroExpand'', but without typechecking the expansion
+ /** Does the same as `macroExpand`, but without typechecking the expansion
* Meant for internal use within the macro infrastructure, don't use it elsewhere.
*/
private def macroExpand1(typer: Typer, expandee: Tree): MacroExpansionResult =
@@ -1117,8 +853,9 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
macroLogLite("typechecking macro expansion %s at %s".format(expandee, expandee.pos))
macroArgs(typer, expandee).fold(failExpansion(): MacroExpansionResult) {
args => (args: @unchecked) match {
- // [Eugene++] crashes virtpatmat:
+ // crashes virtpatmat:
// case args @ ((context: MacroContext) :: _) =>
+ // todo. extract a minimized test case
case args @ (context0 :: _) =>
val context = context0.asInstanceOf[MacroContext]
if (nowDelayed) {
@@ -1197,7 +934,6 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
}
private def handleMacroExpansionException(typer: Typer, expandee: Tree, ex: Throwable): MacroExpansionResult = {
- // [Eugene] any ideas about how to improve this one?
val realex = ReflectionUtils.unwrapThrowable(ex)
realex match {
case realex: reflect.macros.runtime.AbortMacroException =>
@@ -1211,7 +947,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
try {
// [Eugene] is there a better way?
// [Paul] See Exceptional.scala and Origins.scala.
- val relevancyThreshold = realex.getStackTrace().indexWhere(este => este.getMethodName == "macroExpand1")
+ val relevancyThreshold = realex.getStackTrace().indexWhere(_.getMethodName endsWith "macroExpand1")
if (relevancyThreshold == -1) None
else {
var relevantElements = realex.getStackTrace().take(relevancyThreshold + 1)
@@ -1287,7 +1023,7 @@ trait Macros extends scala.tools.reflect.FastTrack with Traces {
/** Performs macro expansion on all subtrees of a given tree.
* Innermost macros are expanded first, outermost macros are expanded last.
- * See the documentation for ``macroExpand'' for more information.
+ * See the documentation for `macroExpand` for more information.
*/
def macroExpandAll(typer: Typer, expandee: Tree): Tree =
new Transformer {
diff --git a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
index dd180e6b76..4f597f97c9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/MethodSynthesis.scala
@@ -31,7 +31,6 @@ trait MethodSynthesis {
else DefDef(sym, body)
def applyTypeInternal(tags: List[TT[_]]): Type = {
- // [Eugene++ to Paul] needs review!!
val symbols = tags map compilerSymbolFromTag
val container :: args = symbols
val tparams = container.typeConstructor.typeParams
@@ -53,21 +52,14 @@ trait MethodSynthesis {
applyTypeInternal(List(t1))
def applyType[CC[X1], X1](implicit t1: TT[CC[_]], t2: TT[X1]): Type =
- applyTypeInternal(List[TT[_]](t1, t2))
+ applyTypeInternal(List(t1, t2))
def applyType[CC[X1, X2], X1, X2](implicit t1: TT[CC[_,_]], t2: TT[X1], t3: TT[X2]): Type =
- // [Eugene++] without an explicit type annotation for List, we get this:
- // [scalacfork] C:\Projects\KeplerUnderRefactoring\src\compiler\scala\tools\nsc\typechecker\MethodSynthesis.scala:59: error: no type parameters for method apply: (xs: A*)List[A] in object List exist so that it can be applied to arguments (scala.tools.nsc.typechecker.MethodSynthesis.synthesisUtil.TT[CC[_, _]], scala.tools.nsc.typechecker.MethodSynthesis.synthesisUtil.TT[X1], scala.tools.nsc.typechecker.MethodSynthesis.synthesisUtil.TT[X2])
- // [scalacfork] --- because ---
- // [scalacfork] undetermined type
- // [scalacfork] applyTypeInternal(List(t1, t2, t3))
- applyTypeInternal(List[TT[_]](t1, t2, t3))
+ applyTypeInternal(List(t1, t2, t3))
def applyType[CC[X1, X2, X3], X1, X2, X3](implicit t1: TT[CC[_,_,_]], t2: TT[X1], t3: TT[X2], t4: TT[X3]): Type =
- applyTypeInternal(List[TT[_]](t1, t2, t3, t4))
+ applyTypeInternal(List(t1, t2, t3, t4))
- // [Martin->Eugene] !!! reinstantiate when typeables are in.
- // [Eugene++->Martin] now this compiles, will soon check it out
def newMethodType[F](owner: Symbol)(implicit t: TT[F]): Type = {
val fnSymbol = compilerSymbolFromTag(t)
val formals = compilerTypeFromTag(t).typeArguments
@@ -250,7 +242,7 @@ trait MethodSynthesis {
abort("No synthetics for " + meth + ": synthetics contains " + context.unit.synthetics.keys.mkString(", "))
}
case _ =>
- List(stat)
+ stat :: Nil
}
def standardAccessors(vd: ValDef): List[DerivedFromValDef] = (
@@ -499,7 +491,7 @@ trait MethodSynthesis {
// Derives a tree without attempting to use the original tree's symbol.
override def derivedTree = {
atPos(tree.pos.focus) {
- DefDef(derivedMods, name, Nil, List(Nil), tree.tpt.duplicate,
+ DefDef(derivedMods, name, Nil, ListOfNil, tree.tpt.duplicate,
if (isDeferred) EmptyTree else Select(This(owner), tree.name)
)
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index fc9cb02d37..fd27c3c070 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -973,7 +973,7 @@ trait Namers extends MethodSynthesis {
// Add a () parameter section if this overrides some method with () parameters.
if (clazz.isClass && vparamss.isEmpty && overriddenSymbol.alternatives.exists(
_.info.isInstanceOf[MethodType])) {
- vparamSymss = List(List())
+ vparamSymss = ListOfNil
}
mforeach(vparamss) { vparam =>
if (vparam.tpt.isEmpty) {
@@ -1032,7 +1032,7 @@ trait Namers extends MethodSynthesis {
var baseParamss = (vparamss, overridden.tpe.paramss) match {
// match empty and missing parameter list
case (Nil, List(Nil)) => Nil
- case (List(Nil), Nil) => List(Nil)
+ case (List(Nil), Nil) => ListOfNil
case (_, paramss) => paramss
}
assert(
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 3507bc4e09..d2ec2f793f 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -1298,13 +1298,12 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
def transformStat(tree: Tree, index: Int): List[Tree] = tree match {
case t if treeInfo.isSelfConstrCall(t) =>
assert(index == 0, index)
- val t = transform(tree)
- if (currentLevel.maxindex > 0) {
+ try transform(tree) :: Nil
+ finally if (currentLevel.maxindex > 0) {
// An implementation restriction to avoid VerifyErrors and lazyvals mishaps; see SI-4717
debuglog("refsym = " + currentLevel.refsym)
unit.error(currentLevel.refpos, "forward reference not allowed from self constructor invocation")
}
- List(t)
case ModuleDef(_, _, _) => eliminateModuleDefs(tree)
case ValDef(_, _, _, _) =>
val tree1 @ ValDef(_, _, _, rhs) = transform(tree) // important to do before forward reference check
@@ -1316,11 +1315,11 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R
debuglog("refsym = " + currentLevel.refsym)
unit.error(currentLevel.refpos, "forward reference extends over definition of " + lazySym)
}
- List(tree1)
+ tree1 :: Nil
}
case Import(_, _) => Nil
case DefDef(mods, _, _, _, _, _) if (mods hasFlag MACRO) || (tree.symbol hasFlag MACRO) => Nil
- case _ => List(transform(tree))
+ case _ => transform(tree) :: Nil
}
/* Check whether argument types conform to bounds of type parameters */
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 2a71295690..032465351e 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -290,7 +290,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
log("Ensuring accessor for call to protected " + sym.fullLocationString + " from " + currentClass)
ensureAccessor(sel)
} else
- mayNeedProtectedAccessor(sel, List(EmptyTree), false)
+ mayNeedProtectedAccessor(sel, EmptyTree.asList, false)
}
case Super(_, mix) =>
@@ -303,7 +303,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
transformSuperSelect(sel)
case _ =>
- mayNeedProtectedAccessor(sel, List(EmptyTree), true)
+ mayNeedProtectedAccessor(sel, EmptyTree.asList, true)
}
case DefDef(mods, name, tparams, vparamss, tpt, rhs) if tree.symbol.isMethodWithExtension =>
diff --git a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
index 26ab3fcfba..0c9ed29182 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SyntheticMethods.scala
@@ -63,7 +63,7 @@ trait SyntheticMethods extends ast.TreeDSL {
// in the original order.
def accessors = clazz.caseFieldAccessors sortBy { acc =>
originalAccessors indexWhere { orig =>
- (acc.name == orig.name) || (acc.name startsWith (orig.name append "$").asInstanceOf[Name]) // [Eugene++] why do we need this cast?
+ (acc.name == orig.name) || (acc.name startsWith (orig.name append "$").asInstanceOf[Name]) // [Eugene] why do we need this cast?
}
}
val arity = accessors.size
@@ -87,7 +87,7 @@ trait SyntheticMethods extends ast.TreeDSL {
)
def forwardToRuntime(method: Symbol): Tree =
- forwardMethod(method, getMember(ScalaRunTimeModule, (method.name prepend "_").asInstanceOf[Name]))(mkThis :: _) // [Eugene++] why do we need this cast?
+ forwardMethod(method, getMember(ScalaRunTimeModule, (method.name prepend "_").asInstanceOf[Name]))(mkThis :: _) // [Eugene] why do we need this cast?
def callStaticsMethod(name: String)(args: Tree*): Tree = {
val method = termMember(RuntimeStaticsModule, name)
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index 4a0977eb90..f0dca64a00 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -462,7 +462,6 @@ trait TypeDiagnostics {
case CyclicReference(sym, info: TypeCompleter) =>
if (context0.owner.isTermMacro) {
// see comments to TypeSigError for an explanation of this special case
- // [Eugene] is there a better way?
throw ex
} else {
val pos = info.tree match {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 6ef45dd56e..b83019775d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -51,7 +51,6 @@ trait Typers extends Modes with Adaptations with Tags {
transformed.clear()
}
- // [Eugene] shouldn't this be converted to resetAllAttrs?
object UnTyper extends Traverser {
override def traverse(tree: Tree) = {
if (tree != EmptyTree) tree.tpe = null
@@ -195,16 +194,14 @@ trait Typers extends Modes with Adaptations with Tags {
case PolyType(_, _) => EmptyTree
case _ =>
def wrapImplicit(from: Type): Tree = {
- val result = inferImplicit(tree, functionType(List(from), to), reportAmbiguous, true, context, saveErrors)
+ val result = inferImplicit(tree, functionType(from :: Nil, to), reportAmbiguous, true, context, saveErrors)
if (result.subst != EmptyTreeTypeSubstituter) {
result.subst traverse tree
notifyUndetparamsInferred(result.subst.from, result.subst.to)
}
result.tree
}
- val result = wrapImplicit(from)
- if (result != EmptyTree) result
- else wrapImplicit(byNameType(from))
+ wrapImplicit(from) orElse wrapImplicit(byNameType(from))
}
}
@@ -909,7 +906,7 @@ trait Typers extends Modes with Adaptations with Tags {
def adaptType(): Tree = {
if (inFunMode(mode)) {
- // [Eugene++] the commented line below makes sense for typechecking, say, TypeApply(Ident(`some abstract type symbol`), List(...))
+ // todo. the commented line below makes sense for typechecking, say, TypeApply(Ident(`some abstract type symbol`), List(...))
// because otherwise Ident will have its tpe set to a TypeRef, not to a PolyType, and `typedTypeApply` will fail
// but this needs additional investigation, because it crashes t5228, gadts1 and maybe something else
// tree setType tree.tpe.normalize
@@ -2502,7 +2499,7 @@ trait Typers extends Modes with Adaptations with Tags {
def translated =
if (members.head eq EmptyTree) setError(tree)
- else typed(atPos(tree.pos)(Block(List(ClassDef(anonClass, NoMods, List(List()), List(List()), members, tree.pos.focus)), atPos(tree.pos.focus)(New(anonClass.tpe)))), mode, pt)
+ else typed(atPos(tree.pos)(Block(List(ClassDef(anonClass, NoMods, ListOfNil, ListOfNil, members, tree.pos.focus)), atPos(tree.pos.focus)(New(anonClass.tpe)))), mode, pt)
}
// Function(params, Match(sel, cases)) ==> new <Partial>Function { def apply<OrElse>(params) = `translateMatch('sel match { cases }')` }
@@ -2606,7 +2603,7 @@ trait Typers extends Modes with Adaptations with Tags {
val stats1 = typedStats(stats, NoSymbol)
// this code kicks in only after typer, so `stats` will never be filled in time
// as a result, most of compound type trees with non-empty stats will fail to reify
- // [Eugene++] todo. investigate whether something can be done about this
+ // todo. investigate whether something can be done about this
val att = templ.attachments.get[CompoundTypeTreeOriginalAttachment].getOrElse(CompoundTypeTreeOriginalAttachment(Nil, Nil))
templ.removeAttachment[CompoundTypeTreeOriginalAttachment]
templ addAttachment att.copy(stats = stats1)
@@ -3412,7 +3409,7 @@ trait Typers extends Modes with Adaptations with Tags {
}
if (hasError) annotationError
- else AnnotationInfo(annType, List(), nvPairs map {p => (p._1.asInstanceOf[Name], p._2.get)}).setOriginal(Apply(typedFun, args).setPos(ann.pos)) // [Eugene+] why do we need this cast?
+ else AnnotationInfo(annType, List(), nvPairs map {p => (p._1.asInstanceOf[Name], p._2.get)}).setOriginal(Apply(typedFun, args).setPos(ann.pos)) // [Eugene] why do we need this cast?
}
} else if (requireJava) {
reportAnnotationError(NestedAnnotationError(ann, annType))
@@ -4029,9 +4026,9 @@ trait Typers extends Modes with Adaptations with Tags {
} else {
var thenp1 = typed(thenp, pt)
var elsep1 = typed(elsep, pt)
+ def thenTp = packedType(thenp1, context.owner)
+ def elseTp = packedType(elsep1, context.owner)
- lazy val thenTp = packedType(thenp1, context.owner)
- lazy val elseTp = packedType(elsep1, context.owner)
// println("typedIf: "+(thenp1.tpe, elsep1.tpe, ptOrLub(List(thenp1.tpe, elsep1.tpe)),"\n", thenTp, elseTp, thenTp =:= elseTp))
val (owntype, needAdapt) =
// in principle we should pack the types of each branch before lubbing, but lub doesn't really work for existentials anyway
@@ -4043,7 +4040,7 @@ trait Typers extends Modes with Adaptations with Tags {
&& thenTp =:= elseTp
) (thenp1.tpe, false) // use unpacked type
// TODO: skolemize (lub of packed types) when that no longer crashes on files/pos/t4070b.scala
- else ptOrLub(List(thenp1.tpe, elsep1.tpe), pt)
+ else ptOrLub(thenp1.tpe :: elsep1.tpe :: Nil, pt)
if (needAdapt) { //isNumericValueType(owntype)) {
thenp1 = adapt(thenp1, mode, owntype)
@@ -5101,7 +5098,7 @@ trait Typers extends Modes with Adaptations with Tags {
erasure.GenericArray.unapply(tpt.tpe).isDefined) => // !!! todo simplify by using extractor
// convert new Array[T](len) to evidence[ClassTag[T]].newArray(len)
// convert new Array^N[T](len) for N > 1 to evidence[ClassTag[Array[...Array[T]...]]].newArray(len), where Array HK gets applied (N-1) times
- // [Eugene] no more MaxArrayDims. ClassTags are flexible enough to allow creation of arrays of arbitrary dimensionality (w.r.t JVM restrictions)
+ // no more MaxArrayDims. ClassTags are flexible enough to allow creation of arrays of arbitrary dimensionality (w.r.t JVM restrictions)
val Some((level, componentType)) = erasure.GenericArray.unapply(tpt.tpe)
val tagType = List.iterate(componentType, level)(tpe => appliedType(ArrayClass.toTypeConstructor, List(tpe))).last
val newArrayApp = atPos(tree.pos) {
@@ -5177,9 +5174,7 @@ trait Typers extends Modes with Adaptations with Tags {
case ReferenceToBoxed(idt @ Ident(_)) =>
val id1 = typed1(idt, mode, pt) match { case id: Ident => id }
- // [Eugene] am I doing it right?
- val erasedTypes = phaseId(currentPeriod) >= currentRun.erasurePhase.id
- val tpe = capturedVariableType(idt.symbol, erasedTypes = erasedTypes)
+ val tpe = capturedVariableType(idt.symbol, erasedTypes = phase.erasedTypes)
treeCopy.ReferenceToBoxed(tree, id1) setType tpe
case Literal(value) =>
@@ -5453,7 +5448,7 @@ trait Typers extends Modes with Adaptations with Tags {
val isMacroBodyOkay = !tree.symbol.isErroneous && !(tree1 exists (_.isErroneous))
val shouldInheritMacroImplReturnType = ddef.tpt.isEmpty
- if (isMacroBodyOkay && shouldInheritMacroImplReturnType) computeMacroDefTypeFromMacroImpl(ddef, tree.symbol, tree1.symbol) else AnyClass.tpe
+ if (isMacroBodyOkay && shouldInheritMacroImplReturnType) computeMacroDefTypeFromMacroImpl(ddef, tree1.symbol) else AnyClass.tpe
}
def transformedOr(tree: Tree, op: => Tree): Tree = transformed.get(tree) match {
diff --git a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
index 4871ef199c..5db1863f67 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Unapplies.scala
@@ -115,7 +115,7 @@ trait Unapplies extends ast.TreeDSL
Modifiers(OVERRIDE | FINAL),
nme.toString_,
Nil,
- List(Nil),
+ ListOfNil,
TypeTree(),
Literal(Constant(cdef.name.decode)))
@@ -126,7 +126,7 @@ trait Unapplies extends ast.TreeDSL
ModuleDef(
Modifiers(cdef.mods.flags & AccessFlags | SYNTHETIC, cdef.mods.privateWithin),
cdef.name.toTermName,
- Template(parents, emptyValDef, NoMods, Nil, List(Nil), body, cdef.impl.pos.focus))
+ Template(parents, emptyValDef, NoMods, Nil, ListOfNil, body, cdef.impl.pos.focus))
}
private val caseMods = Modifiers(SYNTHETIC | CASE)
diff --git a/src/compiler/scala/tools/reflect/MacroImplementations.scala b/src/compiler/scala/tools/reflect/MacroImplementations.scala
index 40ceefcc70..48a4811744 100644
--- a/src/compiler/scala/tools/reflect/MacroImplementations.scala
+++ b/src/compiler/scala/tools/reflect/MacroImplementations.scala
@@ -6,11 +6,12 @@ import scala.collection.mutable.ListBuffer
import scala.collection.mutable.Stack
abstract class MacroImplementations {
- val c: Context
+ val c: Context
- import c.universe.{Position => SPosition, _}
+ import c.universe._
+ import definitions._
- def macro_StringInterpolation_f(parts: List[Tree], args: List[Tree], origApplyPos: SPosition): Tree = {
+ def macro_StringInterpolation_f(parts: List[Tree], args: List[Tree], origApplyPos: c.universe.Position): Tree = {
// the parts all have the same position information (as the expression is generated by the compiler)
// the args have correct position information
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index eeec973299..8cc5a4e531 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -16,9 +16,6 @@ import scala.reflect.NameTransformer
import scala.reflect.api.JavaUniverse
import scala.reflect.base.MirrorOf
-// [Eugene++ to Martin] by the way, toolboxes are unable to compile anything that involves packages
-// is this intentional?
-
abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
val mirror: u.Mirror
@@ -187,10 +184,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
val meth = obj.moduleClass.newMethod(newTermName(wrapperMethodName))
def makeParam(schema: (FreeTermSymbol, TermName)) = {
val (fv, name) = schema
- // [Eugene] conventional way of doing this?
- val underlying = fv.tpe.resultType
- val tpe = appliedType(definitions.FunctionClass(0).tpe, List(underlying))
- meth.newValueParameter(name) setInfo tpe
+ meth.newValueParameter(name) setInfo appliedType(definitions.FunctionClass(0).tpe, List(fv.tpe.resultType))
}
meth setInfo MethodType(freeTerms.map(makeParam).toList, AnyClass.tpe)
minfo.decls enter meth
diff --git a/src/library/scala/Option.scala b/src/library/scala/Option.scala
index 2afe2acc13..5e347b051f 100644
--- a/src/library/scala/Option.scala
+++ b/src/library/scala/Option.scala
@@ -275,7 +275,7 @@ sealed abstract class Option[+A] extends Product with Serializable {
* if it is nonempty, or the empty list if the $option is empty.
*/
def toList: List[A] =
- if (isEmpty) List() else List(this.get)
+ if (isEmpty) List() else new ::(this.get, Nil)
/** Returns a [[scala.util.Left]] containing the given
* argument `left` if this $option is empty, or
diff --git a/src/library/scala/collection/GenTraversableLike.scala b/src/library/scala/collection/GenTraversableLike.scala
index 903de4a247..9b04256c8d 100644
--- a/src/library/scala/collection/GenTraversableLike.scala
+++ b/src/library/scala/collection/GenTraversableLike.scala
@@ -65,14 +65,14 @@ trait GenTraversableLike[+A, +Repr] extends Any with GenTraversableOnce[A] with
* @throws `NoSuchElementException` if the $coll is empty.
*/
def head: A
-
+
/** Optionally selects the first element.
* $orderDependent
* @return the first element of this $coll if it is nonempty,
* `None` if it is empty.
*/
def headOption: Option[A]
-
+
/** Tests whether this $coll can be repeatedly traversed.
* @return `true`
*/
@@ -92,14 +92,14 @@ trait GenTraversableLike[+A, +Repr] extends Any with GenTraversableOnce[A] with
* @throws NoSuchElementException If the $coll is empty.
*/
def last: A
-
+
/** Optionally selects the last element.
* $orderDependent
* @return the last element of this $coll$ if it is nonempty,
* `None` if it is empty.
*/
def lastOption: Option[A]
-
+
/** Selects all elements except the last.
* $orderDependent
* @return a $coll consisting of all elements of this $coll
@@ -107,7 +107,7 @@ trait GenTraversableLike[+A, +Repr] extends Any with GenTraversableOnce[A] with
* @throws `UnsupportedOperationException` if the $coll is empty.
*/
def init: Repr
-
+
/** Computes a prefix scan of the elements of the collection.
*
* Note: The neutral element `z` may be applied more than once.
@@ -210,7 +210,7 @@ trait GenTraversableLike[+A, +Repr] extends Any with GenTraversableOnce[A] with
def collect[B, That](pf: PartialFunction[A, B])(implicit bf: CanBuildFrom[Repr, B, That]): That
/** Builds a new collection by applying a function to all elements of this $coll
- * and using the elements of the resulting collections.
+ * and using the elements of the resulting collections.
*
* @param f the function to apply to each element.
* @tparam B the element type of the returned collection.
diff --git a/src/library/scala/collection/mutable/Queue.scala b/src/library/scala/collection/mutable/Queue.scala
index 2aa19d6cb0..21c3a84699 100644
--- a/src/library/scala/collection/mutable/Queue.scala
+++ b/src/library/scala/collection/mutable/Queue.scala
@@ -32,6 +32,7 @@ import generic._
*/
class Queue[A]
extends MutableList[A]
+ with LinearSeqOptimized[A, Queue[A]]
with GenericTraversableTemplate[A, Queue]
with Cloneable[Queue[A]]
with Serializable
@@ -165,6 +166,17 @@ extends MutableList[A]
* @return the first element.
*/
def front: A = head
+
+
+ // TODO - Don't override this just for new to create appropriate type....
+ override def tail: Queue[A] = {
+ require(nonEmpty, "tail of empty list")
+ val tl = new Queue[A]
+ tl.first0 = first0.tail
+ tl.last0 = last0
+ tl.len = len - 1
+ tl
+ }
}
diff --git a/src/library/scala/reflect/ScalaLongSignature.java b/src/library/scala/reflect/ScalaLongSignature.java
index fce58207f1..5b6d78f446 100644
--- a/src/library/scala/reflect/ScalaLongSignature.java
+++ b/src/library/scala/reflect/ScalaLongSignature.java
@@ -5,9 +5,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-/**
- * [Martin to Eugene++] Todo: Move to somewhere else?
-*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ScalaLongSignature {
diff --git a/src/library/scala/reflect/ScalaSignature.java b/src/library/scala/reflect/ScalaSignature.java
index f0df99fe79..a8af554d2b 100644
--- a/src/library/scala/reflect/ScalaSignature.java
+++ b/src/library/scala/reflect/ScalaSignature.java
@@ -5,8 +5,6 @@ import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
-/** * [Martin to Eugene++] Todo: Move to somewhere else?
- */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface ScalaSignature {
diff --git a/src/library/scala/reflect/base/Base.scala b/src/library/scala/reflect/base/Base.scala
index 714fd365ef..28ebdf4377 100644
--- a/src/library/scala/reflect/base/Base.scala
+++ b/src/library/scala/reflect/base/Base.scala
@@ -279,8 +279,6 @@ class Base extends Universe { self =>
val NoPosition = new Position
- def atPos[T <: Tree](pos: Position)(tree: T): T = tree
-
private val generated = new mutable.HashMap[String, WeakReference[Symbol]]
private def cached(name: String)(symExpr: => Symbol): Symbol =
@@ -411,6 +409,22 @@ class Base extends Universe { self =>
lazy val ListClass = staticClass("scala.List")
lazy val PredefModule = staticModule("scala.Predef")
+
+ lazy val ByteTpe = TypeRef(ScalaPrefix, ByteClass, Nil)
+ lazy val ShortTpe = TypeRef(ScalaPrefix, ShortClass, Nil)
+ lazy val CharTpe = TypeRef(ScalaPrefix, CharClass, Nil)
+ lazy val IntTpe = TypeRef(ScalaPrefix, IntClass, Nil)
+ lazy val LongTpe = TypeRef(ScalaPrefix, LongClass, Nil)
+ lazy val FloatTpe = TypeRef(ScalaPrefix, FloatClass, Nil)
+ lazy val DoubleTpe = TypeRef(ScalaPrefix, DoubleClass, Nil)
+ lazy val BooleanTpe = TypeRef(ScalaPrefix, BooleanClass, Nil)
+ lazy val UnitTpe = TypeRef(ScalaPrefix, UnitClass, Nil)
+ lazy val AnyTpe = TypeRef(ScalaPrefix, AnyClass, Nil)
+ lazy val AnyValTpe = TypeRef(ScalaPrefix, AnyValClass, Nil)
+ lazy val NothingTpe = TypeRef(ScalaPrefix, NothingClass, Nil)
+ lazy val NullTpe = TypeRef(ScalaPrefix, NullClass, Nil)
+ lazy val ObjectTpe = TypeRef(JavaLangPrefix, ObjectClass, Nil)
+ lazy val AnyRefTpe = ObjectTpe
}
import definitions._
@@ -419,22 +433,6 @@ class Base extends Universe { self =>
private lazy val ScalaPrefix = thisModuleType("scala")
private lazy val JavaLangPrefix = thisModuleType("java.lang")
- lazy val ByteTpe = TypeRef(ScalaPrefix, ByteClass, Nil)
- lazy val ShortTpe = TypeRef(ScalaPrefix, ShortClass, Nil)
- lazy val CharTpe = TypeRef(ScalaPrefix, CharClass, Nil)
- lazy val IntTpe = TypeRef(ScalaPrefix, IntClass, Nil)
- lazy val LongTpe = TypeRef(ScalaPrefix, LongClass, Nil)
- lazy val FloatTpe = TypeRef(ScalaPrefix, FloatClass, Nil)
- lazy val DoubleTpe = TypeRef(ScalaPrefix, DoubleClass, Nil)
- lazy val BooleanTpe = TypeRef(ScalaPrefix, BooleanClass, Nil)
- lazy val UnitTpe = TypeRef(ScalaPrefix, UnitClass, Nil)
- lazy val AnyTpe = TypeRef(ScalaPrefix, AnyClass, Nil)
- lazy val AnyValTpe = TypeRef(ScalaPrefix, AnyValClass, Nil)
- lazy val NothingTpe = TypeRef(ScalaPrefix, NothingClass, Nil)
- lazy val NullTpe = TypeRef(ScalaPrefix, NullClass, Nil)
- lazy val ObjectTpe = TypeRef(JavaLangPrefix, ObjectClass, Nil)
- lazy val AnyRefTpe = ObjectTpe
-
private var nodeCount = 0 // not synchronized
abstract class Tree extends TreeBase with Product {
@@ -489,6 +487,7 @@ class Base extends Universe { self =>
}
case object EmptyTree extends TermTree {
+ val asList = List(this)
override def isEmpty = true
}
@@ -745,7 +744,6 @@ class Base extends Universe { self =>
implicit val ExistentialTypeTreeTag = ClassTag[ExistentialTypeTree](classOf[ExistentialTypeTree])
implicit val TypeTreeTag = ClassTag[TypeTree](classOf[TypeTree])
- // [Eugene++] to be removed after SI-5863 is fixed
def ClassDef(sym: Symbol, impl: Template): ClassDef = ???
def ModuleDef(sym: Symbol, impl: Template): ModuleDef = ???
def ValDef(sym: Symbol, rhs: Tree): ValDef = ???
diff --git a/src/library/scala/reflect/base/BuildUtils.scala b/src/library/scala/reflect/base/BuildUtils.scala
index eaba0ec2b7..98f32231ad 100644
--- a/src/library/scala/reflect/base/BuildUtils.scala
+++ b/src/library/scala/reflect/base/BuildUtils.scala
@@ -5,6 +5,10 @@ trait BuildUtils { self: Universe =>
val build: BuildBase
+ // this API abstracts away the functionality necessary for reification
+ // it's too gimmicky and unstructured to be exposed directly in the universe
+ // but we need it in a publicly available place for reification to work
+
abstract class BuildBase {
/** Selects type symbol with given simple name `name` from the defined members of `owner`.
*/
@@ -53,7 +57,6 @@ trait BuildUtils { self: Universe =>
* the only usage for it is preserving the captured symbol for compile-time analysis
* @param flags (optional) flags of the free variable
* @param origin (optional) debug information that tells where this symbol comes from
- * [Martin to Eugene: why needed?]
*/
def newFreeExistential(name: String, info: Type, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol
@@ -68,9 +71,6 @@ trait BuildUtils { self: Universe =>
def flagsFromBits(bits: Long): FlagSet
- // [Eugene++ to Martin] these are necessary for reification
- // on a second thought, I added them to BuildUtils instead of base
-
def emptyValDef: ValDef
def This(sym: Symbol): Tree
diff --git a/src/library/scala/reflect/base/Exprs.scala b/src/library/scala/reflect/base/Exprs.scala
index 47af4f3a9d..10c222722a 100644
--- a/src/library/scala/reflect/base/Exprs.scala
+++ b/src/library/scala/reflect/base/Exprs.scala
@@ -39,10 +39,7 @@ trait Exprs { self: Universe =>
otherMirror.universe.Expr[T](otherMirror1, treec)(tag1)
}
- lazy val tree: Tree = treec[Exprs.this.type](mirror)
- // [Eugene++] this is important
- // !!! remove when we have improved type inference for singletons
- // search for .type] to find other instances
+ lazy val tree: Tree = treec(mirror)
lazy val staticType: Type = implicitly[AbsTypeTag[T]].tpe
def actualType: Type = treeType(tree)
diff --git a/src/library/scala/reflect/base/MirrorOf.scala b/src/library/scala/reflect/base/MirrorOf.scala
index 6dc8090eee..1e9619d062 100644
--- a/src/library/scala/reflect/base/MirrorOf.scala
+++ b/src/library/scala/reflect/base/MirrorOf.scala
@@ -1,8 +1,6 @@
package scala.reflect
package base
-// [Eugene++ to Martin] why was this a member of `scala.reflect`, but not `scala.reflect.base`?
-
abstract class MirrorOf[U <: base.Universe with Singleton] {
/** .. */
val universe: U
diff --git a/src/library/scala/reflect/base/Positions.scala b/src/library/scala/reflect/base/Positions.scala
index cefeb51c9a..76a7382e9e 100644
--- a/src/library/scala/reflect/base/Positions.scala
+++ b/src/library/scala/reflect/base/Positions.scala
@@ -14,9 +14,4 @@ trait Positions {
/** .. */
val NoPosition: Position
-
- /** Assigns a given position to all position-less nodes of a given AST.
- */
- def atPos[T <: Tree](pos: Position)(tree: T): T
- // [Eugene++] why do we have this in base?
}
diff --git a/src/library/scala/reflect/base/StandardDefinitions.scala b/src/library/scala/reflect/base/StandardDefinitions.scala
index fe32fdb4c2..8f1c96ea3f 100644
--- a/src/library/scala/reflect/base/StandardDefinitions.scala
+++ b/src/library/scala/reflect/base/StandardDefinitions.scala
@@ -6,37 +6,12 @@
package scala.reflect
package base
-// [Eugene++] not sure whether we need this in the top level of the universe
-trait StandardTypes {
- self: Universe =>
-
- val ByteTpe: Type
- val ShortTpe: Type
- val CharTpe: Type
- val IntTpe: Type
- val LongTpe: Type
- val FloatTpe: Type
- val DoubleTpe: Type
- val BooleanTpe: Type
- val UnitTpe: Type
-
- val AnyTpe: Type
- val AnyValTpe: Type
- val AnyRefTpe: Type
- val ObjectTpe: Type
-
- val NothingTpe: Type
- val NullTpe: Type
-}
-
-trait StandardDefinitions extends StandardTypes {
+trait StandardDefinitions {
self: Universe =>
val definitions: DefinitionsBase
- // [Eugene] todo. shortcut to these fields if possible when generating tags
- // todo. also shortcut to StandardTypes, of course
- trait DefinitionsBase {
+ trait DefinitionsBase extends StandardTypes {
// packages
def ScalaPackageClass: ClassSymbol
def ScalaPackage: ModuleSymbol
@@ -66,9 +41,32 @@ trait StandardDefinitions extends StandardTypes {
def StringClass : ClassSymbol
def ClassClass : ClassSymbol
def ArrayClass : ClassSymbol
- def ListClass : ClassSymbol // [Eugene] I'd say List has earned its right to be here
+ def ListClass : ClassSymbol
// the Predef object
def PredefModule: ModuleSymbol
}
+
+ trait StandardTypes {
+ // the scala value classes
+ val UnitTpe: Type
+ val ByteTpe: Type
+ val ShortTpe: Type
+ val CharTpe: Type
+ val IntTpe: Type
+ val LongTpe: Type
+ val FloatTpe: Type
+ val DoubleTpe: Type
+ val BooleanTpe: Type
+
+ // top types
+ val AnyTpe: Type
+ val AnyValTpe: Type
+ val AnyRefTpe: Type
+ val ObjectTpe: Type
+
+ // bottom types
+ val NothingTpe: Type
+ val NullTpe: Type
+ }
}
diff --git a/src/library/scala/reflect/base/Symbols.scala b/src/library/scala/reflect/base/Symbols.scala
index fe857c540f..294fa19d62 100644
--- a/src/library/scala/reflect/base/Symbols.scala
+++ b/src/library/scala/reflect/base/Symbols.scala
@@ -3,9 +3,6 @@ package base
trait Symbols { self: Universe =>
- // [Eugene++ to Martin] why is Symbol >: Null, whereas all other symbol types are not nullable?
- // same question goes for Types
-
/** The abstract type of symbols representing declarations */
type Symbol >: Null <: SymbolBase
@@ -266,7 +263,7 @@ trait Symbols { self: Universe =>
* by inspecting its `selfType.termSymbol`.
*/
def moduleClass: Symbol // needed for tree traversals
- // [Eugene++] when this becomes `moduleClass: ClassSymbol`, it will be the happiest day in my life
+ // when this becomes `moduleClass: ClassSymbol`, it will be the happiest day in my life
final override def isModule = true
final override def asModule = this
diff --git a/src/library/scala/reflect/base/TagInterop.scala b/src/library/scala/reflect/base/TagInterop.scala
index a9f0b60fd2..ec054106eb 100644
--- a/src/library/scala/reflect/base/TagInterop.scala
+++ b/src/library/scala/reflect/base/TagInterop.scala
@@ -4,12 +4,9 @@ package base
import scala.runtime.ScalaRunTime._
trait TagInterop { self: Universe =>
- // [Eugene++] `mirror` parameters are now of type `Any`, because I can't make these path-dependent types work
+ // todo. `mirror` parameters are now of type `Any`, because I can't make these path-dependent types work
// if you're brave enough, replace `Any` with `Mirror`, recompile and run interop_typetags_are_manifests.scala
- // [Eugene++] would be great if we could approximate the interop without any mirrors
- // todo. think how to implement that
-
def typeTagToManifest[T: ClassTag](mirror: Any, tag: base.Universe # TypeTag[T]): Manifest[T] =
throw new UnsupportedOperationException("This universe does not support tag -> manifest conversions. Use scala.reflect.runtime.universe from scala-reflect.jar.")
diff --git a/src/library/scala/reflect/base/Trees.scala b/src/library/scala/reflect/base/Trees.scala
index 70993fd77f..224965a2b7 100644
--- a/src/library/scala/reflect/base/Trees.scala
+++ b/src/library/scala/reflect/base/Trees.scala
@@ -5,10 +5,6 @@
package scala.reflect
package base
-// [Eugene++] of all reflection APIs, this one is in the biggest need of review and documentation
-
-// Syncnote: Trees are currently not thread-safe.
-// [Eugene++] now when trees are finally abstract types, can we do something for this?
trait Trees { self: Universe =>
/** The base API that all trees support */
@@ -81,7 +77,6 @@ trait Trees { self: Universe =>
* example is Parens, which is eliminated during parsing.
*/
type Tree >: Null <: TreeBase
- // [Eugene++] todo. discuss nullability of abstract types
/** A tag that preserves the identity of the `Tree` abstract type from erasure.
* Can be used for pattern matching, instance tests, serialization and likes.
@@ -1381,7 +1376,6 @@ trait Trees { self: Universe =>
/** ... */
lazy val NoMods = Modifiers()
- // [Eugene++] temporarily moved here until SI-5863 is fixed
// ---------------------- factories ----------------------------------------------
/** @param sym the class symbol
diff --git a/src/library/scala/reflect/base/TypeTags.scala b/src/library/scala/reflect/base/TypeTags.scala
index b673122d00..c9d1ccf5bc 100644
--- a/src/library/scala/reflect/base/TypeTags.scala
+++ b/src/library/scala/reflect/base/TypeTags.scala
@@ -99,9 +99,10 @@ import language.implicitConversions
* 4) Certain manifest functions (such as `<:<`, `>:>` and `typeArguments`) weren't included in the tag API.
* Consider using reflection API provided by Java (for classes) and Scala (for types) instead.
*/
-// [Eugene++] implement serialization for typetags
trait TypeTags { self: Universe =>
+ import definitions._
+
/**
* If an implicit value of type u.AbsTypeTag[T] is required, the compiler will make one up on demand.
* The implicitly created value contains in its tpe field a value of type u.Type that is a reflective representation of T.
@@ -164,7 +165,7 @@ trait TypeTags { self: Universe =>
}
private class AbsTypeTagImpl[T](val mirror: Mirror, val tpec: TypeCreator) extends AbsTypeTag[T] {
- lazy val tpe: Type = tpec[self.type](mirror)
+ lazy val tpe: Type = tpec(mirror)
def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # AbsTypeTag[T] = {
val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]]
otherMirror.universe.AbsTypeTag[T](otherMirror1, tpec)
diff --git a/src/library/scala/reflect/base/Types.scala b/src/library/scala/reflect/base/Types.scala
index 28aaf2d04d..b016b77f36 100644
--- a/src/library/scala/reflect/base/Types.scala
+++ b/src/library/scala/reflect/base/Types.scala
@@ -14,7 +14,7 @@ trait Types { self: Universe =>
/** A tag that preserves the identity of the `Type` abstract type from erasure.
* Can be used for pattern matching, instance tests, serialization and likes.
*/
- implicit val TypeTagg: ClassTag[Type] // [Eugene++] rename!
+ implicit val TypeTagg: ClassTag[Type]
/** This constant is used as a special value that indicates that no meaningful type exists.
*/
diff --git a/src/library/scala/reflect/macros/internal/package.scala b/src/library/scala/reflect/macros/internal/package.scala
index 912db53ed4..0a0e6c5b51 100644
--- a/src/library/scala/reflect/macros/internal/package.scala
+++ b/src/library/scala/reflect/macros/internal/package.scala
@@ -5,9 +5,7 @@ import scala.reflect.ClassTag
// anchors for materialization macros emitted during tag materialization in Implicits.scala
// implementation is magically hardwired into `scala.reflect.reify.Taggers`
-//
// todo. once we have implicit macros for tag generation, we can remove these anchors
-// [Eugene++] how do I hide this from scaladoc?
package object internal {
private[scala] def materializeClassTag[T](u: BaseUniverse): ClassTag[T] = ??? // macro
private[scala] def materializeAbsTypeTag[T](u: BaseUniverse): u.AbsTypeTag[T] = ??? // macro
diff --git a/src/library/scala/util/Marshal.scala b/src/library/scala/util/Marshal.scala
index 2d3f54a95e..79476bdc16 100644
--- a/src/library/scala/util/Marshal.scala
+++ b/src/library/scala/util/Marshal.scala
@@ -37,8 +37,6 @@ object Marshal {
val in = new ObjectInputStream(new ByteArrayInputStream(buffer))
val found = in.readObject.asInstanceOf[ClassTag[_]]
try {
- // [Eugene] needs review
- // previously was: found <:< expected
found.runtimeClass.asSubclass(expected.runtimeClass)
in.readObject.asInstanceOf[A]
} catch {
diff --git a/src/reflect/scala/reflect/api/FrontEnds.scala b/src/reflect/scala/reflect/api/FrontEnds.scala
index a201b83444..a27450d49d 100644
--- a/src/reflect/scala/reflect/api/FrontEnds.scala
+++ b/src/reflect/scala/reflect/api/FrontEnds.scala
@@ -1,8 +1,6 @@
package scala.reflect
package api
-// [Martin to Eugene] Todo: Needs to be evicted from API
-// [Eugene++ to Martin] but how? we need them for macros
trait FrontEnds {
type Position >: Null
diff --git a/src/reflect/scala/reflect/api/Importers.scala b/src/reflect/scala/reflect/api/Importers.scala
index de540a9605..fbc29a514e 100644
--- a/src/reflect/scala/reflect/api/Importers.scala
+++ b/src/reflect/scala/reflect/api/Importers.scala
@@ -1,8 +1,6 @@
package scala.reflect
package api
-// [Martin] Importers need to be made mirror aware.
-// [Eugene++] this is important
trait Importers { self: Universe =>
def mkImporter(from0: Universe): Importer { val from: from0.type }
diff --git a/src/reflect/scala/reflect/api/JavaUniverse.scala b/src/reflect/scala/reflect/api/JavaUniverse.scala
index 8bf62a357c..f2388433c4 100644
--- a/src/reflect/scala/reflect/api/JavaUniverse.scala
+++ b/src/reflect/scala/reflect/api/JavaUniverse.scala
@@ -1,8 +1,6 @@
package scala.reflect
package api
-// [Martin] Moved to compiler because it needs to see runtime.Universe
-// The two will be united in scala-reflect anyway.
trait JavaUniverse extends Universe with Mirrors with TagInterop { self =>
type RuntimeClass = java.lang.Class[_]
diff --git a/src/reflect/scala/reflect/api/Mirrors.scala b/src/reflect/scala/reflect/api/Mirrors.scala
index f2f96645e3..7d185d9879 100644
--- a/src/reflect/scala/reflect/api/Mirrors.scala
+++ b/src/reflect/scala/reflect/api/Mirrors.scala
@@ -5,19 +5,7 @@ trait Mirrors { self: Universe =>
type RuntimeClass >: Null
- // [Eugene] also, it might make sense to provide shortcuts for the API
- //
- // for example, right now to invoke the same method for several different instances, you need:
- // 1) get the method symbol
- // 2) get the instance mirror for every instance
- // 3) call reflectMethod on the instance mirrors for every instance
- // 4) call apply for every instance (okay, this can be united with step #3, but still)
- //
- // I have several suggestions that we can discuss later:
- // 1) For every `reflectXXX(sym: Symbol): XXXMirror`, add `reflectXXX(name: String, types: Type*): XXXMirror` and `reflectXXXs(): List[XXXMirror]`
- // 2) Provide a way to skip obtaining InstanceMirror (step #2 in the outline provided above)
-
- // [Eugene] another improvement would be have mirrors reproduce the structure of the reflection domain
+ // todo. an improvement might be having mirrors reproduce the structure of the reflection domain
// e.g. a ClassMirror could also have a list of fields, methods, constructors and so on
// read up more on the proposed design in "Reflecting Scala" by Y. Coppel
@@ -162,7 +150,7 @@ trait Mirrors { self: Universe =>
def runtimeClass: RuntimeClass
/** True if the mirror represents the static part
- * if a runtime class or the companion object of a Scala class.
+ * of a runtime class or the companion object of a Scala class.
* One has:
*
* this.isStatic == this.isInstanceOf[ModuleMirror]
@@ -204,7 +192,7 @@ trait Mirrors { self: Universe =>
* Otherwise, if the mirror represents the static part of a runtime class, the
* mirror representing the instance part of the same class.
*/
- def companion: Option[ClassMirror]
+ override def companion: Option[ClassMirror]
}
/** A mirror that reflects the instance parts of a runtime class */
@@ -231,7 +219,7 @@ trait Mirrors { self: Universe =>
* Otherwise, if the mirror represents a runtime instance class, a mirror representing the static
* part of the same class.
*/
- def companion: Option[ModuleMirror]
+ override def companion: Option[ModuleMirror]
}
/** A mirror that reflects instances and static classes */
diff --git a/src/reflect/scala/reflect/api/Positions.scala b/src/reflect/scala/reflect/api/Positions.scala
index 9d3d90d9f8..5e8d958f02 100644
--- a/src/reflect/scala/reflect/api/Positions.scala
+++ b/src/reflect/scala/reflect/api/Positions.scala
@@ -7,6 +7,10 @@ trait Positions extends base.Positions {
/** .. */
type Position >: Null <: PositionApi { type Pos = Position }
+ /** Assigns a given position to all position-less nodes of a given AST.
+ */
+ def atPos[T <: Tree](pos: Position)(tree: T): T
+
/** 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
@@ -20,14 +24,6 @@ trait Positions extends base.Positions {
* Otherwise returns a synthetic offset position to point.
*/
def wrappingPos(trees: List[Tree]): Position
-
- /** 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`.
- */
- //def ensureNonOverlapping(tree: Tree, others: List[Tree])
- // [Eugene++] can this method be of use for macros?
}
/** The Position class and its subclasses represent positions of ASTs and symbols.
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index 3415b0fa10..9e7b3c9712 100644
--- a/src/reflect/scala/reflect/api/Symbols.scala
+++ b/src/reflect/scala/reflect/api/Symbols.scala
@@ -21,7 +21,7 @@ trait Symbols extends base.Symbols { self: Universe =>
/** A list of annotations attached to this Symbol.
*/
- // [Eugene++] we cannot expose the `annotations` method because it doesn't auto-initialize a symbol (see SI-5423)
+ // we cannot expose the `annotations` method because it doesn't auto-initialize a symbol (see SI-5423)
// there was an idea to use the `isCompilerUniverse` flag and auto-initialize symbols in `annotations` whenever this flag is false
// but it doesn't work, because the unpickler (that is shared between reflective universes and global universes) is very picky about initialization
// scala.reflect.internal.Types$TypeError: bad reference while unpickling scala.collection.immutable.Nil: type Nothing not found in scala.type not found.
@@ -205,7 +205,6 @@ trait Symbols extends base.Symbols { self: Universe =>
/** The API of term symbols */
trait TermSymbolApi extends SymbolApi with TermSymbolBase { this: TermSymbol =>
/** Does this symbol represent a value, i.e. not a module and not a method?
- * [Eugene++] I need a review of the implementation
*/
def isValue: Boolean
diff --git a/src/reflect/scala/reflect/api/TagInterop.scala b/src/reflect/scala/reflect/api/TagInterop.scala
index 4d2254cb9f..5ab085741e 100644
--- a/src/reflect/scala/reflect/api/TagInterop.scala
+++ b/src/reflect/scala/reflect/api/TagInterop.scala
@@ -4,16 +4,10 @@ package api
import scala.reflect.base.TypeCreator
import scala.reflect.base.{Universe => BaseUniverse}
-// [Martin] Moved to compiler because it needs to see runtime.Universe
-// The two will be united in scala-reflect anyway.
trait TagInterop { self: JavaUniverse =>
- // [Eugene++] would be great if we could approximate the interop without any mirrors
- // todo. think how to implement that
-
override def typeTagToManifest[T: ClassTag](mirror0: Any, tag: base.Universe # TypeTag[T]): Manifest[T] = {
- // [Eugene++] implement more sophisticated logic
- // Martin said it'd be okay to simply copypaste `Implicits.manifestOfType`
+ // SI-6239: make this conversion more precise
val mirror = mirror0.asInstanceOf[Mirror]
val runtimeClass = mirror.runtimeClass(tag.in(mirror).tpe)
Manifest.classType(runtimeClass).asInstanceOf[Manifest[T]]
diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala
index 199cf9b9e5..ebaedd7ac3 100644
--- a/src/reflect/scala/reflect/api/Types.scala
+++ b/src/reflect/scala/reflect/api/Types.scala
@@ -293,7 +293,6 @@ trait Types extends base.Types { self: Universe =>
// Creators ---------------------------------------------------------------
// too useful and too non-trivial to be left out of public API
- // [Eugene to Paul] needs review!
/** The canonical creator for single-types */
def singleType(pre: Type, sym: Symbol): Type
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index f01247d918..2daf3d1c85 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -19,23 +19,6 @@ trait Definitions extends api.StandardDefinitions {
object definitions extends DefinitionsClass
- // [Eugene] find a way to make these non-lazy
- lazy val ByteTpe = definitions.ByteClass.toTypeConstructor
- lazy val ShortTpe = definitions.ShortClass.toTypeConstructor
- lazy val CharTpe = definitions.CharClass.toTypeConstructor
- lazy val IntTpe = definitions.IntClass.toTypeConstructor
- lazy val LongTpe = definitions.LongClass.toTypeConstructor
- lazy val FloatTpe = definitions.FloatClass.toTypeConstructor
- lazy val DoubleTpe = definitions.DoubleClass.toTypeConstructor
- lazy val BooleanTpe = definitions.BooleanClass.toTypeConstructor
- lazy val UnitTpe = definitions.UnitClass.toTypeConstructor
- lazy val AnyTpe = definitions.AnyClass.toTypeConstructor
- lazy val ObjectTpe = definitions.ObjectClass.toTypeConstructor
- lazy val AnyValTpe = definitions.AnyValClass.toTypeConstructor
- lazy val AnyRefTpe = definitions.AnyRefClass.toTypeConstructor
- lazy val NothingTpe = definitions.NothingClass.toTypeConstructor
- lazy val NullTpe = definitions.NullClass.toTypeConstructor
-
/** Since both the value parameter types and the result type may
* require access to the type parameter symbols, we model polymorphic
* creation as a function from those symbols to (formal types, result type).
@@ -143,10 +126,19 @@ trait Definitions extends api.StandardDefinitions {
lazy val Boolean_or = getMemberMethod(BooleanClass, nme.ZOR)
lazy val Boolean_not = getMemberMethod(BooleanClass, nme.UNARY_!)
- lazy val ScalaNumericValueClasses = ScalaValueClasses filterNot Set[Symbol](UnitClass, BooleanClass)
+ lazy val UnitTpe = UnitClass.toTypeConstructor
+ lazy val ByteTpe = ByteClass.toTypeConstructor
+ lazy val ShortTpe = ShortClass.toTypeConstructor
+ lazy val CharTpe = CharClass.toTypeConstructor
+ lazy val IntTpe = IntClass.toTypeConstructor
+ lazy val LongTpe = LongClass.toTypeConstructor
+ lazy val FloatTpe = FloatClass.toTypeConstructor
+ lazy val DoubleTpe = DoubleClass.toTypeConstructor
+ lazy val BooleanTpe = BooleanClass.toTypeConstructor
- def ScalaValueClassesNoUnit = ScalaValueClasses filterNot (_ eq UnitClass)
- def ScalaValueClasses: List[ClassSymbol] = List(
+ lazy val ScalaNumericValueClasses = ScalaValueClasses filterNot Set[Symbol](UnitClass, BooleanClass)
+ lazy val ScalaValueClassesNoUnit = ScalaValueClasses filterNot (_ eq UnitClass)
+ lazy val ScalaValueClasses: List[ClassSymbol] = List(
UnitClass,
BooleanClass,
ByteClass,
@@ -242,6 +234,9 @@ trait Definitions extends api.StandardDefinitions {
lazy val AnyClass = enterNewClass(ScalaPackageClass, tpnme.Any, Nil, ABSTRACT)
lazy val AnyRefClass = newAlias(ScalaPackageClass, tpnme.AnyRef, ObjectClass.tpe)
lazy val ObjectClass = getRequiredClass(sn.Object.toString)
+ lazy val AnyTpe = definitions.AnyClass.toTypeConstructor
+ lazy val AnyRefTpe = definitions.AnyRefClass.toTypeConstructor
+ lazy val ObjectTpe = definitions.ObjectClass.toTypeConstructor
// Note: this is not the type alias AnyRef, it's a companion-like
// object used by the @specialize annotation.
@@ -255,6 +250,7 @@ trait Definitions extends api.StandardDefinitions {
anyval.info.decls enter av_constr
anyval
}).asInstanceOf[ClassSymbol]
+ lazy val AnyValTpe = definitions.AnyValClass.toTypeConstructor
// bottom types
lazy val RuntimeNothingClass = getClassByName(fulltpnme.RuntimeNothing)
@@ -276,6 +272,8 @@ trait Definitions extends api.StandardDefinitions {
|| (that ne NothingClass) && (that isSubClass ObjectClass)
)
}
+ lazy val NothingTpe = definitions.NothingClass.toTypeConstructor
+ lazy val NullTpe = definitions.NullClass.toTypeConstructor
// exceptions and other throwables
lazy val ClassCastExceptionClass = requiredClass[ClassCastException]
@@ -302,7 +300,7 @@ trait Definitions extends api.StandardDefinitions {
def Sys_error = getMemberMethod(SysPackage, nme.error)
// Modules whose members are in the default namespace
- // [Eugene++] ScalaPackage and JavaLangPackage are never ever shared between mirrors
+ // SI-5941: ScalaPackage and JavaLangPackage are never ever shared between mirrors
// as a result, `Int` becomes `scala.Int` and `String` becomes `java.lang.String`
// I could just change `isOmittablePrefix`, but there's more to it, so I'm leaving this as a todo for now
lazy val UnqualifiedModules = List(PredefModule, ScalaPackage, JavaLangPackage)
@@ -338,7 +336,6 @@ trait Definitions extends api.StandardDefinitions {
lazy val SymbolModule = requiredModule[scala.Symbol.type]
lazy val Symbol_apply = getMemberMethod(SymbolModule, nme.apply)
- def SeqFactory = getMember(ScalaRunTimeModule, nme.Seq) // [Eugene++] obsolete?
def arrayApplyMethod = getMemberMethod(ScalaRunTimeModule, nme.array_apply)
def arrayUpdateMethod = getMemberMethod(ScalaRunTimeModule, nme.array_update)
def arrayLengthMethod = getMemberMethod(ScalaRunTimeModule, nme.array_length)
@@ -383,6 +380,7 @@ trait Definitions extends api.StandardDefinitions {
def isScalaRepeatedParamType(tp: Type) = tp.typeSymbol == RepeatedParamClass
def isJavaRepeatedParamType(tp: Type) = tp.typeSymbol == JavaRepeatedParamClass
def isRepeatedParamType(tp: Type) = isScalaRepeatedParamType(tp) || isJavaRepeatedParamType(tp)
+ def isRepeated(param: Symbol) = isRepeatedParamType(param.tpe)
def isCastSymbol(sym: Symbol) = sym == Any_asInstanceOf || sym == Object_asInstanceOf
def isJavaVarArgsMethod(m: Symbol) = m.isMethod && isJavaVarArgs(m.info.params)
@@ -978,12 +976,7 @@ trait Definitions extends api.StandardDefinitions {
throw new FatalError(owner + " does not have a " + what + " " + name)
}
- def getLanguageFeature(name: String, owner: Symbol = languageFeatureModule): Symbol =
- // [Eugene++] `getMemberClass` leads to crashes in mixin:
- // "object languageFeature does not have a member class implicitConversions"
- // that's because by that time `implicitConversions` becomes a module
- // getMemberClass(owner, newTypeName(name))
- getMember(owner, newTypeName(name))
+ def getLanguageFeature(name: String, owner: Symbol = languageFeatureModule): Symbol = getMember(owner, newTypeName(name))
def termMember(owner: Symbol, name: String): Symbol = owner.info.member(newTermName(name))
def typeMember(owner: Symbol, name: String): Symbol = owner.info.member(newTypeName(name))
@@ -1008,28 +1001,24 @@ trait Definitions extends api.StandardDefinitions {
}
}
def getMemberValue(owner: Symbol, name: Name): TermSymbol = {
- // [Eugene++] should be a ClassCastException instead?
getMember(owner, name.toTermName) match {
case x: TermSymbol => x
case _ => fatalMissingSymbol(owner, name, "member value")
}
}
def getMemberModule(owner: Symbol, name: Name): ModuleSymbol = {
- // [Eugene++] should be a ClassCastException instead?
getMember(owner, name.toTermName) match {
case x: ModuleSymbol => x
case _ => fatalMissingSymbol(owner, name, "member object")
}
}
def getMemberType(owner: Symbol, name: Name): TypeSymbol = {
- // [Eugene++] should be a ClassCastException instead?
getMember(owner, name.toTypeName) match {
case x: TypeSymbol => x
case _ => fatalMissingSymbol(owner, name, "member type")
}
}
def getMemberClass(owner: Symbol, name: Name): ClassSymbol = {
- // [Eugene++] should be a ClassCastException instead?
val y = getMember(owner, name.toTypeName)
getMember(owner, name.toTypeName) match {
case x: ClassSymbol => x
@@ -1037,48 +1026,8 @@ trait Definitions extends api.StandardDefinitions {
}
}
def getMemberMethod(owner: Symbol, name: Name): TermSymbol = {
- // [Eugene++] is this a bug?
- //
- // System.err.println(result.getClass)
- // System.err.println(result.flags)
- // System.err.println("isMethod = " + result.isMethod)
- // System.err.println("isTerm = " + result.isTerm)
- // System.err.println("isValue = " + result.isValue)
- // result.asMethod
- //
- // prints this:
- //
- // quick.lib:
- // [javac] Compiling 1 source file to C:\Projects\KeplerUnderRefactoring\build\quick\classes\library
- // [scalacfork] Compiling 769 files to C:\Projects\KeplerUnderRefactoring\build\quick\classes\library
- // [scalacfork] class scala.reflect.internal.Symbols$TermSymbol
- // [scalacfork] 8589934592
- // [scalacfork] isMethod = false
- // [scalacfork] isTerm = true
- // [scalacfork] isValue = true
- // [scalacfork]
- // [scalacfork] while compiling: C:\Projects\KeplerUnderRefactoring\src\library\scala\LowPriorityImplicits.scala
- // [scalacfork] current phase: cleanup
- // [scalacfork] library version: version 2.10.0-20120507-185519-665d1d9127
- // [scalacfork] compiler version: version 2.10.0-20120507-185519-665d1d9127
- // [scalacfork] reconstructed args: -Xmacros -classpath C:\\Projects\\KeplerUnderRefactoring\\build\\quick\\classes\\library;C:\\Projects\\KeplerUnderRefactoring\\lib\\forkjoin.jar -d C:\\Projects\\KeplerUnderRefactoring\\build\\quick\\classes\\library -sourcepath C:\\Projects\\KeplerUnderRefactoring\\src\\library
- // [scalacfork]
- // [scalacfork] unhandled exception while transforming LowPriorityImplicits.scala
- // [scalacfork] error:
- // [scalacfork] while compiling: C:\Projects\KeplerUnderRefactoring\src\library\scala\LowPriorityImplicits.scala
- // [scalacfork] current phase: cleanup
- // [scalacfork] library version: version 2.10.0-20120507-185519-665d1d9127
- // [scalacfork] compiler version: version 2.10.0-20120507-185519-665d1d9127
- // [scalacfork] reconstructed args: -Xmacros -classpath C:\\Projects\\KeplerUnderRefactoring\\build\\quick\\classes\\library;C:\\Projects\\KeplerUnderRefactoring\\lib\\forkjoin.jar -d C:\\Projects\\KeplerUnderRefactoring\\build\\quick\\classes\\library -sourcepath C:\\Projects\\KeplerUnderRefactoring\\src\\library
- // [scalacfork]
- // [scalacfork] uncaught exception during compilation: java.lang.ClassCastException
- // [scalacfork] error: java.lang.ClassCastException: value apply
- // [scalacfork] at scala.reflect.base.Symbols$SymbolBase$class.asMethod(Symbols.scala:118)
- // [scalacfork] at scala.reflect.internal.Symbols$SymbolContextApiImpl.asMethod(Symbols.scala:63)
- // [scalacfork] at scala.reflect.internal.Definitions$DefinitionsClass.Symbol_apply(Definitions.scala:381)
-
- // [Eugene++] should be a ClassCastException instead?
getMember(owner, name.toTermName) match {
+ // todo. member symbol becomes a term symbol in cleanup. is this a bug?
// case x: MethodSymbol => x
case x: TermSymbol => x
case _ => fatalMissingSymbol(owner, name, "method")
diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala
index 00017e087a..25441f9812 100644
--- a/src/reflect/scala/reflect/internal/Importers.scala
+++ b/src/reflect/scala/reflect/internal/Importers.scala
@@ -2,10 +2,9 @@ package scala.reflect
package internal
import scala.collection.mutable.WeakHashMap
-// todo: move importers to a mirror
+// SI-6241: move importers to a mirror
trait Importers { self: SymbolTable =>
- // [Eugene] possible to make this less cast-heavy?
def mkImporter(from0: api.Universe): Importer { val from: from0.type } = (
if (self eq from0) {
new Importer {
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index 0c86e4fba0..9580ed1f72 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -3,7 +3,7 @@
* @author Martin Odersky
*/
-// [Eugene++ to Martin] we need to unify this prettyprinter with NodePrinters
+// todo. we need to unify this prettyprinter with NodePrinters
package scala.reflect
package internal
@@ -174,12 +174,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
}
def printAnnotations(tree: Tree) {
- if (!isCompilerUniverse && tree.symbol != null && tree.symbol != NoSymbol)
- // [Eugene++] todo. this is not 100% correct, but is necessary for sane printing
- // the problem is that getting annotations doesn't automatically initialize the symbol
- // so we might easily print something as if it doesn't have annotations, whereas it does
- tree.symbol.initialize
-
+ // SI-5885: by default this won't print annotations of not yet initialized symbols
val annots = tree.symbol.annotations match {
case Nil => tree.asInstanceOf[MemberDef].mods.annotations
case anns => anns
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index c1e5f78d50..f63e2602b1 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -1008,8 +1008,6 @@ trait StdNames {
val javanme = nme.javaKeywords
- // [Eugene++ to Martin] had to move a lot of stuff from here to TermNames to satisfy the contract
- // why do we even have stuff in object nme? cf. object tpnme
object nme extends TermNames {
def isModuleVarName(name: Name): Boolean =
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 5e83f638a2..0953849f05 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -294,14 +294,31 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def newExistential(name: TypeName, pos: Position = NoPosition, newFlags: Long = 0L): TypeSymbol =
newAbstractType(name, pos, EXISTENTIAL | newFlags)
- /** Synthetic value parameters when parameter symbols are not available
- */
- final def newSyntheticValueParamss(argtypess: List[List[Type]]): List[List[TermSymbol]] = {
+ private def freshNamer: () => TermName = {
var cnt = 0
- def freshName() = { cnt += 1; nme.syntheticParamName(cnt) }
- mmap(argtypess)(tp => newValueParameter(freshName(), owner.pos.focus, SYNTHETIC) setInfo tp)
+ () => { cnt += 1; nme.syntheticParamName(cnt) }
}
+ /** Synthetic value parameters when parameter symbols are not available
+ */
+ final def newSyntheticValueParamss(argtypess: List[List[Type]]): List[List[TermSymbol]] =
+ argtypess map (xs => newSyntheticValueParams(xs, freshNamer))
+
+ /** Synthetic value parameters when parameter symbols are not available.
+ * Calling this method multiple times will re-use the same parameter names.
+ */
+ final def newSyntheticValueParams(argtypes: List[Type]): List[TermSymbol] =
+ newSyntheticValueParams(argtypes, freshNamer)
+
+ final def newSyntheticValueParams(argtypes: List[Type], freshName: () => TermName): List[TermSymbol] =
+ argtypes map (tp => newSyntheticValueParam(tp, freshName()))
+
+ /** Synthetic value parameter when parameter symbol is not available.
+ * Calling this method multiple times will re-use the same parameter name.
+ */
+ final def newSyntheticValueParam(argtype: Type, name: TermName = nme.syntheticParamName(1)): TermSymbol =
+ newValueParameter(name, owner.pos.focus, SYNTHETIC) setInfo argtype
+
def newSyntheticTypeParam(): TypeSymbol = newSyntheticTypeParam("T0", 0L)
def newSyntheticTypeParam(name: String, newFlags: Long): TypeSymbol = newTypeParameter(newTypeName(name), NoPosition, newFlags) setInfo TypeBounds.empty
def newSyntheticTypeParams(num: Int): List[TypeSymbol] = (0 until num).toList map (n => newSyntheticTypeParam("T" + n, 0L))
@@ -328,18 +345,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def freshExistential(suffix: String): TypeSymbol =
newExistential(freshExistentialName(suffix), pos)
- /** Synthetic value parameters when parameter symbols are not available.
- * Calling this method multiple times will re-use the same parameter names.
- */
- final def newSyntheticValueParams(argtypes: List[Type]): List[TermSymbol] =
- newSyntheticValueParamss(List(argtypes)).head
-
- /** Synthetic value parameter when parameter symbol is not available.
- * Calling this method multiple times will re-use the same parameter name.
- */
- final def newSyntheticValueParam(argtype: Type): Symbol =
- newSyntheticValueParams(List(argtype)).head
-
/** Type skolems are type parameters ''seen from the inside''
* Assuming a polymorphic method m[T], its type is a PolyType which has a TypeParameter
* with name `T` in its typeParams list. While type checking the parameters, result type and
@@ -848,7 +853,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
final def isInitialized: Boolean =
validTo != NoPeriod
- // [Eugene] todo. needs to be reviewed and [only then] rewritten without explicit returns
/** Determines whether this symbol can be loaded by subsequent reflective compilation */
final def isLocatable: Boolean = {
if (this == NoSymbol) return false
@@ -1536,7 +1540,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def alternatives: List[Symbol] =
if (isOverloaded) info.asInstanceOf[OverloadedType].alternatives
- else List(this)
+ else this :: Nil
def filter(cond: Symbol => Boolean): Symbol =
if (isOverloaded) {
@@ -1640,7 +1644,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
(info.decls filter (_.isCaseAccessorMethod)).toList
final def constrParamAccessors: List[Symbol] =
- info.decls.toList filter (sym => !sym.isMethod && sym.isParamAccessor)
+ info.decls.filter(sym => !sym.isMethod && sym.isParamAccessor).toList
/** The symbol accessed by this accessor (getter or setter) function. */
final def accessed: Symbol = accessed(owner.info)
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index d160695e67..f953e9b757 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -194,7 +194,7 @@ abstract class TreeGen extends macros.TreeBuilder {
mkTypeApply(mkAttributedSelect(target, method), targs map TypeTree)
private def mkSingleTypeApply(value: Tree, tpe: Type, what: Symbol, wrapInApply: Boolean) = {
- val tapp = mkAttributedTypeApply(value, what, List(tpe.normalize))
+ val tapp = mkAttributedTypeApply(value, what, tpe.normalize :: Nil)
if (wrapInApply) Apply(tapp, Nil) else tapp
}
private def typeTestSymbol(any: Boolean) = if (any) Any_isInstanceOf else Object_isInstanceOf
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index fa4a35cfe9..d67ec0931c 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -17,7 +17,7 @@ abstract class TreeInfo {
val global: SymbolTable
import global._
- import definitions.{ isVarArgsList, isCastSymbol, ThrowableClass, TupleClass }
+ import definitions.{ isVarArgsList, isCastSymbol, ThrowableClass, TupleClass, MacroContextClass, MacroContextPrefixType }
/* Does not seem to be used. Not sure what it does anyway.
def isOwnerDefinition(tree: Tree): Boolean = tree match {
@@ -525,20 +525,18 @@ abstract class TreeInfo {
*/
def noPredefImportForUnit(body: Tree) = {
// Top-level definition whose leading imports include Predef.
- def containsLeadingPredefImport(defs: List[Tree]): Boolean = defs match {
- case PackageDef(_, defs1) :: _ => containsLeadingPredefImport(defs1)
- case Import(expr, _) :: rest => isReferenceToPredef(expr) || containsLeadingPredefImport(rest)
- case _ => false
+ def isLeadingPredefImport(defn: Tree): Boolean = defn match {
+ case PackageDef(_, defs1) => defs1 exists isLeadingPredefImport
+ case Import(expr, _) => isReferenceToPredef(expr)
+ case _ => false
}
-
// Compilation unit is class or object 'name' in package 'scala'
def isUnitInScala(tree: Tree, name: Name) = tree match {
case PackageDef(Ident(nme.scala_), defs) => firstDefinesClassOrObject(defs, name)
case _ => false
}
- ( isUnitInScala(body, nme.Predef)
- || containsLeadingPredefImport(List(body)))
+ isUnitInScala(body, nme.Predef) || isLeadingPredefImport(body)
}
def isAbsTypeDef(tree: Tree) = tree match {
@@ -595,4 +593,23 @@ abstract class TreeInfo {
object DynamicUpdate extends DynamicApplicationExtractor(_ == nme.updateDynamic)
object DynamicApplication extends DynamicApplicationExtractor(isApplyDynamicName)
object DynamicApplicationNamed extends DynamicApplicationExtractor(_ == nme.applyDynamicNamed)
+
+ object MacroImplReference {
+ private def refPart(tree: Tree): Tree = tree match {
+ case TypeApply(fun, _) => refPart(fun)
+ case ref: RefTree => ref
+ case _ => EmptyTree
+ }
+
+ def unapply(tree: Tree) = refPart(tree) match {
+ case ref: RefTree => Some((ref.qualifier.symbol, ref.symbol, typeArguments(tree)))
+ case _ => None
+ }
+ }
+
+ def stripOffPrefixTypeRefinement(tpe: Type): Type =
+ tpe.dealias match {
+ case RefinedType(List(tpe), Scope(sym)) if tpe == MacroContextClass.tpe && sym.allOverriddenSymbols.contains(MacroContextPrefixType) => tpe
+ case _ => tpe
+ }
}
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index 94d51b7455..b21a28eea8 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -230,6 +230,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
}
case object EmptyTree extends TermTree {
+ val asList = List(this)
super.tpe_=(NoType)
override def tpe_=(t: Type) =
if (t != NoType) throw new UnsupportedOperationException("tpe_=("+t+") inapplicable for <empty>")
@@ -290,7 +291,10 @@ trait Trees extends api.Trees { self: SymbolTable =>
object LabelDef extends LabelDefExtractor
case class ImportSelector(name: Name, namePos: Int, rename: Name, renamePos: Int) extends ImportSelectorApi
- object ImportSelector extends ImportSelectorExtractor
+ object ImportSelector extends ImportSelectorExtractor {
+ val wild = ImportSelector(nme.WILDCARD, -1, null, -1)
+ val wildList = List(wild)
+ }
case class Import(expr: Tree, selectors: List[ImportSelector])
extends SymTree with ImportApi
@@ -979,12 +983,7 @@ trait Trees extends api.Trees { self: SymbolTable =>
*/
def New(tpt: Tree, argss: List[List[Tree]]): Tree = argss match {
case Nil => ApplyConstructor(tpt, Nil)
- case xs :: rest => {
- def mkApply(fun: Tree, args: List[Tree]) = Apply(fun, args)
- rest.foldLeft(ApplyConstructor(tpt, xs): Tree)(mkApply)
- // [Eugene++] no longer compiles after I moved the `Apply` case class here
- // rest.foldLeft(ApplyConstructor(tpt, xs): Tree)(Apply)
- }
+ case xs :: rest => rest.foldLeft(ApplyConstructor(tpt, xs): Tree)(Apply.apply)
}
/** 0-1 argument list new, based on a type.
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 969cbf2456..6e7c06d0da 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -265,14 +265,14 @@ trait Types extends api.Types { self: SymbolTable =>
def declarations = decls
def typeArguments = typeArgs
def erasure = this match {
- case ConstantType(value) => widen.erasure // [Eugene to Martin] constant types are unaffected by erasure. weird.
+ case ConstantType(value) => widen.erasure
case _ =>
var result: Type = transformedType(this)
result = result.normalize match { // necessary to deal with erasures of HK types, typeConstructor won't work
case PolyType(undets, underlying) => existentialAbstraction(undets, underlying) // we don't want undets in the result
case _ => result
}
- // [Eugene] erasure screws up all ThisTypes for modules into PackageTypeRefs
+ // erasure screws up all ThisTypes for modules into PackageTypeRefs
// we need to unscrew them, or certain typechecks will fail mysteriously
// http://groups.google.com/group/scala-internals/browse_thread/thread/6d3277ae21b6d581
result = result.map(tpe => tpe match {
@@ -284,7 +284,6 @@ trait Types extends api.Types { self: SymbolTable =>
def substituteSymbols(from: List[Symbol], to: List[Symbol]): Type = substSym(from, to)
def substituteTypes(from: List[Symbol], to: List[Type]): Type = subst(from, to)
- // [Eugene] to be discussed and refactored
def isConcrete = {
def notConcreteSym(sym: Symbol) =
sym.isAbstractType && !sym.isExistential
@@ -304,11 +303,8 @@ trait Types extends api.Types { self: SymbolTable =>
!notConcreteTpe(this)
}
- // [Eugene] is this comprehensive?
- // the only thingies that we want to splice are: 1) type parameters, 2) type members
+ // the only thingies that we want to splice are: 1) type parameters, 2) abstract type members
// the thingies that we don't want to splice are: 1) concrete types (obviously), 2) existential skolems
- // this check seems to cover them all, right?
- // todo. after we discuss this, move the check to subclasses
def isSpliceable = {
this.isInstanceOf[TypeRef] && typeSymbol.isAbstractType && !typeSymbol.isExistential
}
@@ -446,7 +442,7 @@ trait Types extends api.Types { self: SymbolTable =>
if (phase.erasedTypes) this
else {
val cowner = commonOwner(this)
- refinedType(List(this), cowner, EmptyScope, cowner.pos).narrow
+ refinedType(this :: Nil, cowner, EmptyScope, cowner.pos).narrow
}
/** For a TypeBounds type, itself;
@@ -1011,7 +1007,7 @@ trait Types extends api.Types { self: SymbolTable =>
if (!e.sym.hasFlag(excludedFlags)) {
if (sym == NoSymbol) sym = e.sym
else {
- if (alts.isEmpty) alts = List(sym)
+ if (alts.isEmpty) alts = sym :: Nil
alts = e.sym :: alts
}
}
@@ -3719,10 +3715,11 @@ trait Types extends api.Types { self: SymbolTable =>
case TypeRef(_, SingletonClass, _) =>
AnyClass.tpe
case tp1 @ RefinedType(parents, decls) =>
- var parents1 = parents filter (_.typeSymbol != SingletonClass)
- if (parents1.isEmpty) parents1 = List(AnyClass.tpe)
- if (parents1.tail.isEmpty && decls.isEmpty) mapOver(parents1.head)
- else mapOver(copyRefinedType(tp1, parents1, decls))
+ parents filter (_.typeSymbol != SingletonClass) match {
+ case Nil => AnyClass.tpe
+ case p :: Nil if decls.isEmpty => mapOver(p)
+ case ps => mapOver(copyRefinedType(tp1, ps, decls))
+ }
case tp1 =>
mapOver(tp1)
}
@@ -4587,10 +4584,12 @@ trait Types extends api.Types { self: SymbolTable =>
tp match {
case TypeRef(pre, sym, args) if pre ne NoPrefix =>
val newSym = subst(sym, from, to)
+ // mapOver takes care of subst'ing in args
+ mapOver ( if (sym eq newSym) tp else copyTypeRef(tp, pre, newSym, args) )
// assert(newSym.typeParams.length == sym.typeParams.length, "typars mismatch in SubstSymMap: "+(sym, sym.typeParams, newSym, newSym.typeParams))
- mapOver(copyTypeRef(tp, pre, newSym, args)) // mapOver takes care of subst'ing in args
case SingleType(pre, sym) if pre ne NoPrefix =>
- mapOver(singleType(pre, subst(sym, from, to)))
+ val newSym = subst(sym, from, to)
+ mapOver( if (sym eq newSym) tp else singleType(pre, newSym) )
case _ =>
super.apply(tp)
}
@@ -5629,6 +5628,7 @@ trait Types extends api.Types { self: SymbolTable =>
false
}
+ @deprecated("The compiler doesn't use this so you shouldn't either - it will be removed", "2.10.0")
def instTypeVar(tp: Type): Type = tp match {
case TypeRef(pre, sym, args) =>
copyTypeRef(tp, instTypeVar(pre), sym, args)
diff --git a/src/reflect/scala/reflect/internal/util/Collections.scala b/src/reflect/scala/reflect/internal/util/Collections.scala
index 2ac0e64edd..14b5d3003d 100644
--- a/src/reflect/scala/reflect/internal/util/Collections.scala
+++ b/src/reflect/scala/reflect/internal/util/Collections.scala
@@ -69,7 +69,7 @@ trait Collections {
}
lb.toList
}
-
+
final def flatCollect[A, B](elems: List[A])(pf: PartialFunction[A, Traversable[B]]): List[B] = {
val lb = new ListBuffer[B]
for (x <- elems ; if pf isDefinedAt x)
@@ -104,7 +104,7 @@ trait Collections {
index += 1
}
}
-
+
// @inline
final def findOrElse[A](xs: TraversableOnce[A])(p: A => Boolean)(orElse: => A): A = {
xs find p getOrElse orElse
diff --git a/src/reflect/scala/reflect/macros/Infrastructure.scala b/src/reflect/scala/reflect/macros/Infrastructure.scala
index 5ae2c08265..a8a8b814b1 100644
--- a/src/reflect/scala/reflect/macros/Infrastructure.scala
+++ b/src/reflect/scala/reflect/macros/Infrastructure.scala
@@ -46,10 +46,6 @@ trait Infrastructure {
* val valueOfX = toolBox.runExpr(imported).asInstanceOf[T]
* ...
* }
- *
- * // [Eugene++] using this guy will tremendously slow down the compilation
- * // https://twitter.com/xeno_by/status/201248317831774208
- * // todo. we need to address this somehow
*/
def libraryClassLoader: ClassLoader
diff --git a/src/reflect/scala/reflect/macros/Settings.scala b/src/reflect/scala/reflect/macros/Settings.scala
index 8d166056c3..a2cdb4c8e1 100644
--- a/src/reflect/scala/reflect/macros/Settings.scala
+++ b/src/reflect/scala/reflect/macros/Settings.scala
@@ -12,14 +12,10 @@ trait Settings {
/** Exposes current compiler settings as a list of options.
* Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
*/
- // [Eugene] ugly? yes, but I don't really fancy copy/pasting all our settings here and keep it synchronized at all times
- // why all settings? because macros need to be in full control of the stuff going on
- // maybe later we can implement a gettable/settable list of important settings, but for now let's leave it like that
def compilerSettings: List[String]
/** Updates current compiler settings with an option string.
* Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
- * todo. http://groups.google.com/group/scala-internals/browse_thread/thread/07c18cff41f59203
*/
def setCompilerSettings(options: String): this.type
@@ -28,12 +24,12 @@ trait Settings {
*/
def setCompilerSettings(options: List[String]): this.type
- /** Temporary sets compiler settings to a given option string and executes a given closure.
+ /** Temporarily sets compiler settings to a given option string and executes a given closure.
* Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
*/
def withCompilerSettings[T](options: String)(op: => T): T
- /** Temporary sets compiler settings to a given list of options and executes a given closure.
+ /** Temporarily sets compiler settings to a given list of options and executes a given closure.
* Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
*/
def withCompilerSettings[T](options: List[String])(op: => T): T
diff --git a/src/reflect/scala/reflect/macros/TreeBuilder.scala b/src/reflect/scala/reflect/macros/TreeBuilder.scala
index 06f5caf68b..ca29194859 100644
--- a/src/reflect/scala/reflect/macros/TreeBuilder.scala
+++ b/src/reflect/scala/reflect/macros/TreeBuilder.scala
@@ -1,10 +1,6 @@
package scala.reflect
package macros
-// [Eugene] I added some stuff that was necessary for typetag materialization macros
-// but we should think it over and pick other generally useful stuff
-// same goes for tree traversers/transformers, type maps, etc
-// and once we expose all that, there's another question: how do we stay in sync?
abstract class TreeBuilder {
val global: Universe
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index 4ce2cda04a..967ac69148 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -88,7 +88,6 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
// ----------- Caching ------------------------------------------------------------------
- // [Eugene++ to Martin] not weak? why?
private val classCache = new TwoWayCache[jClass[_], ClassSymbol]
private val packageCache = new TwoWayCache[Package, ModuleSymbol]
private val methodCache = new TwoWayCache[jMethod, MethodSymbol]
@@ -659,43 +658,33 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
private def followStatic(clazz: Symbol, mods: Int) =
if (jModifier.isStatic(mods)) clazz.companionModule.moduleClass else clazz
- implicit class RichClass(jclazz: jClass[_]) {
- // [Eugene++] `jclazz.isLocalClass` doesn't work because of problems with `getSimpleName`
- // java.lang.Error: sOwner(class Test$A$1) has failed
- // Caused by: java.lang.InternalError: Malformed class name
- // at java.lang.Class.getSimpleName(Class.java:1133)
- // at java.lang.Class.isAnonymousClass(Class.java:1188)
- // at java.lang.Class.isLocalClass(Class.java:1199)
- // (see t5256c.scala for more details)
+ /** Methods which need to be treated with care
+ * because they either are getSimpleName or call getSimpleName:
+ *
+ * public String getSimpleName()
+ * public boolean isAnonymousClass()
+ * public boolean isLocalClass()
+ * public String getCanonicalName()
+ *
+ * A typical manifestation:
+ *
+ * // java.lang.Error: sOwner(class Test$A$1) has failed
+ * // Caused by: java.lang.InternalError: Malformed class name
+ * // at java.lang.Class.getSimpleName(Class.java:1133)
+ * // at java.lang.Class.isAnonymousClass(Class.java:1188)
+ * // at java.lang.Class.isLocalClass(Class.java:1199)
+ * // (see t5256c.scala for more details)
+ *
+ * TODO - find all such calls and wrap them.
+ * TODO - create mechanism to avoid the recurrence of unwrapped calls.
+ */
+ implicit class RichClass(jclazz: jClass[_]) {
+ // `jclazz.isLocalClass` doesn't work because of problems with `getSimpleName`
// hence we have to approximate by removing the `isAnonymousClass` check
// def isLocalClass0: Boolean = jclazz.isLocalClass
def isLocalClass0: Boolean = jclazz.getEnclosingMethod != null || jclazz.getEnclosingConstructor != null
}
- // [Eugene++] overflow from Paul's changes made concurrently with reflection refactoring
- // https://github.com/scala/scala/commit/90d2bee45b25844f809f8c5300aefcb1bfe9e336
- //
- // /** Methods which need to be wrapped because they either are getSimpleName
- // * or call getSimpleName:
- // *
- // * public String getSimpleName()
- // * public boolean isAnonymousClass()
- // * public boolean isLocalClass()
- // * public boolean isMemberClass()
- // * public String getCanonicalName()
- // *
- // * TODO - find all such calls and wrap them.
- // * TODO - create mechanism to avoid the recurrence of unwrapped calls.
- // */
- // private def wrapClassCheck[T](alt: T)(body: => T): T =
- // try body catch { case x: InternalError if x.getMessage == "Malformed class name" => alt }
-
- // private def wrapIsLocalClass(clazz: jClass[_]): Boolean =
- // wrapClassCheck(false)(clazz.isLocalClass)
-
- // private def wrapGetSimpleName(clazz: jClass[_]): String =
- // wrapClassCheck("")(clazz.getSimpleName)
-
/**
* The Scala owner of the Scala class corresponding to the Java class `jclazz`
*/
@@ -1208,7 +1197,7 @@ trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse { self: Sym
override def missingHook(owner: Symbol, name: Name): Symbol = {
if (owner.hasPackageFlag) {
val mirror = mirrorThatLoaded(owner)
- // [Eugene++] this makes toolbox tests pass, but it's a mere workaround for SI-5865
+ // todo. this makes toolbox tests pass, but it's a mere workaround for SI-5865
// assert((owner.info decl name) == NoSymbol, s"already exists: $owner . $name")
if (owner.isRootSymbol && mirror.tryJavaClass(name.toString).isDefined)
return mirror.EmptyPackageClass.info decl name
diff --git a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala
index 95c1bc861b..6bfafe6af1 100644
--- a/src/reflect/scala/reflect/runtime/SymbolLoaders.scala
+++ b/src/reflect/scala/reflect/runtime/SymbolLoaders.scala
@@ -61,10 +61,8 @@ trait SymbolLoaders { self: SymbolTable =>
assert(!(name.toString endsWith "[]"), name)
val clazz = owner.newClass(name)
val module = owner.newModule(name.toTermName)
- // [Eugene++] am I doing this right?
- // todo: drop condition, see what goes wrong
- // [Eugene++ to Martin] test/files/run/t5256g and test/files/run/t5256h will crash
- // reflection meeting verdict: need to enter the symbols into the first symbol in the owner chain that has a non-empty scope
+ // without this check test/files/run/t5256g and test/files/run/t5256h will crash
+ // todo. reflection meeting verdict: need to enter the symbols into the first symbol in the owner chain that has a non-empty scope
if (owner.info.decls != EmptyScope) {
owner.info.decls enter clazz
owner.info.decls enter module
diff --git a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala
index 907c0dd369..1a17dd12d2 100644
--- a/src/reflect/scala/reflect/runtime/SynchronizedOps.scala
+++ b/src/reflect/scala/reflect/runtime/SynchronizedOps.scala
@@ -1,6 +1,7 @@
package scala.reflect
package runtime
+// SI-6240: test thread-safety, make trees synchronized as well
trait SynchronizedOps extends internal.SymbolTable
with SynchronizedSymbols
with SynchronizedTypes { self: SymbolTable =>
diff --git a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala
index c65357b652..12db7a7bf9 100644
--- a/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala
+++ b/src/reflect/scala/reflect/runtime/SynchronizedSymbols.scala
@@ -134,8 +134,6 @@ trait SynchronizedSymbols extends internal.Symbols { self: SymbolTable =>
trait SynchronizedModuleClassSymbol extends ModuleClassSymbol with SynchronizedClassSymbol {
override def sourceModule = synchronized { super.sourceModule }
- // [Eugene++ to Martin] doesn't override anything. no longer necessary?
- // def sourceModule_=(module: ModuleSymbol) = synchronized { super.sourceModule_=(module) }
override def implicitMembers: Scope = synchronized { super.implicitMembers }
}
}
diff --git a/src/reflect/scala/reflect/runtime/package.scala b/src/reflect/scala/reflect/runtime/package.scala
index d00094c0c1..ccdea3e82d 100644
--- a/src/reflect/scala/reflect/runtime/package.scala
+++ b/src/reflect/scala/reflect/runtime/package.scala
@@ -5,8 +5,6 @@ package object runtime {
// type is api.JavaUniverse because we only want to expose the `scala.reflect.api.*` subset of reflection
lazy val universe: api.JavaUniverse = new runtime.JavaUniverse
- // [Eugene++ to Martin] removed `mirrorOfLoader`, because one can use `universe.runtimeMirror` instead
-
// implementation magically hardwired to the `currentMirror` method below
def currentMirror: universe.Mirror = ??? // macro
}
diff --git a/src/reflect/scala/tools/nsc/io/Path.scala b/src/reflect/scala/tools/nsc/io/Path.scala
index bfad4b93c5..e965c70111 100644
--- a/src/reflect/scala/tools/nsc/io/Path.scala
+++ b/src/reflect/scala/tools/nsc/io/Path.scala
@@ -43,8 +43,6 @@ object Path {
if (i < 0) ""
else name.substring(i + 1).toLowerCase
}
- // [Eugene++] I hope that noone relied on this method
-// def isJarOrZip(f: Path, examineFile: Boolean = true) = Jar.isJarOrZip(f, examineFile)
// not certain these won't be problematic, but looks good so far
implicit def string2path(s: String): Path = apply(s)
diff --git a/src/scalap/scala/tools/scalap/Main.scala b/src/scalap/scala/tools/scalap/Main.scala
index a8a9c65f63..49c272cc28 100644
--- a/src/scalap/scala/tools/scalap/Main.scala
+++ b/src/scalap/scala/tools/scalap/Main.scala
@@ -10,10 +10,10 @@ package scala.tools.scalap
import java.io.{ PrintStream, OutputStreamWriter, ByteArrayOutputStream }
import scala.reflect.NameTransformer
import scalax.rules.scalasig._
-import tools.nsc.util.{ ClassPath, JavaClassPath }
-import tools.util.PathResolver
+import scala.tools.nsc.util.{ ClassPath, JavaClassPath }
+import scala.tools.util.PathResolver
import ClassPath.DefaultJavaContext
-import tools.nsc.io.{ PlainFile, AbstractFile }
+import scala.tools.nsc.io.{ PlainFile, AbstractFile }
/**The main object used to execute scalap on the command-line.
*