summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-09-28 06:55:49 -0700
committerPaul Phillips <paulp@improving.org>2012-09-28 07:19:01 -0700
commit886c4061222773d76f3ee3f4ff1469f9d4a48eaf (patch)
tree70b13842e325bafd48e5494c844078f35b02f5b7 /src
parent41f37bc428a309b9766f545da0179f270ea01d77 (diff)
parent57db28c55c3610f508b07940f7077cb73932418f (diff)
downloadscala-886c4061222773d76f3ee3f4ff1469f9d4a48eaf.tar.gz
scala-886c4061222773d76f3ee3f4ff1469f9d4a48eaf.tar.bz2
scala-886c4061222773d76f3ee3f4ff1469f9d4a48eaf.zip
Merge branch '2.10.x' into 210-merge
* 2.10.x: (37 commits) Added logic and tests for unchecked refinements. Moved isNonRefinementClassType somewhere logical. Moved two tests to less breaky locations. Nailed down the "impossible match" logic. Finish docs for string interpolation. moves Context.ParseError outside the cake revives macros.Infrastructure moves Context.runtimeUniverse to TreeBuild.mkRuntimeUniverseRef a more precise type for Context.mirror gets rid of macros.Infrastructure simplifies Context.Run and Context.CompilationUnit exposes Position.source as SourceFile removes extraneous stuff from macros.Infrastructure merges macros.CapturedVariables into macros.Universe merges macros.Exprs and macros.TypeTags into Context removes front ends from scala-reflect.jar PositionApi => Position hides BuildUtils from Scaladoc MirrorOf => Mirror docs.pre-lib now checks for mods in reflect ... Conflicts: test/files/neg/t4302.check test/files/neg/unchecked.check test/files/neg/unchecked2.check
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Aliases.scala5
-rw-r--r--src/compiler/scala/reflect/macros/runtime/CapturedVariables.scala15
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Context.scala8
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Enclosures.scala3
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Evals.scala2
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Exprs.scala8
-rw-r--r--src/compiler/scala/reflect/macros/runtime/FrontEnds.scala26
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Infrastructure.scala32
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Parsers.scala5
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Reifiers.scala2
-rw-r--r--src/compiler/scala/reflect/macros/runtime/Settings.scala35
-rw-r--r--src/compiler/scala/reflect/macros/runtime/TypeTags.scala9
-rw-r--r--src/compiler/scala/reflect/reify/Reifier.scala2
-rw-r--r--src/compiler/scala/reflect/reify/utils/Extractors.scala6
-rw-r--r--src/compiler/scala/reflect/reify/utils/NodePrinters.scala2
-rw-r--r--src/compiler/scala/tools/nsc/CompilationUnits.scala2
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/matching/Patterns.scala12
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala5
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Checkable.scala284
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Infer.scala97
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Modes.scala6
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala24
-rw-r--r--src/compiler/scala/tools/reflect/FrontEnd.scala50
-rw-r--r--src/compiler/scala/tools/reflect/FrontEnds.scala88
-rw-r--r--src/compiler/scala/tools/reflect/StdTags.scala8
-rw-r--r--src/compiler/scala/tools/reflect/ToolBox.scala3
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala2
-rw-r--r--src/compiler/scala/tools/reflect/package.scala90
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala61
-rw-r--r--src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala91
-rw-r--r--src/library/scala/StringContext.scala63
-rw-r--r--src/reflect/scala/reflect/api/BuildUtils.scala2
-rw-r--r--src/reflect/scala/reflect/api/Exprs.scala12
-rw-r--r--src/reflect/scala/reflect/api/FrontEnds.scala70
-rw-r--r--src/reflect/scala/reflect/api/JavaUniverse.scala4
-rw-r--r--src/reflect/scala/reflect/api/Mirror.scala (renamed from src/reflect/scala/reflect/api/MirrorOf.scala)4
-rw-r--r--src/reflect/scala/reflect/api/Mirrors.scala10
-rw-r--r--src/reflect/scala/reflect/api/Position.scala167
-rw-r--r--src/reflect/scala/reflect/api/Positions.scala167
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala10
-rw-r--r--src/reflect/scala/reflect/api/TreeCreator.scala2
-rw-r--r--src/reflect/scala/reflect/api/TypeCreator.scala2
-rw-r--r--src/reflect/scala/reflect/api/TypeTags.scala26
-rw-r--r--src/reflect/scala/reflect/internal/AnnotationCheckers.scala26
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Mirrors.scala2
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala4
-rw-r--r--src/reflect/scala/reflect/internal/StdCreators.scala8
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala10
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala10
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala7
-rw-r--r--src/reflect/scala/reflect/internal/package.scala6
-rw-r--r--src/reflect/scala/reflect/internal/util/Collections.scala14
-rw-r--r--src/reflect/scala/reflect/internal/util/Position.scala13
-rw-r--r--src/reflect/scala/reflect/macros/Aliases.scala7
-rw-r--r--src/reflect/scala/reflect/macros/CapturedVariables.scala21
-rw-r--r--src/reflect/scala/reflect/macros/Context.scala8
-rw-r--r--src/reflect/scala/reflect/macros/Enclosures.scala4
-rw-r--r--src/reflect/scala/reflect/macros/Exprs.scala8
-rw-r--r--src/reflect/scala/reflect/macros/FrontEnds.scala14
-rw-r--r--src/reflect/scala/reflect/macros/Infrastructure.scala79
-rw-r--r--src/reflect/scala/reflect/macros/Parsers.scala14
-rw-r--r--src/reflect/scala/reflect/macros/Reifiers.scala13
-rw-r--r--src/reflect/scala/reflect/macros/Settings.scala36
-rw-r--r--src/reflect/scala/reflect/macros/TreeBuilder.scala3
-rw-r--r--src/reflect/scala/reflect/macros/TypeTags.scala9
-rw-r--r--src/reflect/scala/reflect/macros/Universe.scala48
-rw-r--r--src/reflect/scala/reflect/macros/package.scala6
70 files changed, 1025 insertions, 873 deletions
diff --git a/src/compiler/scala/reflect/macros/runtime/Aliases.scala b/src/compiler/scala/reflect/macros/runtime/Aliases.scala
index 30e72997f7..ff870e728e 100644
--- a/src/compiler/scala/reflect/macros/runtime/Aliases.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Aliases.scala
@@ -10,17 +10,20 @@ trait Aliases {
override type TermName = universe.TermName
override type TypeName = universe.TypeName
override type Tree = universe.Tree
- // override type Position = universe.Position
+ override type Position = universe.Position
override type Scope = universe.Scope
override type Modifiers = universe.Modifiers
override type Expr[+T] = universe.Expr[T]
override val Expr = universe.Expr
+ def Expr[T: WeakTypeTag](tree: Tree): Expr[T] = universe.Expr[T](mirror, universe.FixedMirrorTreeCreator(mirror, tree))
override type WeakTypeTag[T] = universe.WeakTypeTag[T]
override type TypeTag[T] = universe.TypeTag[T]
override val WeakTypeTag = universe.WeakTypeTag
override val TypeTag = universe.TypeTag
+ def WeakTypeTag[T](tpe: Type): WeakTypeTag[T] = universe.WeakTypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe))
+ def TypeTag[T](tpe: Type): TypeTag[T] = universe.TypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe))
override def weakTypeTag[T](implicit attag: WeakTypeTag[T]) = attag
override def typeTag[T](implicit ttag: TypeTag[T]) = ttag
override def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = attag.tpe
diff --git a/src/compiler/scala/reflect/macros/runtime/CapturedVariables.scala b/src/compiler/scala/reflect/macros/runtime/CapturedVariables.scala
deleted file mode 100644
index 78fb7100b0..0000000000
--- a/src/compiler/scala/reflect/macros/runtime/CapturedVariables.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-package scala.reflect.macros
-package runtime
-
-trait CapturedVariables {
- self: Context =>
-
- import mirror._
- import universe._
-
- def captureVariable(vble: Symbol): Unit = universe.captureVariable(vble)
-
- def referenceCapturedVariable(vble: Symbol): Tree = universe.referenceCapturedVariable(vble)
-
- def capturedVariableType(vble: Symbol): Type = universe.capturedVariableType(vble)
-} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/macros/runtime/Context.scala b/src/compiler/scala/reflect/macros/runtime/Context.scala
index 8bbfef44a3..8e8b0fcea1 100644
--- a/src/compiler/scala/reflect/macros/runtime/Context.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Context.scala
@@ -5,24 +5,20 @@ import scala.tools.nsc.Global
abstract class Context extends scala.reflect.macros.Context
with Aliases
- with CapturedVariables
- with Infrastructure
with Enclosures
with Names
with Reifiers
with FrontEnds
- with Settings
+ with Infrastructure
with Typers
with Parsers
- with Exprs
- with TypeTags
with Evals
with ExprUtils
with Traces {
val universe: Global
- val mirror: MirrorOf[universe.type] = universe.rootMirror
+ val mirror: universe.Mirror = universe.rootMirror
val callsiteTyper: universe.analyzer.Typer
diff --git a/src/compiler/scala/reflect/macros/runtime/Enclosures.scala b/src/compiler/scala/reflect/macros/runtime/Enclosures.scala
index b5c988ca83..be5f2dbe83 100644
--- a/src/compiler/scala/reflect/macros/runtime/Enclosures.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Enclosures.scala
@@ -19,5 +19,6 @@ trait Enclosures {
val enclosingMacros: List[Context] = this :: universe.analyzer.openMacros // include self
val enclosingMethod: Tree = site.enclMethod.tree
val enclosingPosition: Position = if (enclPoses.isEmpty) NoPosition else enclPoses.head.pos
- val enclosingUnit: CompilationUnit = currentRun.currentUnit
+ val enclosingUnit: CompilationUnit = universe.currentRun.currentUnit
+ val enclosingRun: Run = universe.currentRun
}
diff --git a/src/compiler/scala/reflect/macros/runtime/Evals.scala b/src/compiler/scala/reflect/macros/runtime/Evals.scala
index acafeb5b02..1f7b5f2ff1 100644
--- a/src/compiler/scala/reflect/macros/runtime/Evals.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Evals.scala
@@ -7,7 +7,7 @@ import scala.tools.reflect.ToolBox
trait Evals {
self: Context =>
- private lazy val evalMirror = ru.runtimeMirror(libraryClassLoader)
+ private lazy val evalMirror = ru.runtimeMirror(universe.analyzer.macroClassloader)
private lazy val evalToolBox = evalMirror.mkToolBox()
private lazy val evalImporter = ru.mkImporter(universe).asInstanceOf[ru.Importer { val from: universe.type }]
diff --git a/src/compiler/scala/reflect/macros/runtime/Exprs.scala b/src/compiler/scala/reflect/macros/runtime/Exprs.scala
deleted file mode 100644
index ebf8fa2b96..0000000000
--- a/src/compiler/scala/reflect/macros/runtime/Exprs.scala
+++ /dev/null
@@ -1,8 +0,0 @@
-package scala.reflect.macros
-package runtime
-
-trait Exprs {
- self: Context =>
-
- def Expr[T: WeakTypeTag](tree: Tree): Expr[T] = universe.Expr[T](mirror, universe.FixedMirrorTreeCreator(mirror, tree))
-}
diff --git a/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala b/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala
index 9f328eb82b..a6a198e1b4 100644
--- a/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala
+++ b/src/compiler/scala/reflect/macros/runtime/FrontEnds.scala
@@ -1,28 +1,9 @@
package scala.reflect.macros
package runtime
-trait FrontEnds extends scala.tools.reflect.FrontEnds {
+trait FrontEnds {
self: Context =>
- import universe._
- import mirror._
-
- override type Position = universe.Position
-
- def frontEnd: FrontEnd = wrapReporter(universe.reporter)
-
- def setFrontEnd(frontEnd: FrontEnd): this.type = {
- universe.reporter = wrapFrontEnd(frontEnd)
- this
- }
-
- def withFrontEnd[T](frontEnd: FrontEnd)(op: => T): T = {
- val old = universe.reporter
- setFrontEnd(frontEnd)
- try op
- finally universe.reporter = old
- }
-
def echo(pos: Position, msg: String): Unit = universe.reporter.echo(pos, msg)
def info(pos: Position, msg: String, force: Boolean): Unit = universe.reporter.info(pos, msg, force)
@@ -36,9 +17,4 @@ trait FrontEnds extends scala.tools.reflect.FrontEnds {
def error(pos: Position, msg: String): Unit = callsiteTyper.context.error(pos, msg)
def abort(pos: Position, msg: String): Nothing = throw new AbortMacroException(pos, msg)
-
- def interactive(): Unit = universe.reporter match {
- case reporter: scala.tools.nsc.reporters.AbstractReporter => reporter.displayPrompt()
- case _ => ()
- }
}
diff --git a/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala b/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala
index 7157dbeaa2..7781693822 100644
--- a/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Infrastructure.scala
@@ -1,36 +1,16 @@
package scala.reflect.macros
package runtime
-import scala.tools.nsc.util.ScalaClassLoader
-
trait Infrastructure {
self: Context =>
- val forJVM: Boolean = universe.forJVM
-
- val forMSIL: Boolean = universe.forMSIL
-
- val forInteractive: Boolean = universe.forInteractive
-
- val forScaladoc: Boolean = universe.forScaladoc
-
- val currentRun: Run = universe.currentRun
-
- val libraryClassPath: List[java.net.URL] = universe.classPath.asURLs
-
- lazy val libraryClassLoader: ClassLoader = universe.analyzer.macroClassloader
-
- type Run = universe.Run
-
- object Run extends RunExtractor {
- def unapply(run: Run): Option[(CompilationUnit, List[CompilationUnit])] = Some((run.currentUnit, run.units.toList))
+ def settings: List[String] = {
+ val us = universe.settings
+ import us._
+ userSetSettings collectFirst { case x: MultiStringSetting if x.name == XmacroSettings.name => x.value } getOrElse Nil
}
- type CompilationUnit = universe.CompilationUnit
-
- object CompilationUnit extends CompilationUnitExtractor {
- def unapply(compilationUnit: CompilationUnit): Option[(java.io.File, Array[Char], Tree)] = Some((compilationUnit.source.file.file, compilationUnit.source.content, compilationUnit.body))
- }
+ def compilerSettings: List[String] = universe.settings.recreateArgs
- val currentMacro: Symbol = expandee.symbol
+ def classPath: List[java.net.URL] = global.classPath.asURLs
}
diff --git a/src/compiler/scala/reflect/macros/runtime/Parsers.scala b/src/compiler/scala/reflect/macros/runtime/Parsers.scala
index 5096526fdb..ab9b94ec9f 100644
--- a/src/compiler/scala/reflect/macros/runtime/Parsers.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Parsers.scala
@@ -10,6 +10,7 @@ trait Parsers {
def parse(code: String): Tree =
// todo. provide decent implementation
+ // see `Typers.typedUseCase` for details
try {
import scala.reflect.runtime.{universe => ru}
val parsed = ru.rootMirror.mkToolBox().parse(code)
@@ -17,9 +18,7 @@ trait Parsers {
importer.importTree(parsed)
} catch {
case ToolBoxError(msg, cause) =>
+ // todo. provide a position
throw new ParseError(universe.NoPosition, msg)
}
-
- case class ParseError(val pos: Position, val msg: String) extends Throwable(msg)
- object ParseError extends ParseErrorExtractor
}
diff --git a/src/compiler/scala/reflect/macros/runtime/Reifiers.scala b/src/compiler/scala/reflect/macros/runtime/Reifiers.scala
index f15a7ad502..9e11e5e26d 100644
--- a/src/compiler/scala/reflect/macros/runtime/Reifiers.scala
+++ b/src/compiler/scala/reflect/macros/runtime/Reifiers.scala
@@ -13,8 +13,6 @@ trait Reifiers {
import universe._
import definitions._
- lazy val runtimeUniverse: Tree = gen.mkRuntimeUniverseRef
-
def reifyTree(universe: Tree, mirror: Tree, tree: Tree): Tree = {
assert(ExprClass != NoSymbol)
val result = scala.reflect.reify.`package`.reifyTree(self.universe)(callsiteTyper, universe, mirror, tree)
diff --git a/src/compiler/scala/reflect/macros/runtime/Settings.scala b/src/compiler/scala/reflect/macros/runtime/Settings.scala
deleted file mode 100644
index e9d9a17b81..0000000000
--- a/src/compiler/scala/reflect/macros/runtime/Settings.scala
+++ /dev/null
@@ -1,35 +0,0 @@
-package scala.reflect.macros
-package runtime
-
-trait Settings {
- self: Context =>
-
- def settings: List[String] = {
- val us = universe.settings
- import us._
- userSetSettings collectFirst { case x: MultiStringSetting if x.name == XmacroSettings.name => x.value } getOrElse Nil
- }
-
- def compilerSettings: List[String] = universe.settings.recreateArgs
-
- def setCompilerSettings(options: String): this.type =
- // SI-5925: doesn't work with arguments that contains whitespaces
- setCompilerSettings(options.split(" ").toList)
-
- def setCompilerSettings(options: List[String]): this.type = {
- val settings = new scala.tools.nsc.Settings(_ => ())
- settings.copyInto(universe.settings)
- this
- }
-
- def withCompilerSettings[T](options: String)(op: => T): T =
- // SI-5925: doesn't work with arguments that contains whitespaces
- withCompilerSettings(options.split(" ").toList)(op)
-
- def withCompilerSettings[T](options: List[String])(op: => T): T = {
- val old = options
- setCompilerSettings(options)
- try op
- finally setCompilerSettings(old)
- }
-}
diff --git a/src/compiler/scala/reflect/macros/runtime/TypeTags.scala b/src/compiler/scala/reflect/macros/runtime/TypeTags.scala
deleted file mode 100644
index 19b60159de..0000000000
--- a/src/compiler/scala/reflect/macros/runtime/TypeTags.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-package scala.reflect.macros
-package runtime
-
-trait TypeTags {
- self: Context =>
-
- def WeakTypeTag[T](tpe: Type): WeakTypeTag[T] = universe.WeakTypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe))
- def TypeTag[T](tpe: Type): TypeTag[T] = universe.TypeTag[T](mirror, universe.FixedMirrorTypeCreator(mirror, tpe))
-}
diff --git a/src/compiler/scala/reflect/reify/Reifier.scala b/src/compiler/scala/reflect/reify/Reifier.scala
index 2c0d41e2a9..5d3ac8cde0 100644
--- a/src/compiler/scala/reflect/reify/Reifier.scala
+++ b/src/compiler/scala/reflect/reify/Reifier.scala
@@ -108,7 +108,7 @@ abstract class Reifier extends States
// needs to be solved some day
// maybe try `resetLocalAttrs` once the dust settles
var importantSymbols = Set[Symbol](
- NothingClass, AnyClass, SingletonClass, PredefModule, ScalaRunTimeModule, TypeCreatorClass, TreeCreatorClass, MirrorOfClass,
+ NothingClass, AnyClass, SingletonClass, PredefModule, ScalaRunTimeModule, TypeCreatorClass, TreeCreatorClass, MirrorClass,
ApiUniverseClass, JavaUniverseClass, ReflectRuntimePackage, ReflectRuntimeCurrentMirror)
importantSymbols ++= importantSymbols map (_.companionSymbol)
importantSymbols ++= importantSymbols map (_.moduleClass)
diff --git a/src/compiler/scala/reflect/reify/utils/Extractors.scala b/src/compiler/scala/reflect/reify/utils/Extractors.scala
index 91cccaee99..b7206eda0e 100644
--- a/src/compiler/scala/reflect/reify/utils/Extractors.scala
+++ b/src/compiler/scala/reflect/reify/utils/Extractors.scala
@@ -19,7 +19,7 @@ trait Extractors {
// $treecreator1.super.<init>();
// ()
// };
- // def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.MirrorOf[U]): U#Tree = {
+ // def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.Mirror[U]): U#Tree = {
// val $u: U = $m$untyped.universe;
// val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
// $u.Apply($u.Select($u.Select($u.build.This($m.staticPackage("scala.collection.immutable").moduleClass), $u.newTermName("List")), $u.newTermName("apply")), List($u.Literal($u.Constant(1)), $u.Literal($u.Constant(2))))
@@ -32,7 +32,7 @@ trait Extractors {
// $typecreator1.super.<init>();
// ()
// };
- // def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.MirrorOf[U]): U#Type = {
+ // def apply[U >: Nothing <: scala.reflect.api.Universe with Singleton]($m$untyped: scala.reflect.api.Mirror[U]): U#Type = {
// val $u: U = $m$untyped.universe;
// val $m: $u.Mirror = $m$untyped.asInstanceOf[$u.Mirror];
// $u.TypeRef($u.ThisType($m.staticPackage("scala.collection.immutable").moduleClass), $m.staticClass("scala.collection.immutable.List"), List($m.staticClass("scala.Int").toTypeConstructor))
@@ -81,7 +81,7 @@ trait Extractors {
DefDef(NoMods,
reifierName,
List(TypeDef(Modifiers(PARAM), tparamu, List(), TypeBoundsTree(Ident(NothingClass), CompoundTypeTree(Template(List(Ident(reifierUniverse), Ident(SingletonClass)), emptyValDef, List()))))),
- List(List(ValDef(Modifiers(PARAM), nme.MIRROR_UNTYPED, AppliedTypeTree(Ident(MirrorOfClass), List(Ident(tparamu))), EmptyTree))),
+ List(List(ValDef(Modifiers(PARAM), nme.MIRROR_UNTYPED, AppliedTypeTree(Ident(MirrorClass), List(Ident(tparamu))), EmptyTree))),
reifierTpt, reifierBody))))
Block(tpec, ApplyConstructor(Ident(tpec.name), List()))
}
diff --git a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
index f0480e0699..000e500c69 100644
--- a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
+++ b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
@@ -75,7 +75,7 @@ trait NodePrinters {
val printout = scala.collection.mutable.ListBuffer[String]();
printout += universe.trim
- if (mirrorIsUsed) printout += mirror.replace("MirrorOf[", "scala.reflect.api.MirrorOf[").trim
+ if (mirrorIsUsed) printout += mirror.replace("Mirror[", "scala.reflect.api.Mirror[").trim
val imports = scala.collection.mutable.ListBuffer[String]();
imports += nme.UNIVERSE_SHORT
// if (buildIsUsed) imports += nme.build
diff --git a/src/compiler/scala/tools/nsc/CompilationUnits.scala b/src/compiler/scala/tools/nsc/CompilationUnits.scala
index 6d3fd2e09e..5a2d5ef165 100644
--- a/src/compiler/scala/tools/nsc/CompilationUnits.scala
+++ b/src/compiler/scala/tools/nsc/CompilationUnits.scala
@@ -23,7 +23,7 @@ trait CompilationUnits { self: Global =>
/** One unit of compilation that has been submitted to the compiler.
* It typically corresponds to a single file of source code. It includes
* error-reporting hooks. */
- class CompilationUnit(val source: SourceFile) {
+ class CompilationUnit(val source: SourceFile) extends CompilationUnitContextApi {
/** the fresh name creator */
var fresh: FreshNameCreator = new FreshNameCreator.Default
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 9f7433796d..0252f9677c 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -1158,7 +1158,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
/** A Run is a single execution of the compiler on a sets of units
*/
- class Run {
+ class Run extends RunContextApi {
/** Have been running into too many init order issues with Run
* during erroneous conditions. Moved all these vals up to the
* top of the file so at least they're not trivially null.
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index d8dae0482b..072f4b9ef2 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -1750,7 +1750,7 @@ self =>
in.nextToken()
if (in.token == SUBTYPE || in.token == SUPERTYPE) wildcardType(start)
else atPos(start) { Bind(tpnme.WILDCARD, EmptyTree) }
- case IDENTIFIER if treeInfo.isVariableName(in.name) =>
+ case IDENTIFIER if nme.isVariableName(in.name) =>
atPos(start) { Bind(identForType(), EmptyTree) }
case _ =>
typ()
diff --git a/src/compiler/scala/tools/nsc/matching/Patterns.scala b/src/compiler/scala/tools/nsc/matching/Patterns.scala
index af77d3fe3f..40e520076a 100644
--- a/src/compiler/scala/tools/nsc/matching/Patterns.scala
+++ b/src/compiler/scala/tools/nsc/matching/Patterns.scala
@@ -21,7 +21,7 @@ trait Patterns extends ast.TreeDSL {
import definitions._
import CODE._
import Debug._
- import treeInfo.{ unbind, isStar, isVarPattern, isVariableName }
+ import treeInfo.{ unbind, isStar, isVarPattern }
type PatternMatch = MatchMatrix#PatternMatch
private type PatternVar = MatrixContext#PatternVar
@@ -366,7 +366,7 @@ trait Patterns extends ast.TreeDSL {
lazy val Select(qualifier, name) = select
def pathSegments = getPathSegments(tree)
def backticked: Option[String] = qualifier match {
- case _: This if isVariableName(name) => Some("`%s`".format(name))
+ case _: This if nme.isVariableName(name) => Some("`%s`".format(name))
case _ => None
}
override def covers(sym: Symbol) = newMatchesPattern(sym, tree.tpe)
@@ -388,11 +388,11 @@ trait Patterns extends ast.TreeDSL {
lazy val UnApply(unfn, args) = tree
lazy val Apply(fn, _) = unfn
lazy val MethodType(List(arg, _*), _) = fn.tpe
-
+
// Covers if the symbol matches the unapply method's argument type,
// and the return type of the unapply is Some.
override def covers(sym: Symbol) = newMatchesPattern(sym, arg.tpe)
-
+
// TODO: for alwaysCovers:
// fn.tpe.finalResultType.typeSymbol == SomeClass
@@ -451,7 +451,7 @@ trait Patterns extends ast.TreeDSL {
(sym.tpe.baseTypeSeq exists (_ matchesPattern pattp))
}
}
-
+
def sym = tree.symbol
def tpe = tree.tpe
def isEmpty = tree.isEmpty
@@ -496,4 +496,4 @@ trait Patterns extends ast.TreeDSL {
}
}
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index d541b7be0a..f68cbfc141 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -185,7 +185,7 @@ abstract class UnCurry extends InfoTransform
* try {
* body
* } catch {
- * case ex: NonLocalReturnControl[_] =>
+ * case ex: NonLocalReturnControl[T @unchecked] =>
* if (ex.key().eq(key)) ex.value()
* else throw ex
* }
@@ -195,7 +195,8 @@ abstract class UnCurry extends InfoTransform
localTyper typed {
val extpe = nonLocalReturnExceptionType(meth.tpe.finalResultType)
val ex = meth.newValue(nme.ex, body.pos) setInfo extpe
- val pat = gen.mkBindForCase(ex, NonLocalReturnControlClass, List(meth.tpe.finalResultType))
+ val argType = meth.tpe.finalResultType withAnnotation (AnnotationInfo marker UncheckedClass.tpe)
+ val pat = gen.mkBindForCase(ex, NonLocalReturnControlClass, List(argType))
val rhs = (
IF ((ex DOT nme.key)() OBJ_EQ Ident(key))
THEN ((ex DOT nme.value)())
diff --git a/src/compiler/scala/tools/nsc/typechecker/Checkable.scala b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala
new file mode 100644
index 0000000000..7e15cf91a7
--- /dev/null
+++ b/src/compiler/scala/tools/nsc/typechecker/Checkable.scala
@@ -0,0 +1,284 @@
+/* NSC -- new Scala compiler
+ * Copyright 2005-2012 LAMP/EPFL
+ * @author Paul Phillips
+ */
+
+package scala.tools.nsc
+package typechecker
+
+import scala.collection.{ mutable, immutable }
+import scala.collection.mutable.ListBuffer
+import scala.util.control.ControlThrowable
+import symtab.Flags._
+import scala.annotation.tailrec
+import Checkability._
+
+/** On pattern matcher checkability:
+ *
+ * Consider a pattern match of this form: (x: X) match { case _: P => }
+ *
+ * There are four possibilities to consider:
+ * [P1] X will always conform to P
+ * [P2] x will never conform to P
+ * [P3] X <: P if some runtime test is true
+ * [P4] X cannot be checked against P
+ *
+ * The first two cases correspond to those when there is enough
+ * static information to say X <: P or that (x ∈ X) ⇒ (x ∉ P).
+ * The fourth case includes unknown abstract types or structural
+ * refinements appearing within a pattern.
+ *
+ * The third case is the interesting one. We designate another type, XR,
+ * which is essentially the intersection of X and |P|, where |P| is
+ * the erasure of P. If XR <: P, then no warning is emitted.
+ *
+ * Examples of how this info is put to use:
+ * sealed trait A[T] ; class B[T] extends A[T]
+ * def f(x: B[Int]) = x match { case _: A[Int] if true => }
+ * def g(x: A[Int]) = x match { case _: B[Int] => }
+ *
+ * `f` requires no warning because X=B[Int], P=A[Int], and B[Int] <:< A[Int].
+ * `g` requires no warning because X=A[Int], P=B[Int], XR=B[Int], and B[Int] <:< B[Int].
+ * XR=B[Int] because a value of type A[Int] which is tested to be a B can
+ * only be a B[Int], due to the definition of B (B[T] extends A[T].)
+ *
+ * This is something like asSeenFrom, only rather than asking what a type looks
+ * like from the point of view of one of its base classes, we ask what it looks
+ * like from the point of view of one of its subclasses.
+ */
+trait Checkable {
+ self: Analyzer =>
+
+ import global._
+ import definitions._
+ import CheckabilityChecker.{ isNeverSubType, isNeverSubClass }
+
+ /** The applied type of class 'to' after inferring anything
+ * possible from the knowledge that 'to' must also be of the
+ * type given in 'from'.
+ */
+ def propagateKnownTypes(from: Type, to: Symbol): Type = {
+ def tparams = to.typeParams
+ val tvars = tparams map (p => TypeVar(p))
+ val tvarType = appliedType(to, tvars: _*)
+ val bases = from.baseClasses filter (to.baseClasses contains _)
+
+ bases foreach { bc =>
+ val tps1 = (from baseType bc).typeArgs
+ val tps2 = (tvarType baseType bc).typeArgs
+ (tps1, tps2).zipped foreach (_ =:= _)
+ // Alternate, variance respecting formulation causes
+ // neg/unchecked3.scala to fail (abstract types). TODO -
+ // figure it out. It seems there is more work to do if I
+ // allow for variance, because the constraints accumulate
+ // as bounds and "tvar.instValid" is false.
+ //
+ // foreach3(tps1, tps2, bc.typeParams)((tp1, tp2, tparam) =>
+ // if (tparam.initialize.isCovariant) tp1 <:< tp2
+ // else if (tparam.isContravariant) tp2 <:< tp1
+ // else tp1 =:= tp2
+ // )
+ }
+
+ val resArgs = tparams zip tvars map {
+ case (_, tvar) if tvar.instValid => tvar.constr.inst
+ case (tparam, _) => tparam.tpe
+ }
+ appliedType(to, resArgs: _*)
+ }
+
+ private def isUnwarnableTypeArgSymbol(sym: Symbol) = (
+ sym.isTypeParameter // dummy
+ || (sym.name.toTermName == nme.WILDCARD) // _
+ || nme.isVariableName(sym.name) // type variable
+ )
+ private def isUnwarnableTypeArg(arg: Type) = (
+ uncheckedOk(arg) // @unchecked T
+ || isUnwarnableTypeArgSymbol(arg.typeSymbolDirect) // has to be direct: see pos/t1439
+ )
+ private def uncheckedOk(tp: Type) = tp hasAnnotation UncheckedClass
+
+ private def typeArgsInTopLevelType(tp: Type): List[Type] = {
+ val tps = tp match {
+ case RefinedType(parents, _) => parents flatMap typeArgsInTopLevelType
+ case TypeRef(_, ArrayClass, arg :: Nil) => typeArgsInTopLevelType(arg)
+ case TypeRef(pre, sym, args) => typeArgsInTopLevelType(pre) ++ args
+ case ExistentialType(tparams, underlying) => tparams.map(_.tpe) ++ typeArgsInTopLevelType(underlying)
+ case _ => Nil
+ }
+ tps filterNot isUnwarnableTypeArg
+ }
+
+ private class CheckabilityChecker(val X: Type, val P: Type) {
+ def Xsym = X.typeSymbol
+ def Psym = P.typeSymbol
+ def XR = propagateKnownTypes(X, Psym)
+ // sadly the spec says (new java.lang.Boolean(true)).isInstanceOf[scala.Boolean]
+ def P1 = X matchesPattern P
+ def P2 = !Psym.isPrimitiveValueClass && isNeverSubType(X, P)
+ def P3 = isNonRefinementClassType(P) && (XR matchesPattern P)
+ def P4 = !(P1 || P2 || P3)
+
+ def summaryString = f"""
+ |Checking checkability of (x: $X) against pattern $P
+ |[P1] $P1%-6s X <: P // $X <: $P
+ |[P2] $P2%-6s x ∉ P // (x ∈ $X) ⇒ (x ∉ $P)
+ |[P3] $P3%-6s XR <: P // $XR <: $P
+ |[P4] $P4%-6s None of the above // !(P1 || P2 || P3)
+ """.stripMargin.trim
+
+ val result = (
+ if (X.isErroneous || P.isErroneous) CheckabilityError
+ else if (P1) StaticallyTrue
+ else if (P2) StaticallyFalse
+ else if (P3) RuntimeCheckable
+ else if (uncheckableType == NoType) {
+ // Avoid warning (except ourselves) if we can't pinpoint the uncheckable type
+ debugwarn("Checkability checker says 'Uncheckable', but uncheckable type cannot be found:\n" + summaryString)
+ CheckabilityError
+ }
+ else Uncheckable
+ )
+ lazy val uncheckableType = if (Psym.isAbstractType) P else {
+ val possibles = typeArgsInTopLevelType(P).toSet
+ val opt = possibles find { targ =>
+ // Create a derived type with every possibly uncheckable type replaced
+ // with a WildcardType, except for 'targ'. If !(XR <: derived) then
+ // 'targ' is uncheckable.
+ val derived = P map (tp => if (possibles(tp) && !(tp =:= targ)) WildcardType else tp)
+ !(XR <:< derived)
+ }
+ opt getOrElse NoType
+ }
+
+ def neverSubClass = isNeverSubClass(Xsym, Psym)
+ def neverMatches = result == StaticallyFalse
+ def isUncheckable = result == Uncheckable
+ def uncheckableMessage = uncheckableType match {
+ case NoType => "something"
+ case tp @ RefinedType(_, _) => "refinement " + tp
+ case TypeRef(_, sym, _) if sym.isAbstractType => "abstract type " + sym.name
+ case tp => "non-variable type argument " + tp
+ }
+ }
+
+ /** X, P, [P1], etc. are all explained at the top of the file.
+ */
+ private object CheckabilityChecker {
+ /** A knowable class is one which is either effectively final
+ * itself, or sealed with only knowable children.
+ */
+ def isKnowable(sym: Symbol): Boolean = /*logResult(s"isKnowable($sym)")*/(
+ sym.initialize.isEffectivelyFinal // pesky .initialize requirement, or we receive lies about isSealed
+ || sym.isSealed && (sym.children forall isKnowable)
+ )
+ def knownSubclasses(sym: Symbol): List[Symbol] = /*logResult(s"knownSubclasses($sym)")*/(sym :: {
+ if (sym.isSealed) sym.children.toList flatMap knownSubclasses
+ else Nil
+ })
+ def excludable(s1: Symbol, s2: Symbol) = /*logResult(s"excludable($s1, $s2)")*/(
+ isKnowable(s1)
+ && !(s2 isSubClass s1)
+ && knownSubclasses(s1).forall(child => !(child isSubClass s2))
+ )
+
+ /** Given classes A and B, can it be shown that nothing which is
+ * an A will ever be a subclass of something which is a B? This
+ * entails not only showing that !(A isSubClass B) but that the
+ * same is true of all their subclasses. Restated for symmetry:
+ * the same value cannot be a member of both A and B.
+ *
+ * 1) A must not be a subclass of B, nor B of A (the trivial check)
+ * 2) One of A or B must be completely knowable (see isKnowable)
+ * 3) Assuming A is knowable, the proposition is true if
+ * !(A' isSubClass B) for all A', where A' is a subclass of A.
+ *
+ * Due to symmetry, the last condition applies as well in reverse.
+ */
+ def isNeverSubClass(sym1: Symbol, sym2: Symbol) = /*logResult(s"isNeverSubClass($sym1, $sym2)")*/(
+ sym1.isClass
+ && sym2.isClass
+ && (excludable(sym1, sym2) || excludable(sym2, sym1))
+ )
+ private def isNeverSubArgs(tps1: List[Type], tps2: List[Type], tparams: List[Symbol]): Boolean = /*logResult(s"isNeverSubArgs($tps1, $tps2, $tparams)")*/ {
+ def isNeverSubArg(t1: Type, t2: Type, variance: Int) = {
+ if (variance > 0) isNeverSubType(t2, t1)
+ else if (variance < 0) isNeverSubType(t1, t2)
+ else isNeverSameType(t1, t2)
+ }
+ exists3(tps1, tps2, tparams map (_.variance))(isNeverSubArg)
+ }
+ private def isNeverSameType(tp1: Type, tp2: Type): Boolean = (tp1, tp2) match {
+ case (TypeRef(_, sym1, args1), TypeRef(_, sym2, args2)) =>
+ ( isNeverSubClass(sym1, sym2)
+ || isNeverSubClass(sym2, sym1)
+ || ((sym1 == sym2) && isNeverSubArgs(args1, args2, sym1.typeParams))
+ )
+ case _ =>
+ false
+ }
+ // Important to dealias at any entry point (this is the only one at this writing.)
+ def isNeverSubType(tp1: Type, tp2: Type): Boolean = /*logResult(s"isNeverSubType($tp1, $tp2)")*/((tp1.dealias, tp2.dealias) match {
+ case (TypeRef(_, sym1, args1), TypeRef(_, sym2, args2)) =>
+ isNeverSubClass(sym1, sym2) || {
+ (sym1 isSubClass sym2) && {
+ val tp1seen = tp1 baseType sym2
+ isNeverSubArgs(tp1seen.typeArgs, args2, sym2.typeParams)
+ }
+ }
+ case _ => false
+ })
+ }
+
+ trait InferCheckable {
+ self: Inferencer =>
+
+ /** TODO: much better error positions.
+ * Kind of stuck right now because they just pass us the one tree.
+ * TODO: Eliminate inPattern, canRemedy, which have no place here.
+ */
+ def checkCheckable(tree: Tree, P0: Type, X0: Type, inPattern: Boolean, canRemedy: Boolean = false) {
+ if (uncheckedOk(P0)) return
+ def where = if (inPattern) "pattern " else ""
+
+ // singleton types not considered here
+ val P = P0.widen
+ val X = X0.widen
+
+ P match {
+ // Prohibit top-level type tests for these, but they are ok nested (e.g. case Foldable[Nothing] => ... )
+ case TypeRef(_, NothingClass | NullClass | AnyValClass, _) =>
+ InferErrorGen.TypePatternOrIsInstanceTestError(tree, P)
+ // If top-level abstract types can be checked using a classtag extractor, don't warn about them
+ case TypeRef(_, sym, _) if sym.isAbstractType && canRemedy =>
+ ;
+ // Matching on types like case _: AnyRef { def bippy: Int } => doesn't work -- yet.
+ case RefinedType(_, decls) if !decls.isEmpty =>
+ getContext.unit.warning(tree.pos, s"a pattern match on a refinement type is unchecked")
+ case _ =>
+ val checker = new CheckabilityChecker(X, P)
+ log(checker.summaryString)
+ if (checker.neverMatches) {
+ val addendum = if (checker.neverSubClass) "" else " (but still might match its erasure)"
+ getContext.unit.warning(tree.pos, s"fruitless type test: a value of type $X cannot also be a $P$addendum")
+ }
+ else if (checker.isUncheckable) {
+ val msg = (
+ if (checker.uncheckableType =:= P) s"abstract type $where$P"
+ else s"${checker.uncheckableMessage} in type $where$P"
+ )
+ getContext.unit.warning(tree.pos, s"$msg is unchecked since it is eliminated by erasure")
+ }
+ }
+ }
+ }
+}
+
+private[typechecker] final class Checkability(val value: Int) extends AnyVal { }
+private[typechecker] object Checkability {
+ val StaticallyTrue = new Checkability(0)
+ val StaticallyFalse = new Checkability(1)
+ val RuntimeCheckable = new Checkability(2)
+ val Uncheckable = new Checkability(3)
+ val CheckabilityError = new Checkability(4)
+}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Infer.scala b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
index db16bd02ab..48abfd7a2c 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Infer.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Infer.scala
@@ -17,7 +17,7 @@ import scala.annotation.tailrec
* @author Martin Odersky
* @version 1.0
*/
-trait Infer {
+trait Infer extends Checkable {
self: Analyzer =>
import global._
@@ -253,7 +253,7 @@ trait Infer {
private val stdErrorValue = stdErrorClass.newErrorValue(nme.ERROR)
/** The context-dependent inferencer part */
- class Inferencer(context: Context) extends InferencerContextErrors {
+ class Inferencer(context: Context) extends InferencerContextErrors with InferCheckable {
import InferErrorGen._
/* -- Error Messages --------------------------------------------------- */
@@ -1361,99 +1361,6 @@ trait Infer {
check(tp, Nil)
}
- // if top-level abstract types can be checked using a classtag extractor, don't warn about them
- def checkCheckable(tree: Tree, typeToTest: Type, typeEnsured: Type, inPattern: Boolean, canRemedy: Boolean = false) = {
- log(s"checkCheckable($tree, $typeToTest, $typeEnsured, inPattern = $inPattern, canRemedy = $canRemedy")
-
- sealed abstract class TypeConformance(check: (Type, Type) => Boolean) {
- def apply(t1: Type, t2: Type): Boolean = check(t1, t2) && {
- log(s"Skipping unchecked for statically verifiable condition $t1 ${this} $t2")
- true
- }
- }
- // I tried to use varianceInType to track the variance implications
- // but I could not make it work.
- case object =:= extends TypeConformance(_ =:= _)
- case object <:< extends TypeConformance(_ <:< _)
- case object >:> extends TypeConformance((t1, t2) => t2 <:< t1)
- case object =!= extends TypeConformance((t1, t2) => false)
-
- var bound: List[Symbol] = Nil
- var warningMessages: List[String] = Nil
-
- def isLocalBinding(sym: Symbol) = (
- sym.isAbstractType && (
- (bound contains sym)
- || (sym.name == tpnme.WILDCARD)
- || {
- val e = context.scope.lookupEntry(sym.name)
- (e ne null) && e.sym == sym && !e.sym.isTypeParameterOrSkolem && e.owner == context.scope
- }
- )
- )
- def check(tp0: Type, pt: Type, conformance: TypeConformance): Boolean = {
- val tp = tp0.normalize
- // Set the warning message to be issued when the top-level call fails.
- def warn(what: String): Boolean = {
- warningMessages ::= what
- false
- }
- def checkArg(param: Symbol, arg: Type) = {
- def conforms = (
- if (param.isCovariant) <:<
- else if (param.isContravariant) >:>
- else =:=
- )
- (arg hasAnnotation UncheckedClass) || {
- arg.withoutAnnotations match {
- case TypeRef(_, sym, args) =>
- ( isLocalBinding(sym)
- || arg.typeSymbol.isTypeParameterOrSkolem
- || (sym.name == tpnme.WILDCARD) // avoid spurious warnings on HK types
- || check(arg, param.tpeHK, conforms)
- || warn("non-variable type argument " + arg)
- )
- case _ =>
- warn("non-variable type argument " + arg)
- }
- }
- }
-
- // Checking if pt (the expected type of the pattern, and the type
- // we are guaranteed) conforms to tp (the type expressed in the pattern's
- // type test.) If it does, then even if the type being checked for appears
- // to be uncheckable, it is not a warning situation, because it is indeed
- // checked: not at runtime, but statically.
- conformance.apply(pt, tp) || (tp match {
- case SingleType(pre, _) => check(pre, pt, =:=)
- case ExistentialType(quantified, tp1) => bound :::= quantified ; check(tp1, pt, <:<)
- case ThisType(_) | NoPrefix => true
- case RefinedType(parents, decls) if decls.isEmpty => parents forall (p => check(p, pt, <:<))
- case RefinedType(_, _) => warn("refinement " + tp)
- case TypeRef(_, ArrayClass, arg :: Nil) => check(arg, NoType, =!=)
- case TypeRef(_, NonLocalReturnControlClass, _) => true // no way to suppress unchecked warnings on try/catch
- // we only use the extractor for top-level type tests, type arguments remain unchecked
- case TypeRef(_, sym, _) if sym.isAbstractType => isLocalBinding(sym) || canRemedy || warn("abstract type " + tp)
- case TypeRef(_, _, Nil) => false // leaf node
- case TypeRef(pre, sym, args) => forall2(sym.typeParams, args)(checkArg) && check(pre, pt.prefix, =:=)
- case _ => warn("type " + tp)
- })
- }
- typeToTest match {
- // Prohibit top-level type tests for these, but they are
- // acceptable nested (e.g. case Foldable[Nothing] => ... )
- case TypeRef(_, NothingClass | NullClass | AnyValClass, _) =>
- TypePatternOrIsInstanceTestError(tree, typeToTest)
- case _ =>
- def where = ( if (inPattern) "pattern " else "" ) + typeToTest
- if (check(typeToTest, typeEnsured, =:=)) ()
- // Note that this is a regular warning, not an uncheckedWarning,
- // which is now the province of such notifications as "pattern matcher
- // exceeded its analysis budget."
- else warningMessages foreach (m =>
- context.unit.warning(tree.pos, s"$m in type $where is unchecked since it is eliminated by erasure"))
- }
- }
/** Type intersection of simple type tp1 with general type tp2.
* The result eliminates some redundancies.
diff --git a/src/compiler/scala/tools/nsc/typechecker/Modes.scala b/src/compiler/scala/tools/nsc/typechecker/Modes.scala
index e9ea99faab..d942d080cb 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Modes.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Modes.scala
@@ -86,6 +86,10 @@ trait Modes {
*/
final val TYPEPATmode = 0x10000
+ /** RETmode is set when we are typing a return expression.
+ */
+ final val RETmode = 0x20000
+
final private val StickyModes = EXPRmode | PATTERNmode | TYPEmode | ALTmode
final def onlyStickyModes(mode: Int) =
@@ -133,4 +137,4 @@ trait Modes {
def modeString(mode: Int): String =
if (mode == 0) "NOmode"
else (modeNameMap filterKeys (bit => inAllModes(mode, bit))).values mkString " "
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 6e222459c9..3a443ea2c0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -253,12 +253,6 @@ trait Typers extends Modes with Adaptations with Tags {
result
}
}
- def isNonRefinementClassType(tpe: Type) = tpe match {
- case SingleType(_, sym) => sym.isModuleClass
- case TypeRef(_, sym, _) => sym.isClass && !sym.isRefinementClass
- case ErrorType => true
- case _ => false
- }
private def errorNotClass(tpt: Tree, found: Type) = { ClassTypeRequiredError(tpt, found); false }
private def errorNotStable(tpt: Tree, found: Type) = { TypeNotAStablePrefixError(tpt, found); false }
@@ -3772,9 +3766,13 @@ trait Typers extends Modes with Adaptations with Tags {
if (fun.symbol == Predef_classOf)
typedClassOf(tree, args.head, true)
else {
- if (!isPastTyper && fun.symbol == Any_isInstanceOf && !targs.isEmpty)
- checkCheckable(tree, targs.head, AnyClass.tpe, inPattern = false)
-
+ if (!isPastTyper && fun.symbol == Any_isInstanceOf && targs.nonEmpty) {
+ val scrutineeType = fun match {
+ case Select(qual, _) => qual.tpe
+ case _ => AnyClass.tpe
+ }
+ checkCheckable(tree, targs.head, scrutineeType, inPattern = false)
+ }
val resultpe = restpe.instantiateTypeParams(tparams, targs)
//@M substitution in instantiateParams needs to be careful!
//@M example: class Foo[a] { def foo[m[x]]: m[a] = error("") } (new Foo[Int]).foo[List] : List[Int]
@@ -3784,7 +3782,8 @@ trait Typers extends Modes with Adaptations with Tags {
//println("instantiating type params "+restpe+" "+tparams+" "+targs+" = "+resultpe)
treeCopy.TypeApply(tree, fun, args) setType resultpe
}
- } else {
+ }
+ else {
TypedApplyWrongNumberOfTpeParametersError(tree, fun)
}
case ErrorType =>
@@ -4181,7 +4180,7 @@ trait Typers extends Modes with Adaptations with Tags {
ReturnWithoutTypeError(tree, enclMethod.owner)
} else {
context.enclMethod.returnsSeen = true
- val expr1: Tree = typed(expr, EXPRmode | BYVALmode, restpt.tpe)
+ val expr1: Tree = typed(expr, EXPRmode | BYVALmode | RETmode, restpt.tpe)
// Warn about returning a value if no value can be returned.
if (restpt.tpe.typeSymbol == UnitClass) {
// The typing in expr1 says expr is Unit (it has already been coerced if
@@ -4190,7 +4189,8 @@ trait Typers extends Modes with Adaptations with Tags {
if (typed(expr).tpe.typeSymbol != UnitClass)
unit.warning(tree.pos, "enclosing method " + name + " has result type Unit: return value discarded")
}
- treeCopy.Return(tree, checkDead(expr1)) setSymbol enclMethod.owner setType NothingClass.tpe
+ treeCopy.Return(tree, checkDead(expr1)).setSymbol(enclMethod.owner)
+ .setType(adaptTypeOfReturn(expr1, restpt.tpe, NothingClass.tpe))
}
}
}
diff --git a/src/compiler/scala/tools/reflect/FrontEnd.scala b/src/compiler/scala/tools/reflect/FrontEnd.scala
new file mode 100644
index 0000000000..f0d3d5973d
--- /dev/null
+++ b/src/compiler/scala/tools/reflect/FrontEnd.scala
@@ -0,0 +1,50 @@
+package scala.tools
+package reflect
+
+import scala.reflect.internal.util.Position
+
+trait FrontEnd {
+ object severity extends Enumeration
+ class Severity(val id: Int) extends severity.Value {
+ var count: Int = 0
+ override def toString() = this match {
+ case INFO => "INFO"
+ case WARNING => "WARNING"
+ case ERROR => "ERROR"
+ case _ => "<unknown>"
+ }
+ }
+ val INFO = new Severity(0)
+ val WARNING = new Severity(1)
+ val ERROR = new Severity(2)
+
+ def hasErrors = ERROR.count > 0
+ def hasWarnings = WARNING.count > 0
+
+ case class Info(val pos: Position, val msg: String, val severity: Severity)
+ val infos = new scala.collection.mutable.LinkedHashSet[Info]
+
+ /** Handles incoming info */
+ def log(pos: Position, msg: String, severity: Severity) {
+ infos += new Info(pos, msg, severity)
+ severity.count += 1
+ display(infos.last)
+ }
+
+ /** Displays incoming info */
+ def display(info: Info): Unit
+
+ /** Services a request to drop into interactive mode */
+ def interactive(): Unit
+
+ /** Refreshes the UI */
+ def flush(): Unit = {}
+
+ /** Resets the reporter */
+ def reset(): Unit = {
+ INFO.count = 0
+ WARNING.count = 0
+ ERROR.count = 0
+ infos.clear()
+ }
+}
diff --git a/src/compiler/scala/tools/reflect/FrontEnds.scala b/src/compiler/scala/tools/reflect/FrontEnds.scala
deleted file mode 100644
index d0c3c1c774..0000000000
--- a/src/compiler/scala/tools/reflect/FrontEnds.scala
+++ /dev/null
@@ -1,88 +0,0 @@
-package scala.tools
-package reflect
-
-import scala.tools.nsc.reporters._
-import scala.tools.nsc.Settings
-import scala.reflect.ClassTag
-
-trait FrontEnds extends scala.reflect.api.FrontEnds {
-
- type Position = scala.reflect.internal.util.Position
-
- def mkConsoleFrontEnd(minSeverity: Int = 1): FrontEnd = {
- val settings = new Settings()
- if (minSeverity <= 0) settings.verbose.value = true
- if (minSeverity > 1) settings.nowarn.value = true
- wrapReporter(new ConsoleReporter(settings))
- }
-
- abstract class FrontEndToReporterProxy(val frontEnd: FrontEnd) extends AbstractReporter {
- import frontEnd.{Severity => ApiSeverity}
- val API_INFO = frontEnd.INFO
- val API_WARNING = frontEnd.WARNING
- val API_ERROR = frontEnd.ERROR
-
- type NscSeverity = Severity
- val NSC_INFO = INFO
- val NSC_WARNING = WARNING
- val NSC_ERROR = ERROR
-
- def display(pos: Position, msg: String, nscSeverity: NscSeverity): Unit =
- frontEnd.log(pos, msg, nscSeverity match {
- case NSC_INFO => API_INFO
- case NSC_WARNING => API_WARNING
- case NSC_ERROR => API_ERROR
- })
-
- def displayPrompt(): Unit =
- frontEnd.interactive()
-
- override def flush(): Unit = {
- super.flush()
- frontEnd.flush()
- }
-
- override def reset(): Unit = {
- super.reset()
- frontEnd.reset()
- }
- }
-
- def wrapFrontEnd(frontEnd: FrontEnd): Reporter = new FrontEndToReporterProxy(frontEnd) {
- val settings = new Settings()
- settings.verbose.value = true
- settings.nowarn.value = false
- }
-
- class ReporterToFrontEndProxy(val reporter: Reporter) extends FrontEnd {
- val API_INFO = INFO
- val API_WARNING = WARNING
- val API_ERROR = ERROR
-
- override def hasErrors = reporter.hasErrors
- override def hasWarnings = reporter.hasWarnings
-
- def display(info: Info): Unit = info.severity match {
- case API_INFO => reporter.info(info.pos, info.msg, false)
- case API_WARNING => reporter.warning(info.pos, info.msg)
- case API_ERROR => reporter.error(info.pos, info.msg)
- }
-
- def interactive(): Unit = reporter match {
- case reporter: AbstractReporter => reporter.displayPrompt()
- case _ => // do nothing
- }
-
- override def flush(): Unit = {
- super.flush()
- reporter.flush()
- }
-
- override def reset(): Unit = {
- super.reset()
- reporter.reset()
- }
- }
-
- def wrapReporter(reporter: Reporter): FrontEnd = new ReporterToFrontEndProxy(reporter)
-}
diff --git a/src/compiler/scala/tools/reflect/StdTags.scala b/src/compiler/scala/tools/reflect/StdTags.scala
index 94fd8e1fe8..a3bc9b9bd1 100644
--- a/src/compiler/scala/tools/reflect/StdTags.scala
+++ b/src/compiler/scala/tools/reflect/StdTags.scala
@@ -3,7 +3,7 @@ package reflect
import java.lang.{Class => jClass}
import scala.reflect.{ClassTag, classTag}
-import scala.reflect.api.{MirrorOf, TypeCreator, Universe => ApiUniverse}
+import scala.reflect.api.{Mirror, TypeCreator, Universe => ApiUniverse}
// [Eugene++] Before 2.10 is released, I suggest we don't rely on automated type tag generation
// sure, it's convenient, but then refactoring reflection / reification becomes a pain
@@ -11,13 +11,13 @@ import scala.reflect.api.{MirrorOf, TypeCreator, Universe => ApiUniverse}
trait StdTags {
val u: ApiUniverse with Singleton
- val m: MirrorOf[u.type]
+ val m: Mirror[u.type]
lazy val tagOfListOfString: u.TypeTag[List[String]] =
u.TypeTag[List[String]](
m,
new TypeCreator {
- def apply[U <: ApiUniverse with Singleton](m: MirrorOf[U]): U # Type = {
+ def apply[U <: ApiUniverse with Singleton](m: Mirror[U]): U # Type = {
val u = m.universe
val pre = u.ThisType(m.staticPackage("scala.collection.immutable").moduleClass.asInstanceOf[u.Symbol])
u.TypeRef(pre, u.definitions.ListClass, List(u.definitions.StringClass.toTypeConstructor))
@@ -28,7 +28,7 @@ trait StdTags {
u.TypeTag[T](
m,
new TypeCreator {
- def apply[U <: ApiUniverse with Singleton](m: MirrorOf[U]): U # Type =
+ def apply[U <: ApiUniverse with Singleton](m: Mirror[U]): U # Type =
m.staticClass(classTag[T].runtimeClass.getName).toTypeConstructor.asInstanceOf[U # Type]
})
lazy val tagOfInt = u.TypeTag.Int
diff --git a/src/compiler/scala/tools/reflect/ToolBox.scala b/src/compiler/scala/tools/reflect/ToolBox.scala
index f627699597..ab814b617d 100644
--- a/src/compiler/scala/tools/reflect/ToolBox.scala
+++ b/src/compiler/scala/tools/reflect/ToolBox.scala
@@ -15,6 +15,9 @@ trait ToolBox[U <: scala.reflect.api.Universe] {
*
* Accumulates and displays warnings and errors, can drop to interactive mode (if supported).
* The latter can be useful to study the typechecker or to debug complex macros.
+ *
+ * [[scala.tools.reflect]] provides two predefined front ends that can be created using
+ * [[scala.tools.reflect.mkSilentFrontEnd]] and [[scala.tools.reflect.mkConsoleFrontEnd]].
*/
def frontEnd: FrontEnd
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index 17d69cf94b..95135b84e0 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -334,7 +334,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
val errorFn: String => Unit = msg => frontEnd.log(scala.reflect.internal.util.NoPosition, msg, frontEnd.ERROR)
val command = new CompilerCommand(arguments.toList, errorFn)
command.settings.outputDirs setSingleOutput virtualDirectory
- val instance = new ToolBoxGlobal(command.settings, new FrontEndToReporterProxy(frontEnd) { val settings = command.settings })
+ val instance = new ToolBoxGlobal(command.settings, frontEndToReporter(frontEnd, command.settings))
if (frontEnd.hasErrors) {
var msg = "reflective compilation has failed: cannot initialize the compiler: " + EOL + EOL
msg += frontEnd.infos map (_.msg) mkString EOL
diff --git a/src/compiler/scala/tools/reflect/package.scala b/src/compiler/scala/tools/reflect/package.scala
index 901071d91a..8a1e3628e2 100644
--- a/src/compiler/scala/tools/reflect/package.scala
+++ b/src/compiler/scala/tools/reflect/package.scala
@@ -6,9 +6,12 @@
package scala.tools
import scala.reflect.api.JavaUniverse
+import scala.reflect.internal.util.Position
import scala.language.implicitConversions
+import scala.tools.nsc.reporters._
+import scala.tools.nsc.Settings
-package object reflect extends FrontEnds {
+package object reflect {
// [todo: can we generalize this?
import scala.reflect.runtime.{universe => ru}
implicit def ToolBox(mirror0: ru.Mirror): ToolBoxFactory[ru.type] =
@@ -17,9 +20,92 @@ package object reflect extends FrontEnds {
}
// todo. replace this with an implicit class, once the pesky warning is gone
+ // we don't provide `Eval` for trees, because it's unclear where to get an evaluation mirror from
implicit def Eval[T](expr: JavaUniverse # Expr[T]): Eval[T] = new Eval[T](expr)
- // we don't provide `Eval` for trees, because it's unclear where to get an evaluation mirror from
+ /** Creates a UI-less reporter that simply accumulates all the messages
+ */
+ def mkSilentFrontEnd(): FrontEnd = new FrontEnd {
+ def display(info: Info) {}
+ def interactive() {}
+ }
+
+ /** Creates a reporter that prints messages to the console according to the settings.
+ *
+ * ``minSeverity'' determines minimum severity of the messages to be printed.
+ * 0 stands for INFO, 1 stands for WARNING and 2 stands for ERROR.
+ */
+ // todo. untangle warningsAsErrors from Reporters. I don't feel like moving this flag here!
+ def mkConsoleFrontEnd(minSeverity: Int = 1): FrontEnd = {
+ val settings = new Settings()
+ if (minSeverity <= 0) settings.verbose.value = true
+ if (minSeverity > 1) settings.nowarn.value = true
+ reporterToFrontEnd(new ConsoleReporter(settings))
+ }
+
+ private[reflect] def reporterToFrontEnd(reporter: Reporter): FrontEnd = new FrontEnd {
+ val API_INFO = INFO
+ val API_WARNING = WARNING
+ val API_ERROR = ERROR
+
+ override def hasErrors = reporter.hasErrors
+ override def hasWarnings = reporter.hasWarnings
+
+ def display(info: Info): Unit = info.severity match {
+ case API_INFO => reporter.info(info.pos, info.msg, false)
+ case API_WARNING => reporter.warning(info.pos, info.msg)
+ case API_ERROR => reporter.error(info.pos, info.msg)
+ }
+
+ def interactive(): Unit = reporter match {
+ case reporter: AbstractReporter => reporter.displayPrompt()
+ case _ => // do nothing
+ }
+
+ override def flush(): Unit = {
+ super.flush()
+ reporter.flush()
+ }
+
+ override def reset(): Unit = {
+ super.reset()
+ reporter.reset()
+ }
+ }
+
+ private[reflect] def frontEndToReporter(frontEnd: FrontEnd, settings0: Settings): Reporter = new AbstractReporter {
+ val settings = settings0
+
+ import frontEnd.{Severity => ApiSeverity}
+ val API_INFO = frontEnd.INFO
+ val API_WARNING = frontEnd.WARNING
+ val API_ERROR = frontEnd.ERROR
+
+ type NscSeverity = Severity
+ val NSC_INFO = INFO
+ val NSC_WARNING = WARNING
+ val NSC_ERROR = ERROR
+
+ def display(pos: Position, msg: String, nscSeverity: NscSeverity): Unit =
+ frontEnd.log(pos, msg, nscSeverity match {
+ case NSC_INFO => API_INFO
+ case NSC_WARNING => API_WARNING
+ case NSC_ERROR => API_ERROR
+ })
+
+ def displayPrompt(): Unit =
+ frontEnd.interactive()
+
+ override def flush(): Unit = {
+ super.flush()
+ frontEnd.flush()
+ }
+
+ override def reset(): Unit = {
+ super.reset()
+ frontEnd.reset()
+ }
+ }
}
package reflect {
diff --git a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
index a20ff1667b..b373b3d0de 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/CPSAnnotationChecker.scala
@@ -150,10 +150,8 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes {
if ((mode & global.analyzer.EXPRmode) != 0) {
if ((annots1 corresponds annots2)(_.atp <:< _.atp)) {
vprintln("already same, can't adapt further")
- return false
- }
-
- if (annots1.isEmpty && !annots2.isEmpty && ((mode & global.analyzer.BYVALmode) == 0)) {
+ false
+ } else if (annots1.isEmpty && !annots2.isEmpty && ((mode & global.analyzer.BYVALmode) == 0)) {
//println("can adapt annotations? " + tree + " / " + tree.tpe + " / " + Integer.toHexString(mode) + " / " + pt)
if (!hasPlusMarker(tree.tpe)) {
// val base = tree.tpe <:< removeAllCPSAnnotations(pt)
@@ -163,17 +161,26 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes {
// TBD: use same or not?
//if (same) {
vprintln("yes we can!! (unit)")
- return true
+ true
//}
- }
- } else if (!annots1.isEmpty && ((mode & global.analyzer.BYVALmode) != 0)) {
- if (!hasMinusMarker(tree.tpe)) {
+ } else false
+ } else if (!hasPlusMarker(tree.tpe) && annots1.isEmpty && !annots2.isEmpty && ((mode & global.analyzer.RETmode) != 0)) {
+ vprintln("checking enclosing method's result type without annotations")
+ tree.tpe <:< pt.withoutAnnotations
+ } else if (!hasMinusMarker(tree.tpe) && !annots1.isEmpty && ((mode & global.analyzer.BYVALmode) != 0)) {
+ val optCpsTypes: Option[(Type, Type)] = cpsParamTypes(tree.tpe)
+ val optExpectedCpsTypes: Option[(Type, Type)] = cpsParamTypes(pt)
+ if (optCpsTypes.isEmpty || optExpectedCpsTypes.isEmpty) {
vprintln("yes we can!! (byval)")
- return true
+ true
+ } else { // check cps param types
+ val cpsTpes = optCpsTypes.get
+ val cpsPts = optExpectedCpsTypes.get
+ // class cpsParam[-B,+C], therefore:
+ cpsPts._1 <:< cpsTpes._1 && cpsTpes._2 <:< cpsPts._2
}
- }
- }
- false
+ } else false
+ } else false
}
override def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = {
@@ -184,6 +191,7 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes {
val patMode = (mode & global.analyzer.PATTERNmode) != 0
val exprMode = (mode & global.analyzer.EXPRmode) != 0
val byValMode = (mode & global.analyzer.BYVALmode) != 0
+ val retMode = (mode & global.analyzer.RETmode) != 0
val annotsTree = cpsParamAnnotation(tree.tpe)
val annotsExpected = cpsParamAnnotation(pt)
@@ -210,9 +218,38 @@ abstract class CPSAnnotationChecker extends CPSUtils with Modes {
val res = tree modifyType addMinusMarker
vprintln("adapted annotations (by val) of " + tree + " to " + res.tpe)
res
+ } else if (retMode && !hasPlusMarker(tree.tpe) && annotsTree.isEmpty && annotsExpected.nonEmpty) {
+ // add a marker annotation that will make tree.tpe behave as pt, subtyping wise
+ // tree will look like having any possible annotation
+
+ // note 1: we are only adding a plus marker if the method's result type is a cps type
+ // (annotsExpected.nonEmpty == cpsParamAnnotation(pt).nonEmpty)
+ // note 2: we are not adding the expected cps annotations, since they will be added
+ // by adaptTypeOfReturn (see below).
+ val res = tree modifyType (_ withAnnotations List(newPlusMarker()))
+ vprintln("adapted annotations (return) of " + tree + " to " + res.tpe)
+ res
} else tree
}
+ /** Returns an adapted type for a return expression if the method's result type (pt) is a CPS type.
+ * Otherwise, it returns the `default` type (`typedReturn` passes `NothingClass.tpe`).
+ *
+ * A return expression in a method that has a CPS result type is an error unless the return
+ * is in tail position. Therefore, we are making sure that only the types of return expressions
+ * are adapted which will either be removed, or lead to an error.
+ */
+ override def adaptTypeOfReturn(tree: Tree, pt: Type, default: => Type): Type = {
+ // only adapt if method's result type (pt) is cps type
+ val annots = cpsParamAnnotation(pt)
+ if (annots.nonEmpty) {
+ // return type of `tree` without plus marker, but only if it doesn't have other cps annots
+ if (hasPlusMarker(tree.tpe) && !hasCpsParamTypes(tree.tpe))
+ tree.setType(removeAttribs(tree.tpe, MarkerCPSAdaptPlus))
+ tree.tpe
+ } else default
+ }
+
def updateAttributesFromChildren(tpe: Type, childAnnots: List[AnnotationInfo], byName: List[Tree]): Type = {
tpe match {
// Would need to push annots into each alternative of overloaded type
diff --git a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
index 51760d2807..ba87cadfeb 100644
--- a/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
+++ b/src/continuations/plugin/scala/tools/selectivecps/SelectiveANFTransform.scala
@@ -32,6 +32,55 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
implicit val _unit = unit // allow code in CPSUtils.scala to report errors
var cpsAllowed: Boolean = false // detect cps code in places we do not handle (yet)
+ object RemoveTailReturnsTransformer extends Transformer {
+ override def transform(tree: Tree): Tree = tree match {
+ case Block(stms, r @ Return(expr)) =>
+ treeCopy.Block(tree, stms, expr)
+
+ case Block(stms, expr) =>
+ treeCopy.Block(tree, stms, transform(expr))
+
+ case If(cond, r1 @ Return(thenExpr), r2 @ Return(elseExpr)) =>
+ treeCopy.If(tree, cond, transform(thenExpr), transform(elseExpr))
+
+ case If(cond, r1 @ Return(thenExpr), elseExpr) =>
+ treeCopy.If(tree, cond, transform(thenExpr), transform(elseExpr))
+
+ case If(cond, thenExpr, r2 @ Return(elseExpr)) =>
+ treeCopy.If(tree, cond, transform(thenExpr), transform(elseExpr))
+
+ case If(cond, thenExpr, elseExpr) =>
+ treeCopy.If(tree, cond, transform(thenExpr), transform(elseExpr))
+
+ case Try(block, catches, finalizer) =>
+ treeCopy.Try(tree,
+ transform(block),
+ (catches map (t => transform(t))).asInstanceOf[List[CaseDef]],
+ transform(finalizer))
+
+ case CaseDef(pat, guard, r @ Return(expr)) =>
+ treeCopy.CaseDef(tree, pat, guard, expr)
+
+ case CaseDef(pat, guard, body) =>
+ treeCopy.CaseDef(tree, pat, guard, transform(body))
+
+ case Return(_) =>
+ unit.error(tree.pos, "return expressions in CPS code must be in tail position")
+ tree
+
+ case _ =>
+ super.transform(tree)
+ }
+ }
+
+ def removeTailReturns(body: Tree): Tree = {
+ // support body with single return expression
+ body match {
+ case Return(expr) => expr
+ case _ => RemoveTailReturnsTransformer.transform(body)
+ }
+ }
+
override def transform(tree: Tree): Tree = {
if (!cpsEnabled) return tree
@@ -46,11 +95,14 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
// this would cause infinite recursion. But we could remove the
// ValDef case here.
- case dd @ DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
+ case dd @ DefDef(mods, name, tparams, vparamss, tpt, rhs0) =>
debuglog("transforming " + dd.symbol)
atOwner(dd.symbol) {
- val rhs1 = transExpr(rhs, None, getExternalAnswerTypeAnn(tpt.tpe))
+ val rhs =
+ if (cpsParamTypes(tpt.tpe).nonEmpty) removeTailReturns(rhs0)
+ else rhs0
+ val rhs1 = transExpr(rhs, None, getExternalAnswerTypeAnn(tpt.tpe))(getExternalAnswerTypeAnn(tpt.tpe).isDefined)
debuglog("result "+rhs1)
debuglog("result is of type "+rhs1.tpe)
@@ -75,6 +127,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
val ext = getExternalAnswerTypeAnn(body.tpe)
val pureBody = getAnswerTypeAnn(body.tpe).isEmpty
+ implicit val isParentImpure = ext.isDefined
def transformPureMatch(tree: Tree, selector: Tree, cases: List[CaseDef]) = {
val caseVals = cases map { case cd @ CaseDef(pat, guard, body) =>
@@ -154,8 +207,8 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
}
- def transExpr(tree: Tree, cpsA: CPSInfo, cpsR: CPSInfo): Tree = {
- transTailValue(tree, cpsA, cpsR) match {
+ def transExpr(tree: Tree, cpsA: CPSInfo, cpsR: CPSInfo)(implicit isAnyParentImpure: Boolean = false): Tree = {
+ transTailValue(tree, cpsA, cpsR)(cpsR.isDefined || isAnyParentImpure) match {
case (Nil, b) => b
case (a, b) =>
treeCopy.Block(tree, a,b)
@@ -163,7 +216,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
}
- def transArgList(fun: Tree, args: List[Tree], cpsA: CPSInfo): (List[List[Tree]], List[Tree], CPSInfo) = {
+ def transArgList(fun: Tree, args: List[Tree], cpsA: CPSInfo)(implicit isAnyParentImpure: Boolean): (List[List[Tree]], List[Tree], CPSInfo) = {
val formals = fun.tpe.paramTypes
val overshoot = args.length - formals.length
@@ -172,7 +225,8 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
val (stm,expr) = (for ((a,tp) <- args.zip(formals ::: List.fill(overshoot)(NoType))) yield {
tp match {
case TypeRef(_, ByNameParamClass, List(elemtp)) =>
- (Nil, transExpr(a, None, getAnswerTypeAnn(elemtp)))
+ // note that we're not passing just isAnyParentImpure
+ (Nil, transExpr(a, None, getAnswerTypeAnn(elemtp))(getAnswerTypeAnn(elemtp).isDefined || isAnyParentImpure))
case _ =>
val (valStm, valExpr, valSpc) = transInlineValue(a, spc)
spc = valSpc
@@ -184,7 +238,8 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
}
- def transValue(tree: Tree, cpsA: CPSInfo, cpsR: CPSInfo): (List[Tree], Tree, CPSInfo) = {
+ // precondition: cpsR.isDefined "implies" isAnyParentImpure
+ def transValue(tree: Tree, cpsA: CPSInfo, cpsR: CPSInfo)(implicit isAnyParentImpure: Boolean): (List[Tree], Tree, CPSInfo) = {
// return value: (stms, expr, spc), where spc is CPSInfo after stms but *before* expr
implicit val pos = tree.pos
tree match {
@@ -192,7 +247,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
val (cpsA2, cpsR2) = (cpsA, linearize(cpsA, getAnswerTypeAnn(tree.tpe))) // tbd
// val (cpsA2, cpsR2) = (None, getAnswerTypeAnn(tree.tpe))
- val (a, b) = transBlock(stms, expr, cpsA2, cpsR2)
+ val (a, b) = transBlock(stms, expr, cpsA2, cpsR2)(cpsR2.isDefined || isAnyParentImpure)
val tree1 = (treeCopy.Block(tree, a, b)) // no updateSynthFlag here!!!
(Nil, tree1, cpsA)
@@ -206,8 +261,8 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
val (cpsA2, cpsR2) = if (hasSynthMarker(tree.tpe))
(spc, linearize(spc, getAnswerTypeAnn(tree.tpe))) else
(None, getAnswerTypeAnn(tree.tpe)) // if no cps in condition, branches must conform to tree.tpe directly
- val thenVal = transExpr(thenp, cpsA2, cpsR2)
- val elseVal = transExpr(elsep, cpsA2, cpsR2)
+ val thenVal = transExpr(thenp, cpsA2, cpsR2)(cpsR2.isDefined || isAnyParentImpure)
+ val elseVal = transExpr(elsep, cpsA2, cpsR2)(cpsR2.isDefined || isAnyParentImpure)
// check that then and else parts agree (not necessary any more, but left as sanity check)
if (cpsR.isDefined) {
@@ -227,7 +282,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
else (None, getAnswerTypeAnn(tree.tpe))
val caseVals = cases map { case cd @ CaseDef(pat, guard, body) =>
- val bodyVal = transExpr(body, cpsA2, cpsR2)
+ val bodyVal = transExpr(body, cpsA2, cpsR2)(cpsR2.isDefined || isAnyParentImpure)
treeCopy.CaseDef(cd, transform(pat), transform(guard), bodyVal)
}
@@ -245,7 +300,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
// currentOwner.newMethod(name, tree.pos, Flags.SYNTHETIC) setInfo ldef.symbol.info
val sym = ldef.symbol resetFlag Flags.LABEL
val rhs1 = rhs //new TreeSymSubstituter(List(ldef.symbol), List(sym)).transform(rhs)
- val rhsVal = transExpr(rhs1, None, getAnswerTypeAnn(tree.tpe)) changeOwner (currentOwner -> sym)
+ val rhsVal = transExpr(rhs1, None, getAnswerTypeAnn(tree.tpe))(getAnswerTypeAnn(tree.tpe).isDefined || isAnyParentImpure) changeOwner (currentOwner -> sym)
val stm1 = localTyper.typed(DefDef(sym, rhsVal))
// since virtpatmat does not rely on fall-through, don't call the labels it emits
@@ -284,6 +339,8 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
(stms, updateSynthFlag(treeCopy.Assign(tree, transform(lhs), expr)), spc)
case Return(expr0) =>
+ if (isAnyParentImpure)
+ unit.error(tree.pos, "return expression not allowed, since method calls CPS method")
val (stms, expr, spc) = transInlineValue(expr0, cpsA)
(stms, updateSynthFlag(treeCopy.Return(tree, expr)), spc)
@@ -321,7 +378,8 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
}
}
- def transTailValue(tree: Tree, cpsA: CPSInfo, cpsR: CPSInfo): (List[Tree], Tree) = {
+ // precondition: cpsR.isDefined "implies" isAnyParentImpure
+ def transTailValue(tree: Tree, cpsA: CPSInfo, cpsR: CPSInfo)(implicit isAnyParentImpure: Boolean): (List[Tree], Tree) = {
val (stms, expr, spc) = transValue(tree, cpsA, cpsR)
@@ -398,7 +456,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
(stms, expr)
}
- def transInlineValue(tree: Tree, cpsA: CPSInfo): (List[Tree], Tree, CPSInfo) = {
+ def transInlineValue(tree: Tree, cpsA: CPSInfo)(implicit isAnyParentImpure: Boolean): (List[Tree], Tree, CPSInfo) = {
val (stms, expr, spc) = transValue(tree, cpsA, None) // never required to be cps
@@ -425,7 +483,7 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
- def transInlineStm(stm: Tree, cpsA: CPSInfo): (List[Tree], CPSInfo) = {
+ def transInlineStm(stm: Tree, cpsA: CPSInfo)(implicit isAnyParentImpure: Boolean): (List[Tree], CPSInfo) = {
stm match {
// TODO: what about DefDefs?
@@ -455,7 +513,8 @@ abstract class SelectiveANFTransform extends PluginComponent with Transform with
}
}
- def transBlock(stms: List[Tree], expr: Tree, cpsA: CPSInfo, cpsR: CPSInfo): (List[Tree], Tree) = {
+ // precondition: cpsR.isDefined "implies" isAnyParentImpure
+ def transBlock(stms: List[Tree], expr: Tree, cpsA: CPSInfo, cpsR: CPSInfo)(implicit isAnyParentImpure: Boolean): (List[Tree], Tree) = {
def rec(currStats: List[Tree], currAns: CPSInfo, accum: List[Tree]): (List[Tree], Tree) =
currStats match {
case Nil =>
diff --git a/src/library/scala/StringContext.scala b/src/library/scala/StringContext.scala
index 8b478f6845..e381c09398 100644
--- a/src/library/scala/StringContext.scala
+++ b/src/library/scala/StringContext.scala
@@ -8,10 +8,43 @@
package scala
-/** A class to support string interpolation.
- * This class supports string interpolation as outlined in Scala SIP-11.
- * It needs to be fully documented once the SIP is accepted.
+/** This class provides the basic mechanism to do String Interpolation.
+ * String Interpolation allows users
+ * to embed variable references directly in *processed* string literals.
+ * Here's an example:
+ * {{{
+ * val name = "James"
+ * println(s"Hello, $name") // Hello, James
+ * }}}
*
+ * Any processed string literal is rewritten as an instantiation and
+ * method call against this class. For example:
+ * {{{
+ * s"Hello, $name"
+ * }}}
+ *
+ * is rewritten to be:
+ *
+ * {{{
+ * new StringContext("Hello, ", "").s(name)
+ * }}}
+ *
+ * By default, this class provides the `raw`, `s` and `f` methods as
+ * available interpolators.
+ *
+ * To provide your own string interpolator, create an implicit class
+ * which adds a method to `StringContext`. Here's an example:
+ * {{{
+ * implicit class JsonHelper(val sc: StringContext) extends AnyVal {
+ * def json(args: Any*): JSONObject = ...
+ * }
+ * val x: JSONObject = json"{ a: $a }"
+ * }}}
+ *
+ * Here the `JsonHelper` extenion class implicitly adds the `json` method to
+ * `StringContext` which can be used for `json` string literals.
+ *
+ * @since 2.10.0
* @param parts The parts that make up the interpolated string,
* without the expressions that get inserted by interpolation.
*/
@@ -33,6 +66,20 @@ case class StringContext(parts: String*) {
*
* It inserts its arguments between corresponding parts of the string context.
* It also treats standard escape sequences as defined in the Scala specification.
+ * Here's an example of usage:
+ * {{{
+ * val name = "James"
+ * println(s"Hello, $name") // Hello, James
+ * }}}
+ * In this example, the expression $name is replaced with the `toString` of the
+ * variable `name`.
+ * The `s` interpolator can take the `toString` of any arbitrary expression within
+ * a `${}` block, for example:
+ * {{{
+ * println(s"1 + 1 = ${1 + 1}")
+ * }}}
+ * will print the string `1 + 1 = 2`.
+ *
* @param `args` The arguments to be inserted into the resulting string.
* @throws An `IllegalArgumentException`
* if the number of `parts` in the enclosing `StringContext` does not exceed
@@ -47,6 +94,9 @@ case class StringContext(parts: String*) {
* It inserts its arguments between corresponding parts of the string context.
* As opposed to the simple string interpolator `s`, this one does not treat
* standard escape sequences as defined in the Scala specification.
+ *
+ * For example, the raw processed string `raw"a\nb"` is equal to the scala string `"a\\nb"`.
+ *
* @param `args` The arguments to be inserted into the resulting string.
* @throws An `IllegalArgumentException`
* if the number of `parts` in the enclosing `StringContext` does not exceed
@@ -77,6 +127,13 @@ case class StringContext(parts: String*) {
* specifier. All specifiers allowed in Java format strings are handled, and in the same
* way they are treated in Java.
*
+ * For example:
+ * {{{
+ * val height = 1.9d
+ * val name = "James"
+ * println(f"$name%s is $height%2.2f meters tall") // James is 1.90 meters tall
+ * }}}
+ *
* @param `args` The arguments to be inserted into the resulting string.
* @throws An `IllegalArgumentException`
* if the number of `parts` in the enclosing `StringContext` does not exceed
diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala
index 2bb0cc3c76..b0de7f8d5a 100644
--- a/src/reflect/scala/reflect/api/BuildUtils.scala
+++ b/src/reflect/scala/reflect/api/BuildUtils.scala
@@ -4,7 +4,7 @@ package api
/**
* This is an internal implementation class.
*/
-trait BuildUtils { self: Universe =>
+private[reflect] trait BuildUtils { self: Universe =>
val build: BuildApi
diff --git a/src/reflect/scala/reflect/api/Exprs.scala b/src/reflect/scala/reflect/api/Exprs.scala
index 65b0eb9301..b86f36420d 100644
--- a/src/reflect/scala/reflect/api/Exprs.scala
+++ b/src/reflect/scala/reflect/api/Exprs.scala
@@ -12,14 +12,18 @@ trait Exprs { self: Universe =>
/** Expr wraps an expression tree and tags it with its type. */
trait Expr[+T] extends Equals with Serializable {
+ /**
+ * Underlying mirror of this expr.
+ */
val mirror: Mirror
+
/**
* Migrates the expression into another mirror, jumping into a different universe if necessary.
*
* This means that all symbolic references to classes/objects/packages in the expression
* will be re-resolved within the new mirror (typically using that mirror's classloader).
*/
- def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # Expr[T]
+ def in[U <: Universe with Singleton](otherMirror: scala.reflect.api.Mirror[U]): U # Expr[T]
/**
* The Scala syntax tree representing the wrapped expression.
@@ -91,13 +95,13 @@ trait Exprs { self: Universe =>
* in which case the tree first needs to be wrapped in an expr.
*/
object Expr {
- def apply[T: WeakTypeTag](mirror: MirrorOf[self.type], treec: TreeCreator): Expr[T] = new ExprImpl[T](mirror.asInstanceOf[Mirror], treec)
+ def apply[T: WeakTypeTag](mirror: scala.reflect.api.Mirror[self.type], treec: TreeCreator): Expr[T] = new ExprImpl[T](mirror.asInstanceOf[Mirror], treec)
def unapply[T](expr: Expr[T]): Option[Tree] = Some(expr.tree)
}
private class ExprImpl[+T: WeakTypeTag](val mirror: Mirror, val treec: TreeCreator) extends Expr[T] {
- def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # Expr[T] = {
- val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]]
+ def in[U <: Universe with Singleton](otherMirror: scala.reflect.api.Mirror[U]): U # Expr[T] = {
+ val otherMirror1 = otherMirror.asInstanceOf[scala.reflect.api.Mirror[otherMirror.universe.type]]
val tag1 = (implicitly[WeakTypeTag[T]] in otherMirror).asInstanceOf[otherMirror.universe.WeakTypeTag[T]]
otherMirror.universe.Expr[T](otherMirror1, treec)(tag1)
}
diff --git a/src/reflect/scala/reflect/api/FrontEnds.scala b/src/reflect/scala/reflect/api/FrontEnds.scala
deleted file mode 100644
index 61ea227c47..0000000000
--- a/src/reflect/scala/reflect/api/FrontEnds.scala
+++ /dev/null
@@ -1,70 +0,0 @@
-package scala.reflect
-package api
-
-trait FrontEnds {
-
- type Position >: Null
-
- trait FrontEnd {
- object severity extends Enumeration
- class Severity(val id: Int) extends severity.Value {
- var count: Int = 0
- override def toString() = this match {
- case INFO => "INFO"
- case WARNING => "WARNING"
- case ERROR => "ERROR"
- case _ => "<unknown>"
- }
- }
- val INFO = new Severity(0)
- val WARNING = new Severity(1)
- val ERROR = new Severity(2)
-
- def hasErrors = ERROR.count > 0
- def hasWarnings = WARNING.count > 0
-
- case class Info(val pos: Position, val msg: String, val severity: Severity)
- val infos = new scala.collection.mutable.LinkedHashSet[Info]
-
- /** Handles incoming info */
- def log(pos: Position, msg: String, severity: Severity) {
- infos += new Info(pos, msg, severity)
- severity.count += 1
- display(infos.last)
- }
-
- /** Displays incoming info */
- def display(info: Info): Unit
-
- /** Services a request to drop into interactive mode */
- def interactive(): Unit
-
- /** Refreshes the UI */
- def flush(): Unit = {}
-
- /** Resets the reporter */
- def reset(): Unit = {
- INFO.count = 0
- WARNING.count = 0
- ERROR.count = 0
- infos.clear()
- }
- }
-
- class SilentFrontEnd extends FrontEnd {
- def display(info: Info) {}
- def interactive() {}
- }
-
- /** Creates a UI-less reporter that simply accumulates all the messages
- */
- def mkSilentFrontEnd(): FrontEnd = new SilentFrontEnd()
-
- /** Creates a reporter that prints messages to the console according to the settings.
- *
- * ``minSeverity'' determines minimum severity of the messages to be printed.
- * 0 stands for INFO, 1 stands for WARNING and 2 stands for ERROR.
- */
- // todo. untangle warningsAsErrors from Reporters. I don't feel like moving this flag here!
- def mkConsoleFrontEnd(minSeverity: Int = 1): FrontEnd
-}
diff --git a/src/reflect/scala/reflect/api/JavaUniverse.scala b/src/reflect/scala/reflect/api/JavaUniverse.scala
index ba38381561..cc703e833d 100644
--- a/src/reflect/scala/reflect/api/JavaUniverse.scala
+++ b/src/reflect/scala/reflect/api/JavaUniverse.scala
@@ -7,7 +7,7 @@ trait JavaUniverse extends Universe with Mirrors { self =>
override type Mirror >: Null <: JavaMirror
- trait JavaMirror extends MirrorOf[self.type] with RuntimeMirror {
+ trait JavaMirror extends scala.reflect.api.Mirror[self.type] with RuntimeMirror {
val classLoader: ClassLoader
override def toString = s"JavaMirror with ${runtime.ReflectionUtils.show(classLoader)}"
}
@@ -23,7 +23,7 @@ trait JavaUniverse extends Universe with Mirrors { self =>
override def manifestToTypeTag[T](mirror0: Any, manifest: Manifest[T]): Universe # TypeTag[T] =
TypeTag(mirror0.asInstanceOf[Mirror], new TypeCreator {
- def apply[U <: Universe with Singleton](mirror: MirrorOf[U]): U # Type = {
+ def apply[U <: Universe with Singleton](mirror: scala.reflect.api.Mirror[U]): U # Type = {
mirror.universe match {
case ju: JavaUniverse =>
val jm = mirror.asInstanceOf[ju.Mirror]
diff --git a/src/reflect/scala/reflect/api/MirrorOf.scala b/src/reflect/scala/reflect/api/Mirror.scala
index cd5641e692..2de0d7120e 100644
--- a/src/reflect/scala/reflect/api/MirrorOf.scala
+++ b/src/reflect/scala/reflect/api/Mirror.scala
@@ -8,13 +8,13 @@ package api
*
* This is defined outside the reflection universe cake pattern implementation
* so that it can be referenced from outside. For example TypeCreator and TreeCreator
- * reference MirrorOf and also need to be defined outside the cake as they are
+ * reference Mirror and also need to be defined outside the cake as they are
* used by type tags, which can be migrated between different universes and consequently
* cannot be bound to a fixed one.
*
* @see [[Mirrors]]
*/
-abstract class MirrorOf[U <: Universe with Singleton] {
+abstract class Mirror[U <: Universe with Singleton] {
/** The universe this mirror belongs to. */
val universe: U
diff --git a/src/reflect/scala/reflect/api/Mirrors.scala b/src/reflect/scala/reflect/api/Mirrors.scala
index c935533027..bff899daa4 100644
--- a/src/reflect/scala/reflect/api/Mirrors.scala
+++ b/src/reflect/scala/reflect/api/Mirrors.scala
@@ -11,8 +11,12 @@ package api
*/
trait Mirrors { self: Universe =>
- /** The base type of all mirrors of this universe */
- type Mirror >: Null <: MirrorOf[self.type]
+ /** The base type of all mirrors of this universe.
+ *
+ * This abstract type conforms the base interface for all mirrors defined in [[scala.reflect.api.Mirror]]
+ * and is gradually refined in specific universes (e.g. `Mirror` of a [[scala.reflect.api.JavaUniverse]] is capable of reflection).
+ */
+ type Mirror >: Null <: scala.reflect.api.Mirror[self.type]
/** The root mirror of this universe. This mirror contains standard Scala classes and types such as `Any`, `AnyRef`, `AnyVal`,
* `Nothing`, `Null`, and all classes loaded from scala-library, which are shared across all mirrors within the enclosing universe.
@@ -239,7 +243,7 @@ trait Mirrors { self: Universe =>
}
/** A mirror that reflects instances and static classes */
- trait ReflectiveMirror extends MirrorOf[Mirrors.this.type] {
+ trait ReflectiveMirror extends scala.reflect.api.Mirror[Mirrors.this.type] {
/** A reflective mirror for the given object.
*
diff --git a/src/reflect/scala/reflect/api/Position.scala b/src/reflect/scala/reflect/api/Position.scala
new file mode 100644
index 0000000000..9c63e4becf
--- /dev/null
+++ b/src/reflect/scala/reflect/api/Position.scala
@@ -0,0 +1,167 @@
+package scala.reflect
+package api
+
+/** The Position class and its subclasses represent positions of ASTs and symbols.
+ * Except for NoPosition and FakePos, every position refers to a SourceFile
+ * and to an offset in the sourcefile (its `point`). For batch compilation,
+ * that's all. For interactive IDE's there are also RangePositions
+ * and TransparentPositions. A RangePosition indicates a start and an end
+ * in addition to its point. TransparentPositions are a subclass of RangePositions.
+ * Range positions that are not transparent are called opaque.
+ * Trees with RangePositions need to satisfy the following invariants.
+ *
+ * INV1: A tree with an offset position never contains a child
+ * with a range position
+ * INV2: If the child of a tree with a range position also has a range position,
+ * then the child's range is contained in the parent's range.
+ * INV3: Opaque range positions of children of the same node are non-overlapping
+ * (this means their overlap is at most a single point).
+ *
+ * The following tests are useful on positions:
+ *
+ * pos.isDefined true if position is not a NoPosition nor a FakePosition
+ * pos.isRange true if position is a range
+ * pos.isOpaqueRange true if position is an opaque range
+ *
+ * The following accessor methods are provided:
+ *
+ * pos.source The source file of the position, which must be defined
+ * pos.point The offset of the position's point, which must be defined
+ * pos.start The start of the position, which must be a range
+ * pos.end The end of the position, which must be a range
+ *
+ * There are also convenience methods, such as
+ *
+ * pos.startOrPoint
+ * pos.endOrPoint
+ * pos.pointOrElse(default)
+ *
+ * These are less strict about the kind of position on which they can be applied.
+ *
+ * The following conversion methods are often used:
+ *
+ * pos.focus converts a range position to an offset position, keeping its point;
+ * returns all other positions unchanged.
+ * pos.makeTransparent converts an opaque range position into a transparent one.
+ * returns all other positions unchanged.
+ */
+trait Position extends Attachments {
+
+ type Pos >: Null <: Position
+
+ /** Java file corresponding to the source file of this position.
+ *
+ * The return type is [[scala.reflect.io.AbstractFile]], which belongs to an experimental part of Scala reflection.
+ * It should not be used unless you know what you are doing. In subsequent releases, this API will be refined
+ * and exposed as a part of scala.reflect.api.
+ */
+ def source: scala.reflect.internal.util.SourceFile
+
+ /** Is this position neither a NoPosition nor a FakePosition?
+ * If isDefined is true, offset and source are both defined.
+ */
+ def isDefined: Boolean
+
+ /** Is this position a range position? */
+ def isRange: Boolean
+
+ /** Is this position a transparent position? */
+ def isTransparent: Boolean
+
+ /** Is this position a non-transparent range position? */
+ def isOpaqueRange: Boolean
+
+ /** if opaque range, make this position transparent */
+ def makeTransparent: Pos
+
+ /** The start of the position's range, error if not a range position */
+ def start: Int
+
+ /** The start of the position's range, or point if not a range position */
+ def startOrPoint: Int
+
+ /** The point (where the ^ is) of the position */
+ def point: Int
+
+ /** The point (where the ^ is) of the position, or else `default` if undefined */
+ def pointOrElse(default: Int): Int
+
+ /** The end of the position's range, error if not a range position */
+ def end: Int
+
+ /** The end of the position's range, or point if not a range position */
+ def endOrPoint: Int
+
+ /** The same position with a different start value (if a range) */
+ def withStart(off: Int): Pos
+
+ /** The same position with a different end value (if a range) */
+ def withEnd(off: Int): Pos
+
+ /** The same position with a different point value (if a range or offset) */
+ def withPoint(off: Int): Pos
+
+ /** If this is a range, the union with the other range, with the point of this position.
+ * Otherwise, this position
+ */
+ def union(pos: Pos): Pos
+
+ /** If this is a range position, the offset position of its point.
+ * Otherwise the position itself
+ */
+ def focus: Pos
+
+ /** If this is a range position, the offset position of its start.
+ * Otherwise the position itself
+ */
+ def focusStart: Pos
+
+ /** If this is a range position, the offset position of its end.
+ * Otherwise the position itself
+ */
+ def focusEnd: Pos
+
+ /** Does this position include the given position `pos`.
+ * This holds if `this` is a range position and its range [start..end]
+ * is the same or covers the range of the given position, which may or may not be a range position.
+ */
+ def includes(pos: Pos): Boolean
+
+ /** Does this position properly include the given position `pos` ("properly" meaning their
+ * ranges are not the same)?
+ */
+ def properlyIncludes(pos: Pos): Boolean
+
+ /** Does this position precede that position?
+ * This holds if both positions are defined and the end point of this position
+ * is not larger than the start point of the given position.
+ */
+ def precedes(pos: Pos): Boolean
+
+ /** Does this position properly precede the given position `pos` ("properly" meaning their ranges
+ * do not share a common point).
+ */
+ def properlyPrecedes(pos: Pos): Boolean
+
+ /** Does this position overlap with that position?
+ * This holds if both positions are ranges and there is an interval of
+ * non-zero length that is shared by both position ranges.
+ */
+ def overlaps(pos: Pos): Boolean
+
+ /** Does this position cover the same range as that position?
+ * Holds only if both position are ranges
+ */
+ def sameRange(pos: Pos): Boolean
+
+ def line: Int
+
+ def column: Int
+
+ /** Convert this to a position around `point` that spans a single source line */
+ def toSingleLine: Pos
+
+ def lineContent: String
+
+ def show: String
+}
diff --git a/src/reflect/scala/reflect/api/Positions.scala b/src/reflect/scala/reflect/api/Positions.scala
index 0eddc88fc4..5c530e7e70 100644
--- a/src/reflect/scala/reflect/api/Positions.scala
+++ b/src/reflect/scala/reflect/api/Positions.scala
@@ -10,7 +10,7 @@ trait Positions {
self: Universe =>
/** .. */
- type Position >: Null <: PositionApi { type Pos = Position }
+ type Position >: Null <: scala.reflect.api.Position { type Pos = Position }
/** A tag that preserves the identity of the `Position` abstract type from erasure.
* Can be used for pattern matching, instance tests, serialization and likes.
@@ -38,168 +38,3 @@ trait Positions {
*/
def wrappingPos(trees: List[Tree]): Position
}
-
-/** The Position class and its subclasses represent positions of ASTs and symbols.
- * Except for NoPosition and FakePos, every position refers to a SourceFile
- * and to an offset in the sourcefile (its `point`). For batch compilation,
- * that's all. For interactive IDE's there are also RangePositions
- * and TransparentPositions. A RangePosition indicates a start and an end
- * in addition to its point. TransparentPositions are a subclass of RangePositions.
- * Range positions that are not transparent are called opaque.
- * Trees with RangePositions need to satisfy the following invariants.
- *
- * INV1: A tree with an offset position never contains a child
- * with a range position
- * INV2: If the child of a tree with a range position also has a range position,
- * then the child's range is contained in the parent's range.
- * INV3: Opaque range positions of children of the same node are non-overlapping
- * (this means their overlap is at most a single point).
- *
- * The following tests are useful on positions:
- *
- * pos.isDefined true if position is not a NoPosition nor a FakePosition
- * pos.isRange true if position is a range
- * pos.isOpaqueRange true if position is an opaque range
- *
- * The following accessor methods are provided:
- *
- * pos.source The source file of the position, which must be defined
- * pos.point The offset of the position's point, which must be defined
- * pos.start The start of the position, which must be a range
- * pos.end The end of the position, which must be a range
- *
- * There are also convenience methods, such as
- *
- * pos.startOrPoint
- * pos.endOrPoint
- * pos.pointOrElse(default)
- *
- * These are less strict about the kind of position on which they can be applied.
- *
- * The following conversion methods are often used:
- *
- * pos.focus converts a range position to an offset position, keeping its point;
- * returns all other positions unchanged.
- * pos.makeTransparent converts an opaque range position into a transparent one.
- * returns all other positions unchanged.
- */
-trait PositionApi extends Attachments {
-
- type Pos >: Null <: PositionApi
-
- /** Java file corresponding to the source file of this position.
- */
- def fileInfo: java.io.File
-
- /** Content of the source file that contains this position.
- */
- def fileContent: Array[Char]
-
- /** Is this position neither a NoPosition nor a FakePosition?
- * If isDefined is true, offset and source are both defined.
- */
- def isDefined: Boolean
-
- /** Is this position a range position? */
- def isRange: Boolean
-
- /** Is this position a transparent position? */
- def isTransparent: Boolean
-
- /** Is this position a non-transparent range position? */
- def isOpaqueRange: Boolean
-
- /** if opaque range, make this position transparent */
- def makeTransparent: Pos
-
- /** The start of the position's range, error if not a range position */
- def start: Int
-
- /** The start of the position's range, or point if not a range position */
- def startOrPoint: Int
-
- /** The point (where the ^ is) of the position */
- def point: Int
-
- /** The point (where the ^ is) of the position, or else `default` if undefined */
- def pointOrElse(default: Int): Int
-
- /** The end of the position's range, error if not a range position */
- def end: Int
-
- /** The end of the position's range, or point if not a range position */
- def endOrPoint: Int
-
- /** The same position with a different start value (if a range) */
- def withStart(off: Int): Pos
-
- /** The same position with a different end value (if a range) */
- def withEnd(off: Int): Pos
-
- /** The same position with a different point value (if a range or offset) */
- def withPoint(off: Int): Pos
-
- /** If this is a range, the union with the other range, with the point of this position.
- * Otherwise, this position
- */
- def union(pos: Pos): Pos
-
- /** If this is a range position, the offset position of its point.
- * Otherwise the position itself
- */
- def focus: Pos
-
- /** If this is a range position, the offset position of its start.
- * Otherwise the position itself
- */
- def focusStart: Pos
-
- /** If this is a range position, the offset position of its end.
- * Otherwise the position itself
- */
- def focusEnd: Pos
-
- /** Does this position include the given position `pos`.
- * This holds if `this` is a range position and its range [start..end]
- * is the same or covers the range of the given position, which may or may not be a range position.
- */
- def includes(pos: Pos): Boolean
-
- /** Does this position properly include the given position `pos` ("properly" meaning their
- * ranges are not the same)?
- */
- def properlyIncludes(pos: Pos): Boolean
-
- /** Does this position precede that position?
- * This holds if both positions are defined and the end point of this position
- * is not larger than the start point of the given position.
- */
- def precedes(pos: Pos): Boolean
-
- /** Does this position properly precede the given position `pos` ("properly" meaning their ranges
- * do not share a common point).
- */
- def properlyPrecedes(pos: Pos): Boolean
-
- /** Does this position overlap with that position?
- * This holds if both positions are ranges and there is an interval of
- * non-zero length that is shared by both position ranges.
- */
- def overlaps(pos: Pos): Boolean
-
- /** Does this position cover the same range as that position?
- * Holds only if both position are ranges
- */
- def sameRange(pos: Pos): Boolean
-
- def line: Int
-
- def column: Int
-
- /** Convert this to a position around `point` that spans a single source line */
- def toSingleLine: Pos
-
- def lineContent: String
-
- def show: String
-}
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index d8f955ddf3..8b24b953ae 100644
--- a/src/reflect/scala/reflect/api/Symbols.scala
+++ b/src/reflect/scala/reflect/api/Symbols.scala
@@ -86,10 +86,10 @@ trait Symbols { self: Universe =>
* that directly contains the current symbol's definition.
* The `NoSymbol` symbol does not have an owner, and calling this method
* on one causes an internal error.
- * The owner of the Scala root class [[scala.reflect.api.MirrorOf.RootClass]]
- * and the Scala root object [[scala.reflect.api.MirrorOf.RootPackage]] is `NoSymbol`.
+ * The owner of the Scala root class [[scala.reflect.api.Mirror.RootClass]]
+ * and the Scala root object [[scala.reflect.api.Mirror.RootPackage]] is `NoSymbol`.
* Every other symbol has a chain of owners that ends in
- * [[scala.reflect.api.MirrorOf.RootClass]].
+ * [[scala.reflect.api.Mirror.RootClass]].
*/
def owner: Symbol
@@ -209,6 +209,10 @@ trait Symbols { self: Universe =>
/** Source file if this symbol is created during this compilation run,
* or a class file if this symbol is loaded from a *.class or *.jar.
+ *
+ * The return type is [[scala.reflect.io.AbstractFile]], which belongs to an experimental part of Scala reflection.
+ * It should not be used unless you know what you are doing. In subsequent releases, this API will be refined
+ * and exposed as a part of scala.reflect.api.
*/
def associatedFile: scala.reflect.io.AbstractFile
diff --git a/src/reflect/scala/reflect/api/TreeCreator.scala b/src/reflect/scala/reflect/api/TreeCreator.scala
index 0c8701775c..a8e8ae1b58 100644
--- a/src/reflect/scala/reflect/api/TreeCreator.scala
+++ b/src/reflect/scala/reflect/api/TreeCreator.scala
@@ -22,5 +22,5 @@ package api
* `TreeCreator` can't have a functional type, so it's implemented as class with an apply method.
*/
abstract class TreeCreator {
- def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Tree
+ def apply[U <: Universe with Singleton](m: scala.reflect.api.Mirror[U]): U # Tree
}
diff --git a/src/reflect/scala/reflect/api/TypeCreator.scala b/src/reflect/scala/reflect/api/TypeCreator.scala
index cc6d38c548..2b3ef4320b 100644
--- a/src/reflect/scala/reflect/api/TypeCreator.scala
+++ b/src/reflect/scala/reflect/api/TypeCreator.scala
@@ -22,5 +22,5 @@ package api
* `TypeCreator` can't have a functional type, so it's implemented as class with an apply method.
*/
abstract class TypeCreator {
- def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Type
+ def apply[U <: Universe with Singleton](m: scala.reflect.api.Mirror[U]): U # Type
}
diff --git a/src/reflect/scala/reflect/api/TypeTags.scala b/src/reflect/scala/reflect/api/TypeTags.scala
index a7e58d2bcb..fc3f067a96 100644
--- a/src/reflect/scala/reflect/api/TypeTags.scala
+++ b/src/reflect/scala/reflect/api/TypeTags.scala
@@ -154,19 +154,17 @@ trait TypeTags { self: Universe =>
@annotation.implicitNotFound(msg = "No WeakTypeTag available for ${T}")
trait WeakTypeTag[T] extends Equals with Serializable {
/**
- * Mirror corresponding to the universe of this WeakTypeTag.
+ * Underlying mirror of this type tag.
*/
val mirror: Mirror
+
/**
- * Migrates type tag to another universe.
- *
- * Type tags are path dependent on their universe. This methods allows migration
- * given the mirror corresponding to the target universe.
+ * Migrates the expression into another mirror, jumping into a different universe if necessary.
*
* Migration means that all symbolic references to classes/objects/packages in the expression
* will be re-resolved within the new mirror (typically using that mirror's classloader).
*/
- def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # WeakTypeTag[T]
+ def in[U <: Universe with Singleton](otherMirror: scala.reflect.api.Mirror[U]): U # WeakTypeTag[T]
/**
* Reflective representation of type T.
@@ -201,7 +199,7 @@ trait TypeTags { self: Universe =>
val Null : WeakTypeTag[scala.Null] = TypeTag.Null
- def apply[T](mirror1: MirrorOf[self.type], tpec1: TypeCreator): WeakTypeTag[T] =
+ def apply[T](mirror1: scala.reflect.api.Mirror[self.type], tpec1: TypeCreator): WeakTypeTag[T] =
tpec1(mirror1) match {
case ByteTpe => WeakTypeTag.Byte.asInstanceOf[WeakTypeTag[T]]
case ShortTpe => WeakTypeTag.Short.asInstanceOf[WeakTypeTag[T]]
@@ -226,8 +224,8 @@ trait TypeTags { self: Universe =>
private class WeakTypeTagImpl[T](val mirror: Mirror, val tpec: TypeCreator) extends WeakTypeTag[T] {
lazy val tpe: Type = tpec(mirror)
- def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # WeakTypeTag[T] = {
- val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]]
+ def in[U <: Universe with Singleton](otherMirror: scala.reflect.api.Mirror[U]): U # WeakTypeTag[T] = {
+ val otherMirror1 = otherMirror.asInstanceOf[scala.reflect.api.Mirror[otherMirror.universe.type]]
otherMirror.universe.WeakTypeTag[T](otherMirror1, tpec)
}
private def writeReplace(): AnyRef = new SerializedTypeTag(tpec, concrete = false)
@@ -245,7 +243,7 @@ trait TypeTags { self: Universe =>
/**
* @inheritdoc
*/
- override def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # TypeTag[T]
+ override def in[U <: Universe with Singleton](otherMirror: scala.reflect.api.Mirror[U]): U # TypeTag[T]
// case class accessories
override def canEqual(x: Any) = x.isInstanceOf[TypeTag[_]]
@@ -271,7 +269,7 @@ trait TypeTags { self: Universe =>
val Nothing: TypeTag[scala.Nothing] = new PredefTypeTag[scala.Nothing] (NothingTpe, _.TypeTag.Nothing)
val Null: TypeTag[scala.Null] = new PredefTypeTag[scala.Null] (NullTpe, _.TypeTag.Null)
- def apply[T](mirror1: MirrorOf[self.type], tpec1: TypeCreator): TypeTag[T] =
+ def apply[T](mirror1: scala.reflect.api.Mirror[self.type], tpec1: TypeCreator): TypeTag[T] =
tpec1(mirror1) match {
case ByteTpe => TypeTag.Byte.asInstanceOf[TypeTag[T]]
case ShortTpe => TypeTag.Short.asInstanceOf[TypeTag[T]]
@@ -295,15 +293,15 @@ trait TypeTags { self: Universe =>
}
private class TypeTagImpl[T](mirror: Mirror, tpec: TypeCreator) extends WeakTypeTagImpl[T](mirror, tpec) with TypeTag[T] {
- override def in[U <: Universe with Singleton](otherMirror: MirrorOf[U]): U # TypeTag[T] = {
- val otherMirror1 = otherMirror.asInstanceOf[MirrorOf[otherMirror.universe.type]]
+ override def in[U <: Universe with Singleton](otherMirror: scala.reflect.api.Mirror[U]): U # TypeTag[T] = {
+ val otherMirror1 = otherMirror.asInstanceOf[scala.reflect.api.Mirror[otherMirror.universe.type]]
otherMirror.universe.TypeTag[T](otherMirror1, tpec)
}
private def writeReplace(): AnyRef = new SerializedTypeTag(tpec, concrete = true)
}
private class PredefTypeCreator[T](copyIn: Universe => Universe#TypeTag[T]) extends TypeCreator {
- def apply[U <: Universe with Singleton](m: MirrorOf[U]): U # Type = {
+ def apply[U <: Universe with Singleton](m: scala.reflect.api.Mirror[U]): U # Type = {
copyIn(m.universe).asInstanceOf[U # TypeTag[T]].tpe
}
}
diff --git a/src/reflect/scala/reflect/internal/AnnotationCheckers.scala b/src/reflect/scala/reflect/internal/AnnotationCheckers.scala
index 9f102c5712..05f80c8a0c 100644
--- a/src/reflect/scala/reflect/internal/AnnotationCheckers.scala
+++ b/src/reflect/scala/reflect/internal/AnnotationCheckers.scala
@@ -47,6 +47,13 @@ trait AnnotationCheckers {
* before. If the implementing class cannot do the adaptiong, it
* should return the tree unchanged.*/
def adaptAnnotations(tree: Tree, mode: Int, pt: Type): Tree = tree
+
+ /** Adapt the type of a return expression. The decision of an annotation checker
+ * whether the type should be adapted is based on the type of the expression
+ * which is returned, as well as the result type of the method (pt).
+ * By default, this method simply returns the passed `default` type.
+ */
+ def adaptTypeOfReturn(tree: Tree, pt: Type, default: => Type): Type = default
}
// Syncnote: Annotation checkers inaccessible to reflection, so no sync in var necessary.
@@ -118,4 +125,23 @@ trait AnnotationCheckers {
annotationCheckers.foldLeft(tree)((tree, checker) =>
checker.adaptAnnotations(tree, mode, pt))
}
+
+ /** Let a registered annotation checker adapt the type of a return expression.
+ * Annotation checkers that cannot do the adaptation should simply return
+ * the `default` argument.
+ *
+ * Note that the result is undefined if more than one annotation checker
+ * returns an adapted type which is not a subtype of `default`.
+ */
+ def adaptTypeOfReturn(tree: Tree, pt: Type, default: => Type): Type = {
+ val adaptedTypes = annotationCheckers flatMap { checker =>
+ val adapted = checker.adaptTypeOfReturn(tree, pt, default)
+ if (!(adapted <:< default)) List(adapted)
+ else List()
+ }
+ adaptedTypes match {
+ case fst :: _ => fst
+ case List() => default
+ }
+ }
}
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index dc0c002ea7..abf11020fa 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -520,7 +520,7 @@ trait Definitions extends api.StandardDefinitions {
def ApiUniverseReify = if (ApiUniverseClass != NoSymbol) getMemberMethod(ApiUniverseClass, nme.reify) else NoSymbol
lazy val JavaUniverseClass = getClassIfDefined("scala.reflect.api.JavaUniverse") // defined in scala-reflect.jar, so we need to be careful
- lazy val MirrorOfClass = getClassIfDefined("scala.reflect.api.MirrorOf") // defined in scala-reflect.jar, so we need to be careful
+ lazy val MirrorClass = getClassIfDefined("scala.reflect.api.Mirror") // defined in scala-reflect.jar, so we need to be careful
lazy val TypeCreatorClass = getClassIfDefined("scala.reflect.api.TypeCreator") // defined in scala-reflect.jar, so we need to be careful
lazy val TreeCreatorClass = getClassIfDefined("scala.reflect.api.TreeCreator") // defined in scala-reflect.jar, so we need to be careful
diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala
index 4836db5db0..019cf7f908 100644
--- a/src/reflect/scala/reflect/internal/Mirrors.scala
+++ b/src/reflect/scala/reflect/internal/Mirrors.scala
@@ -19,7 +19,7 @@ trait Mirrors extends api.Mirrors {
// if there are any symbols created by that mirror
trait RootSymbol extends Symbol { def mirror: Mirror }
- abstract class RootsBase(rootOwner: Symbol) extends MirrorOf[Mirrors.this.type] { thisMirror =>
+ abstract class RootsBase(rootOwner: Symbol) extends scala.reflect.api.Mirror[Mirrors.this.type] { thisMirror =>
protected[scala] def rootLoader: LazyType
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index 4c423e0bc2..cb8dc4b197 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -580,7 +580,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
else print(sym.name)
if (printIds) print("#", sym.id)
if (printKinds) print("#", sym.abbreviatedKindString)
- if (printMirrors) print("%M", footnotes.put[MirrorOf[_]](mirrorThatLoaded(sym)))
+ if (printMirrors) print("%M", footnotes.put[scala.reflect.api.Mirror[_]](mirrorThatLoaded(sym)))
case NoType =>
print("NoType")
case NoPrefix =>
@@ -609,7 +609,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
if (depth == 0 && !printingFootnotes) {
printingFootnotes = true
footnotes.print[Type](this)
- footnotes.print[MirrorOf[_]](this)
+ footnotes.print[scala.reflect.api.Mirror[_]](this)
printingFootnotes = false
}
}
diff --git a/src/reflect/scala/reflect/internal/StdCreators.scala b/src/reflect/scala/reflect/internal/StdCreators.scala
index eba583d4b5..5e5e4f9043 100644
--- a/src/reflect/scala/reflect/internal/StdCreators.scala
+++ b/src/reflect/scala/reflect/internal/StdCreators.scala
@@ -7,14 +7,14 @@ import scala.reflect.api.{Universe => ApiUniverse}
trait StdCreators {
self: SymbolTable =>
- case class FixedMirrorTreeCreator(mirror: MirrorOf[StdCreators.this.type], tree: Tree) extends TreeCreator {
- def apply[U <: ApiUniverse with Singleton](m: MirrorOf[U]): U # Tree =
+ case class FixedMirrorTreeCreator(mirror: scala.reflect.api.Mirror[StdCreators.this.type], tree: Tree) extends TreeCreator {
+ def apply[U <: ApiUniverse with Singleton](m: scala.reflect.api.Mirror[U]): U # Tree =
if (m eq mirror) tree.asInstanceOf[U # Tree]
else throw new IllegalArgumentException(s"Expr defined in $mirror cannot be migrated to other mirrors.")
}
- case class FixedMirrorTypeCreator(mirror: MirrorOf[StdCreators.this.type], tpe: Type) extends TypeCreator {
- def apply[U <: ApiUniverse with Singleton](m: MirrorOf[U]): U # Type =
+ case class FixedMirrorTypeCreator(mirror: scala.reflect.api.Mirror[StdCreators.this.type], tpe: Type) extends TypeCreator {
+ def apply[U <: ApiUniverse with Singleton](m: scala.reflect.api.Mirror[U]): U # Type =
if (m eq mirror) tpe.asInstanceOf[U # Type]
else throw new IllegalArgumentException(s"Type tag defined in $mirror cannot be migrated to other mirrors.")
}
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index 2cdfb05e77..eacbf6a0cc 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -346,6 +346,16 @@ trait StdNames {
def isSingletonName(name: Name) = name endsWith SINGLETON_SUFFIX
def isModuleName(name: Name) = name endsWith MODULE_SUFFIX_NAME
+ /** Is name a variable name? */
+ def isVariableName(name: Name): Boolean = {
+ val first = name.startChar
+ ( ((first.isLower && first.isLetter) || first == '_')
+ && (name != nme.false_)
+ && (name != nme.true_)
+ && (name != nme.null_)
+ )
+ }
+
def isDeprecatedIdentifierName(name: Name) = name.toTermName match {
case nme.`then` | nme.`macro` => true
case _ => false
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 77cbbd936b..db062d138f 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -247,7 +247,7 @@ abstract class TreeInfo {
/** Is tree a variable pattern? */
def isVarPattern(pat: Tree): Boolean = pat match {
- case x: Ident => !x.isBackquoted && isVariableName(x.name)
+ case x: Ident => !x.isBackquoted && nme.isVariableName(x.name)
case _ => false
}
def isDeprecatedIdentifier(tree: Tree): Boolean = tree match {
@@ -312,14 +312,6 @@ abstract class TreeInfo {
/** Is name a left-associative operator? */
def isLeftAssoc(operator: Name) = operator.nonEmpty && (operator.endChar != ':')
- private val reserved = Set[Name](nme.false_, nme.true_, nme.null_)
-
- /** Is name a variable name? */
- def isVariableName(name: Name): Boolean = {
- val first = name.startChar
- ((first.isLower && first.isLetter) || first == '_') && !reserved(name)
- }
-
/** Is tree a `this` node which belongs to `enclClass`? */
def isSelf(tree: Tree, enclClass: Symbol): Boolean = tree match {
case This(_) => tree.symbol == enclClass
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index f6af515fa3..2c036b3308 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -5748,6 +5748,13 @@ trait Types extends api.Types { self: SymbolTable =>
case _ => false
}
+ def isNonRefinementClassType(tpe: Type) = tpe match {
+ case SingleType(_, sym) => sym.isModuleClass
+ case TypeRef(_, sym, _) => sym.isClass && !sym.isRefinementClass
+ case ErrorType => true
+ case _ => false
+ }
+
// @assume tp1.isHigherKinded || tp2.isHigherKinded
def isHKSubType0(tp1: Type, tp2: Type, depth: Int): Boolean = (
tp1.typeSymbol == NothingClass
diff --git a/src/reflect/scala/reflect/internal/package.scala b/src/reflect/scala/reflect/internal/package.scala
deleted file mode 100644
index 63568f6a6b..0000000000
--- a/src/reflect/scala/reflect/internal/package.scala
+++ /dev/null
@@ -1,6 +0,0 @@
-package scala.reflect
-
-package object internal {
-
- type MirrorOf[U <: scala.reflect.api.Universe with Singleton] = scala.reflect.api.MirrorOf[U]
-}
diff --git a/src/reflect/scala/reflect/internal/util/Collections.scala b/src/reflect/scala/reflect/internal/util/Collections.scala
index 14b5d3003d..201b4dfe0a 100644
--- a/src/reflect/scala/reflect/internal/util/Collections.scala
+++ b/src/reflect/scala/reflect/internal/util/Collections.scala
@@ -175,6 +175,20 @@ trait Collections {
}
false
}
+ final def exists3[A, B, C](xs1: List[A], xs2: List[B], xs3: List[C])(f: (A, B, C) => Boolean): Boolean = {
+ var ys1 = xs1
+ var ys2 = xs2
+ var ys3 = xs3
+ while (!ys1.isEmpty && !ys2.isEmpty && !ys3.isEmpty) {
+ if (f(ys1.head, ys2.head, ys3.head))
+ return true
+
+ ys1 = ys1.tail
+ ys2 = ys2.tail
+ ys3 = ys3.tail
+ }
+ false
+ }
final def forall2[A, B](xs1: List[A], xs2: List[B])(f: (A, B) => Boolean): Boolean = {
var ys1 = xs1
var ys2 = xs2
diff --git a/src/reflect/scala/reflect/internal/util/Position.scala b/src/reflect/scala/reflect/internal/util/Position.scala
index 1621fb84d4..151a64daff 100644
--- a/src/reflect/scala/reflect/internal/util/Position.scala
+++ b/src/reflect/scala/reflect/internal/util/Position.scala
@@ -8,7 +8,6 @@ package scala.reflect.internal.util
import scala.reflect.ClassTag
import scala.reflect.api.Attachments
-import scala.reflect.api.PositionApi
object Position {
val tabInc = 8
@@ -36,7 +35,7 @@ object Position {
}
}
-abstract class Position extends PositionApi { self =>
+abstract class Position extends scala.reflect.api.Position { self =>
type Pos = Position
@@ -44,16 +43,6 @@ abstract class Position extends PositionApi { self =>
def withPos(newPos: Position): Attachments { type Pos = self.Pos } = newPos
- /** Java file corresponding to the source file of this position.
- */
- // necessary for conformance with scala.reflect.api.Position
- def fileInfo: java.io.File = source.file.file
-
- /** Contents of the source file that contains this position.
- */
- // necessary for conformance with scala.reflect.api.Position
- def fileContent: Array[Char] = source.content
-
/** An optional value containing the source file referred to by this position, or
* None if not defined.
*/
diff --git a/src/reflect/scala/reflect/macros/Aliases.scala b/src/reflect/scala/reflect/macros/Aliases.scala
index eff7f34b02..754335d50d 100644
--- a/src/reflect/scala/reflect/macros/Aliases.scala
+++ b/src/reflect/scala/reflect/macros/Aliases.scala
@@ -10,17 +10,22 @@ trait Aliases {
type TermName = universe.TermName
type TypeName = universe.TypeName
type Tree = universe.Tree
- // type Position = universe.Position
+ type Position = universe.Position
type Scope = universe.Scope
type Modifiers = universe.Modifiers
+ type Run = universe.Run
+ type CompilationUnit = universe.CompilationUnit
type Expr[+T] = universe.Expr[T]
val Expr = universe.Expr
+ def Expr[T: WeakTypeTag](tree: Tree): Expr[T]
type WeakTypeTag[T] = universe.WeakTypeTag[T]
type TypeTag[T] = universe.TypeTag[T]
val WeakTypeTag = universe.WeakTypeTag
val TypeTag = universe.TypeTag
+ def WeakTypeTag[T](tpe: Type): WeakTypeTag[T]
+ def TypeTag[T](tpe: Type): TypeTag[T]
def weakTypeTag[T](implicit attag: WeakTypeTag[T]) = attag
def typeTag[T](implicit ttag: TypeTag[T]) = ttag
def weakTypeOf[T](implicit attag: WeakTypeTag[T]): Type = attag.tpe
diff --git a/src/reflect/scala/reflect/macros/CapturedVariables.scala b/src/reflect/scala/reflect/macros/CapturedVariables.scala
deleted file mode 100644
index 60ed6f5e7b..0000000000
--- a/src/reflect/scala/reflect/macros/CapturedVariables.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-package scala.reflect
-package macros
-
-trait CapturedVariables {
- self: Context =>
-
- import mirror._
-
- /** Mark a variable as captured; i.e. force boxing in a *Ref type.
- */
- def captureVariable(vble: Symbol): Unit
-
- /** Mark given identifier as a reference to a captured variable itself
- * suppressing dereferencing with the `elem` field.
- */
- def referenceCapturedVariable(vble: Symbol): Tree
-
- /** Convert type of a captured variable to *Ref type.
- */
- def capturedVariableType(vble: Symbol): Type
-} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/macros/Context.scala b/src/reflect/scala/reflect/macros/Context.scala
index 37c8f9057e..7a365ed37b 100644
--- a/src/reflect/scala/reflect/macros/Context.scala
+++ b/src/reflect/scala/reflect/macros/Context.scala
@@ -6,17 +6,13 @@ package macros
// the full context should include all traits from scala.reflect.macros (and probably reside in scala-compiler.jar)
trait Context extends Aliases
- with CapturedVariables
with Enclosures
- with Infrastructure
with Names
with Reifiers
with FrontEnds
- with Settings
+ with Infrastructure
with Typers
with Parsers
- with Exprs
- with TypeTags
with Evals
with ExprUtils {
@@ -24,7 +20,7 @@ trait Context extends Aliases
val universe: Universe
/** The mirror of the compile-time universe */
- val mirror: MirrorOf[universe.type]
+ val mirror: universe.Mirror
/** The type of the prefix tree from which the macro is selected */
type PrefixType
diff --git a/src/reflect/scala/reflect/macros/Enclosures.scala b/src/reflect/scala/reflect/macros/Enclosures.scala
index a07ff85a08..218cf6ebb3 100644
--- a/src/reflect/scala/reflect/macros/Enclosures.scala
+++ b/src/reflect/scala/reflect/macros/Enclosures.scala
@@ -47,4 +47,8 @@ trait Enclosures {
/** Compilation unit that contains this macro application.
*/
val enclosingUnit: CompilationUnit
+
+ /** Compilation run that contains this macro application.
+ */
+ val enclosingRun: Run
} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/macros/Exprs.scala b/src/reflect/scala/reflect/macros/Exprs.scala
deleted file mode 100644
index 280d5508c8..0000000000
--- a/src/reflect/scala/reflect/macros/Exprs.scala
+++ /dev/null
@@ -1,8 +0,0 @@
-package scala.reflect
-package macros
-
-trait Exprs {
- self: Context =>
-
- def Expr[T: WeakTypeTag](tree: Tree): Expr[T]
-}
diff --git a/src/reflect/scala/reflect/macros/FrontEnds.scala b/src/reflect/scala/reflect/macros/FrontEnds.scala
index d15db0725f..e6b67cfc87 100644
--- a/src/reflect/scala/reflect/macros/FrontEnds.scala
+++ b/src/reflect/scala/reflect/macros/FrontEnds.scala
@@ -1,18 +1,9 @@
package scala.reflect
package macros
-trait FrontEnds extends scala.reflect.api.FrontEnds {
+trait FrontEnds {
self: Context =>
- import mirror._
-
- type Position = universe.Position
-
- /** Exposes means to control the compiler UI */
- def frontEnd: FrontEnd
- def setFrontEnd(frontEnd: FrontEnd): this.type
- def withFrontEnd[T](frontEnd: FrontEnd)(op: => T): T
-
/** For sending a message which should not be labeled as a warning/error,
* but also shouldn't require -verbose to be visible.
* Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''.
@@ -36,7 +27,4 @@ trait FrontEnds extends scala.reflect.api.FrontEnds {
* Use ``enclosingPosition'' if you're in doubt what position to pass to ``pos''.
*/
def abort(pos: Position, msg: String): Nothing
-
- /** Drops into interactive mode if supported by the compiler UI */
- def interactive(): Unit
} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/macros/Infrastructure.scala b/src/reflect/scala/reflect/macros/Infrastructure.scala
index 80153ff257..a1ef1c87a3 100644
--- a/src/reflect/scala/reflect/macros/Infrastructure.scala
+++ b/src/reflect/scala/reflect/macros/Infrastructure.scala
@@ -4,77 +4,16 @@ package macros
trait Infrastructure {
self: Context =>
- /** Determines whether the compiler expanding a macro targets JVM.
+ /** Exposes macro-specific settings as a list of strings.
+ * These settings are passed to the compiler via the "-Xmacro-settings:setting1,setting2...,settingN" command-line option.
*/
- val forJVM: Boolean
+ def settings: List[String]
- /** Determines whether the compiler expanding a macro targets CLR.
+ /** Exposes current compiler settings as a list of options.
+ * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
*/
- val forMSIL: Boolean
+ def compilerSettings: List[String]
- /** Determines whether the compiler expanding a macro is a presentation compiler.
- */
- val forInteractive: Boolean
-
- /** Determines whether the compiler expanding a macro is a Scaladoc compiler.
- */
- val forScaladoc: Boolean
-
- /** Exposes current compilation run.
- */
- val currentRun: Run
-
- /** Exposes library classpath.
- */
- val libraryClassPath: List[java.net.URL]
-
- /** Exposes a classloader that corresponds to the library classpath.
- *
- * With this classloader you can perform on-the-fly evaluation of macro arguments.
- * For example, consider this code snippet:
- *
- * def staticEval[T](x: T) = macro staticEval[T]
- *
- * def staticEval[T](c: Context)(x: c.Expr[T]) = {
- * import scala.reflect.runtime.{universe => ru}
- * val mirror = ru.runtimeMirror(c.libraryClassLoader)
- * import scala.tools.reflect.ToolBox
- * val toolBox = mirror.mkToolBox()
- * val importer = ru.mkImporter(c.universe).asInstanceOf[ru.Importer { val from: c.universe.type }]
- * val tree = c.resetAllAttrs(x.tree.duplicate)
- * val imported = importer.importTree(tree)
- * val valueOfX = toolBox.eval(imported).asInstanceOf[T]
- * ...
- * }
- */
- def libraryClassLoader: ClassLoader
-
- /** As seen by macro API, compilation run is an opaque type that can be deconstructed into:
- * 1) Current compilation unit
- * 2) List of all compilation units that comprise the run
- */
- type Run
-
- val Run: RunExtractor
-
- abstract class RunExtractor {
- def unapply(run: Run): Option[(CompilationUnit, List[CompilationUnit])]
- }
-
- /** As seen by macro API, compilation unit is an opaque type that can be deconstructed into:
- * 1) File that corresponds to the unit (if not applicable, null)
- * 2) Content of the file (if not applicable, empty array)
- * 3) Body, i.e. the AST that represents the compilation unit
- */
- type CompilationUnit
-
- val CompilationUnit: CompilationUnitExtractor
-
- abstract class CompilationUnitExtractor {
- def unapply(compilationUnit: CompilationUnit): Option[(java.io.File, Array[Char], Tree)]
- }
-
- /** Returns a macro definition which triggered this macro expansion.
- */
- val currentMacro: Symbol
-}
+ /** Exposes current classpath. */
+ def classPath: List[java.net.URL]
+} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/macros/Parsers.scala b/src/reflect/scala/reflect/macros/Parsers.scala
index 1742d07b60..c2d4d8a3ab 100644
--- a/src/reflect/scala/reflect/macros/Parsers.scala
+++ b/src/reflect/scala/reflect/macros/Parsers.scala
@@ -5,14 +5,10 @@ trait Parsers {
self: Context =>
/** .. */
- // todo. distinguish between `parse` and `parse`
+ // todo. distinguish between parsing an expression and parsing arbitrary code
+ // for example, parsing in expression mode will fail on packages
def parse(code: String): Tree
+}
- /** Represents an error during parsing
- */
- type ParseError <: Throwable
- val ParseError: ParseErrorExtractor
- abstract class ParseErrorExtractor {
- def unapply(error: ParseError): Option[(Position, String)]
- }
-} \ No newline at end of file
+// should be path-dependent, otherwise exception handling becomes a mess
+case class ParseError(val pos: scala.reflect.api.Position, val msg: String) extends Throwable(msg)
diff --git a/src/reflect/scala/reflect/macros/Reifiers.scala b/src/reflect/scala/reflect/macros/Reifiers.scala
index c2a6c5be05..ed31663c68 100644
--- a/src/reflect/scala/reflect/macros/Reifiers.scala
+++ b/src/reflect/scala/reflect/macros/Reifiers.scala
@@ -1,21 +1,14 @@
package scala.reflect
package macros
-import scala.reflect.api.PositionApi
-
trait Reifiers {
self: Context =>
- /** Reification prefix that refers to the runtime reflexive universe, ``scala.reflect.runtime.universe''.
- * Providing it for the ``prefix'' parameter of ``reifyTree'' or ``reifyType'' will create a full-fledged tree that can be inspected at runtime.
- */
- val runtimeUniverse: Tree
-
/** Given a tree, generate a tree that when compiled and executed produces the original tree.
* For more information and examples see the documentation for ``Universe.reify''.
*
* The produced tree will be bound to the specified ``universe'' and ``mirror''.
- * Possible values for ``universe'' include ``runtimeUniverse''.
+ * Possible values for ``universe'' include ``universe.treeBuild.mkRuntimeUniverseRef''.
* Possible values for ``mirror'' include ``EmptyTree'' (in that case the reifier will automatically pick an appropriate mirror).
*
* This function is deeply connected to ``Universe.reify'', a macro that reifies arbitrary expressions into runtime trees.
@@ -83,6 +76,6 @@ trait Reifiers {
// made these guys non path-dependent, otherwise exception handling quickly becomes a mess
-case class ReificationError(val pos: PositionApi, val msg: String) extends Throwable(msg)
+case class ReificationError(val pos: scala.reflect.api.Position, val msg: String) extends Throwable(msg)
-case class UnexpectedReificationError(val pos: PositionApi, val msg: String, val cause: Throwable = null) extends Throwable(msg, cause)
+case class UnexpectedReificationError(val pos: scala.reflect.api.Position, val msg: String, val cause: Throwable = null) extends Throwable(msg, cause)
diff --git a/src/reflect/scala/reflect/macros/Settings.scala b/src/reflect/scala/reflect/macros/Settings.scala
deleted file mode 100644
index a2cdb4c8e1..0000000000
--- a/src/reflect/scala/reflect/macros/Settings.scala
+++ /dev/null
@@ -1,36 +0,0 @@
-package scala.reflect
-package macros
-
-trait Settings {
- self: Context =>
-
- /** Exposes macro-specific settings as a list of strings.
- * These settings are passed to the compiler via the "-Xmacro-settings:setting1,setting2...,settingN" command-line option.
- */
- def settings: List[String]
-
- /** Exposes current compiler settings as a list of options.
- * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
- */
- 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.
- */
- def setCompilerSettings(options: String): this.type
-
- /** Updates current compiler settings with a list of options.
- * Use `scalac -help`, `scalac -X` and `scalac -Y` to learn about currently supported options.
- */
- def setCompilerSettings(options: List[String]): this.type
-
- /** 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
-
- /** 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
-} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/macros/TreeBuilder.scala b/src/reflect/scala/reflect/macros/TreeBuilder.scala
index ca29194859..5f18ab9ee8 100644
--- a/src/reflect/scala/reflect/macros/TreeBuilder.scala
+++ b/src/reflect/scala/reflect/macros/TreeBuilder.scala
@@ -53,4 +53,7 @@ abstract class TreeBuilder {
def mkMethodCall(receiver: Tree, method: Symbol, targs: List[Type], args: List[Tree]): Tree
def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree
def mkNullaryCall(method: Symbol, targs: List[Type]): Tree
+
+ /** A tree that refers to the runtime reflexive universe, ``scala.reflect.runtime.universe''. */
+ def mkRuntimeUniverseRef: Tree
}
diff --git a/src/reflect/scala/reflect/macros/TypeTags.scala b/src/reflect/scala/reflect/macros/TypeTags.scala
deleted file mode 100644
index 2f15e37f6a..0000000000
--- a/src/reflect/scala/reflect/macros/TypeTags.scala
+++ /dev/null
@@ -1,9 +0,0 @@
-package scala.reflect
-package macros
-
-trait TypeTags {
- self: Context =>
-
- def WeakTypeTag[T](tpe: Type): WeakTypeTag[T]
- def TypeTag[T](tpe: Type): TypeTag[T]
-}
diff --git a/src/reflect/scala/reflect/macros/Universe.scala b/src/reflect/scala/reflect/macros/Universe.scala
index f84c11ee63..97d0a8d98a 100644
--- a/src/reflect/scala/reflect/macros/Universe.scala
+++ b/src/reflect/scala/reflect/macros/Universe.scala
@@ -109,4 +109,52 @@ abstract class Universe extends scala.reflect.api.Universe {
trait IdentContextApi extends IdentApi { this: Ident =>
def isBackquoted: Boolean
}
+
+ /** Mark a variable as captured; i.e. force boxing in a *Ref type.
+ */
+ def captureVariable(vble: Symbol): Unit
+
+ /** Mark given identifier as a reference to a captured variable itself
+ * suppressing dereferencing with the `elem` field.
+ */
+ def referenceCapturedVariable(vble: Symbol): Tree
+
+ /** Convert type of a captured variable to *Ref type.
+ */
+ def capturedVariableType(vble: Symbol): Type
+
+ type Run <: RunContextApi
+
+ /** Compilation run uniquely identifies current invocation of the compiler
+ * (e.g. can be used to implement per-run caches for macros) and provides access to units of work
+ * of the invocation (currently processed unit of work and the list of all units).
+ */
+ trait RunContextApi {
+ /** Currently processed unit of work (a real or a virtual file). */
+ def currentUnit: CompilationUnit
+
+ /** All units of work comprising this compilation run. */
+ def units: Iterator[CompilationUnit]
+ }
+
+ type CompilationUnit <: CompilationUnitContextApi
+
+ /** Compilation unit describes a unit of work of the compilation run.
+ * It provides such information as file name, textual representation of the unit and the underlying AST.
+ */
+ trait CompilationUnitContextApi {
+ /** Source file corresponding to this compilation unit.
+ *
+ * Exposes information about the file as a part of a real or virtual file system
+ * along with the contents of that file.
+ *
+ * The return type is [[scala.reflect.io.AbstractFile]], which belongs to an experimental part of Scala reflection.
+ * It should not be used unless you know what you are doing. In subsequent releases, this API will be refined
+ * and exposed as a part of scala.reflect.api.
+ */
+ def source: scala.reflect.internal.util.SourceFile
+
+ /** The AST that corresponds to this compilation unit. */
+ def body: Tree
+ }
} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/macros/package.scala b/src/reflect/scala/reflect/macros/package.scala
deleted file mode 100644
index df93785d40..0000000000
--- a/src/reflect/scala/reflect/macros/package.scala
+++ /dev/null
@@ -1,6 +0,0 @@
-package scala.reflect
-
-package object macros {
-
- type MirrorOf[U <: scala.reflect.api.Universe with Singleton] = scala.reflect.api.MirrorOf[U]
-}