summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-02-19 10:37:09 +0100
committerJason Zaugg <jzaugg@gmail.com>2014-02-19 10:37:09 +0100
commit3973f29cec9f06724941b68577908f546341c45e (patch)
treef99466561254174a678818fd5bae566bd9742488 /src
parent3dbcb1b9d4daa5cba98747bbc66f898ba0f864fd (diff)
parent1714578eb8b4526de248c5a62e9aa175c5758b7c (diff)
downloadscala-3973f29cec9f06724941b68577908f546341c45e.tar.gz
scala-3973f29cec9f06724941b68577908f546341c45e.tar.bz2
scala-3973f29cec9f06724941b68577908f546341c45e.zip
Merge pull request #3452 from xeno-by/topic/palladium0
SI-8063 and its seventy friends
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Context.scala3
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Evals.scala2
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Internals.scala47
-rw-r--r--src/compiler/scala/reflect/macros/contexts/Typers.scala15
-rw-r--r--src/compiler/scala/reflect/reify/States.scala2
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenAnnotationInfos.scala17
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenSymbols.scala4
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenTrees.scala24
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenTypes.scala37
-rw-r--r--src/compiler/scala/reflect/reify/codegen/GenUtils.scala4
-rw-r--r--src/compiler/scala/reflect/reify/phases/Calculate.scala2
-rw-r--r--src/compiler/scala/reflect/reify/utils/Extractors.scala20
-rw-r--r--src/compiler/scala/reflect/reify/utils/NodePrinters.scala3
-rw-r--r--src/compiler/scala/reflect/reify/utils/SymbolTables.scala2
-rw-r--r--src/compiler/scala/tools/nsc/Global.scala13
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeGen.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/Trees.scala2
-rw-r--r--src/compiler/scala/tools/nsc/ast/parser/Parsers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala2
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala4
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala12
-rw-r--r--src/compiler/scala/tools/nsc/transform/Delambdafy.scala4
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala8
-rw-r--r--src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala2
-rw-r--r--src/compiler/scala/tools/nsc/transform/LambdaLift.scala18
-rw-r--r--src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala11
-rw-r--r--src/compiler/scala/tools/nsc/transform/UnCurry.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala9
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Implicits.scala91
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Namers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala10
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala4
-rw-r--r--src/compiler/scala/tools/reflect/ReflectGlobal.scala8
-rw-r--r--src/compiler/scala/tools/reflect/StdTags.scala3
-rw-r--r--src/compiler/scala/tools/reflect/ToolBox.scala32
-rw-r--r--src/compiler/scala/tools/reflect/ToolBoxFactory.scala27
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Holes.scala10
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala2
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala10
-rw-r--r--src/reflect/scala/reflect/api/Annotations.scala78
-rw-r--r--src/reflect/scala/reflect/api/BuildUtils.scala306
-rw-r--r--src/reflect/scala/reflect/api/Constants.scala4
-rw-r--r--src/reflect/scala/reflect/api/FlagSets.scala83
-rw-r--r--src/reflect/scala/reflect/api/ImplicitTags.scala8
-rw-r--r--src/reflect/scala/reflect/api/Importers.scala104
-rw-r--r--src/reflect/scala/reflect/api/Internals.scala1183
-rw-r--r--src/reflect/scala/reflect/api/JavaMirrors.scala57
-rw-r--r--src/reflect/scala/reflect/api/JavaUniverse.scala70
-rw-r--r--src/reflect/scala/reflect/api/Mirror.scala12
-rw-r--r--src/reflect/scala/reflect/api/Mirrors.scala33
-rw-r--r--src/reflect/scala/reflect/api/Names.scala20
-rw-r--r--src/reflect/scala/reflect/api/Position.scala162
-rw-r--r--src/reflect/scala/reflect/api/Positions.scala3
-rw-r--r--src/reflect/scala/reflect/api/Printers.scala15
-rw-r--r--src/reflect/scala/reflect/api/Scopes.scala11
-rw-r--r--src/reflect/scala/reflect/api/StandardDefinitions.scala12
-rw-r--r--src/reflect/scala/reflect/api/StandardLiftables.scala41
-rw-r--r--src/reflect/scala/reflect/api/StandardNames.scala12
-rw-r--r--src/reflect/scala/reflect/api/Symbols.scala243
-rw-r--r--src/reflect/scala/reflect/api/TagInterop.scala44
-rw-r--r--src/reflect/scala/reflect/api/Trees.scala327
-rw-r--r--src/reflect/scala/reflect/api/TypeTags.scala6
-rw-r--r--src/reflect/scala/reflect/api/Types.scala353
-rw-r--r--src/reflect/scala/reflect/api/Universe.scala4
-rw-r--r--src/reflect/scala/reflect/internal/AnnotationInfos.scala63
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala3
-rw-r--r--src/reflect/scala/reflect/internal/FlagSets.scala6
-rw-r--r--src/reflect/scala/reflect/internal/Flags.scala14
-rw-r--r--src/reflect/scala/reflect/internal/HasFlags.scala3
-rw-r--r--src/reflect/scala/reflect/internal/Importers.scala14
-rw-r--r--src/reflect/scala/reflect/internal/Internals.scala174
-rw-r--r--src/reflect/scala/reflect/internal/Mirrors.scala21
-rw-r--r--src/reflect/scala/reflect/internal/Names.scala4
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala31
-rw-r--r--src/reflect/scala/reflect/internal/ReificationSupport.scala (renamed from src/reflect/scala/reflect/internal/BuildUtils.scala)59
-rw-r--r--src/reflect/scala/reflect/internal/StdAttachments.scala10
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala28
-rw-r--r--src/reflect/scala/reflect/internal/SymbolTable.scala7
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala112
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala7
-rw-r--r--src/reflect/scala/reflect/internal/Trees.scala143
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala68
-rw-r--r--src/reflect/scala/reflect/internal/Variances.scala10
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeMaps.scala2
-rw-r--r--src/reflect/scala/reflect/internal/transform/Erasure.scala2
-rw-r--r--src/reflect/scala/reflect/internal/util/Position.scala38
-rw-r--r--src/reflect/scala/reflect/io/NoAbstractFile.scala1
-rw-r--r--src/reflect/scala/reflect/macros/Aliases.scala5
-rw-r--r--src/reflect/scala/reflect/macros/Enclosures.scala3
-rw-r--r--src/reflect/scala/reflect/macros/Internals.scala79
-rw-r--r--src/reflect/scala/reflect/macros/Reifiers.scala2
-rw-r--r--src/reflect/scala/reflect/macros/TreeBuilder.scala97
-rw-r--r--src/reflect/scala/reflect/macros/Typers.scala38
-rw-r--r--src/reflect/scala/reflect/macros/Universe.scala479
-rw-r--r--src/reflect/scala/reflect/macros/blackbox/Context.scala3
-rw-r--r--src/reflect/scala/reflect/runtime/JavaMirrors.scala58
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverse.scala43
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala7
-rw-r--r--src/reflect/scala/reflect/runtime/ReflectionUtils.scala71
-rw-r--r--src/repl/scala/tools/nsc/interpreter/IMain.scala2
-rw-r--r--src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala2
-rw-r--r--src/repl/scala/tools/nsc/interpreter/package.scala2
106 files changed, 3539 insertions, 1851 deletions
diff --git a/src/compiler/scala/reflect/macros/contexts/Context.scala b/src/compiler/scala/reflect/macros/contexts/Context.scala
index 87dac18849..f3dd29d8b2 100644
--- a/src/compiler/scala/reflect/macros/contexts/Context.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Context.scala
@@ -15,7 +15,8 @@ abstract class Context extends scala.reflect.macros.blackbox.Context
with Parsers
with Evals
with ExprUtils
- with Traces {
+ with Traces
+ with Internals {
val universe: Global
diff --git a/src/compiler/scala/reflect/macros/contexts/Evals.scala b/src/compiler/scala/reflect/macros/contexts/Evals.scala
index 180a998c39..a715af986c 100644
--- a/src/compiler/scala/reflect/macros/contexts/Evals.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Evals.scala
@@ -9,7 +9,7 @@ trait Evals {
private lazy val evalMirror = ru.runtimeMirror(universe.analyzer.defaultMacroClassloader)
private lazy val evalToolBox = evalMirror.mkToolBox()
- private lazy val evalImporter = ru.mkImporter(universe).asInstanceOf[ru.Importer { val from: universe.type }]
+ private lazy val evalImporter = ru.internal.createImporter(universe).asInstanceOf[ru.Importer { val from: universe.type }]
def eval[T](expr: Expr[T]): T = {
expr.tree match {
diff --git a/src/compiler/scala/reflect/macros/contexts/Internals.scala b/src/compiler/scala/reflect/macros/contexts/Internals.scala
new file mode 100644
index 0000000000..8c784d7e54
--- /dev/null
+++ b/src/compiler/scala/reflect/macros/contexts/Internals.scala
@@ -0,0 +1,47 @@
+package scala.reflect.macros
+package contexts
+
+trait Internals extends scala.tools.nsc.transform.TypingTransformers {
+ self: Context =>
+
+ import global._
+
+ lazy val internal: ContextInternalApi = new global.SymbolTableInternal with ContextInternalApi {
+ val enclosingOwner = callsiteTyper.context.owner
+
+ class HofTransformer(hof: (Tree, TransformApi) => Tree) extends Transformer {
+ val api = new TransformApi {
+ def recur(tree: Tree): Tree = hof(tree, this)
+ def default(tree: Tree): Tree = superTransform(tree)
+ }
+ def superTransform(tree: Tree) = super.transform(tree)
+ override def transform(tree: Tree): Tree = hof(tree, api)
+ }
+
+ def transform(tree: Tree)(transformer: (Tree, TransformApi) => Tree): Tree = new HofTransformer(transformer).transform(tree)
+
+ class HofTypingTransformer(hof: (Tree, TypingTransformApi) => Tree) extends TypingTransformer(callsiteTyper.context.unit) { self =>
+ currentOwner = callsiteTyper.context.owner
+ curTree = EmptyTree
+ localTyper = global.analyzer.newTyper(callsiteTyper.context.make(unit = callsiteTyper.context.unit))
+
+ val api = new TypingTransformApi {
+ def recur(tree: Tree): Tree = hof(tree, this)
+ def default(tree: Tree): Tree = superTransform(tree)
+ def atOwner[T](owner: Symbol)(op: => T): T = self.atOwner(owner)(op)
+ def atOwner[T](tree: Tree, owner: Symbol)(op: => T): T = self.atOwner(tree, owner)(op)
+ def currentOwner: Symbol = self.currentOwner
+ def typecheck(tree: Tree): Tree = localTyper.typed(tree)
+ }
+ def superTransform(tree: Tree) = super.transform(tree)
+ override def transform(tree: Tree): Tree = hof(tree, api)
+ }
+
+ def typingTransform(tree: Tree)(transformer: (Tree, TypingTransformApi) => Tree): Tree = new HofTypingTransformer(transformer).transform(tree)
+
+ def typingTransform(tree: Tree, owner: Symbol)(transformer: (Tree, TypingTransformApi) => Tree): Tree = {
+ val trans = new HofTypingTransformer(transformer)
+ trans.atOwner(owner)(trans.transform(tree))
+ }
+ }
+} \ No newline at end of file
diff --git a/src/compiler/scala/reflect/macros/contexts/Typers.scala b/src/compiler/scala/reflect/macros/contexts/Typers.scala
index f80b43b636..28c1e3ddb3 100644
--- a/src/compiler/scala/reflect/macros/contexts/Typers.scala
+++ b/src/compiler/scala/reflect/macros/contexts/Typers.scala
@@ -1,8 +1,6 @@
package scala.reflect.macros
package contexts
-import scala.reflect.internal.Mode
-
trait Typers {
self: Context =>
@@ -10,17 +8,24 @@ trait Typers {
def openImplicits: List[ImplicitCandidate] = callsiteTyper.context.openImplicits.map(_.toImplicitCandidate)
+ type TypecheckMode = scala.reflect.internal.Mode
+ val TypecheckMode = scala.reflect.internal.Mode
+ val TERMmode = TypecheckMode.EXPRmode
+ val TYPEmode = TypecheckMode.TYPEmode | TypecheckMode.FUNmode
+ val PATTERNmode = TypecheckMode.PATTERNmode
+
/**
* @see [[scala.tools.reflect.ToolBox.typeCheck]]
*/
- def typecheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = {
+ def typecheck(tree: Tree, mode: TypecheckMode = TERMmode, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree = {
macroLogVerbose("typechecking %s with expected type %s, implicit views = %s, macros = %s".format(tree, pt, !withImplicitViewsDisabled, !withMacrosDisabled))
val context = callsiteTyper.context
val withImplicitFlag = if (!withImplicitViewsDisabled) (context.withImplicitsEnabled[Tree] _) else (context.withImplicitsDisabled[Tree] _)
val withMacroFlag = if (!withMacrosDisabled) (context.withMacrosEnabled[Tree] _) else (context.withMacrosDisabled[Tree] _)
def withContext(tree: => Tree) = withImplicitFlag(withMacroFlag(tree))
- def typecheckInternal(tree: Tree) = callsiteTyper.silent(_.typed(universe.duplicateAndKeepPositions(tree), pt), reportAmbiguousErrors = false)
- universe.wrappingIntoTerm(tree)(wrappedTree => withContext(typecheckInternal(wrappedTree) match {
+ def withWrapping(tree: Tree)(op: Tree => Tree) = if (mode == TERMmode) universe.wrappingIntoTerm(tree)(op) else op(tree)
+ def typecheckInternal(tree: Tree) = callsiteTyper.silent(_.typed(universe.duplicateAndKeepPositions(tree), mode, pt), reportAmbiguousErrors = false)
+ withWrapping(tree)(wrappedTree => withContext(typecheckInternal(wrappedTree) match {
case universe.analyzer.SilentResultValue(result) =>
macroLogVerbose(result)
result
diff --git a/src/compiler/scala/reflect/reify/States.scala b/src/compiler/scala/reflect/reify/States.scala
index 29bfa19845..65f3f424e8 100644
--- a/src/compiler/scala/reflect/reify/States.scala
+++ b/src/compiler/scala/reflect/reify/States.scala
@@ -35,7 +35,7 @@ trait States {
if (!value && concrete) {
current match {
case tpe: Type => CannotReifyWeakType(s" having unresolved type parameter $tpe")
- case sym: Symbol => CannotReifyWeakType(s" referring to local ${sym.kindString} ${sym.fullName}")
+ case sym: Symbol => CannotReifyWeakType(s" referring to ${sym.kindString} ${sym.fullName} local to the reifee")
case _ => CannotReifyWeakType("")
}
}
diff --git a/src/compiler/scala/reflect/reify/codegen/GenAnnotationInfos.scala b/src/compiler/scala/reflect/reify/codegen/GenAnnotationInfos.scala
index bd60faf4cd..ce26232e5f 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenAnnotationInfos.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenAnnotationInfos.scala
@@ -38,19 +38,10 @@ trait GenAnnotationInfos {
}
}
- def reifyClassfileAnnotArg(arg: ClassfileAnnotArg): Tree = arg match {
- case LiteralAnnotArg(const) =>
- mirrorFactoryCall(nme.LiteralAnnotArg, reifyProduct(const))
- case ArrayAnnotArg(args) =>
- mirrorFactoryCall(nme.ArrayAnnotArg, scalaFactoryCall(nme.Array, args map reifyClassfileAnnotArg: _*))
- case NestedAnnotArg(ann) =>
- mirrorFactoryCall(nme.NestedAnnotArg, reifyAnnotationInfo(ann))
- case _ =>
- sys.error(s"Don't know what to do with $arg")
- }
-
// if you reify originals of anns, you get SO when trying to reify AnnotatedTypes, so screw it - after all, it's not that important
- val reifiedAssocs = ann.assocs map (assoc => scalaFactoryCall(nme.Tuple2, reify(assoc._1), reifyClassfileAnnotArg(assoc._2)))
- mirrorFactoryCall(nme.Annotation, reify(ann.atp), mkList(reifiedArgs), mkListMap(reifiedAssocs))
+ val Apply(Select(New(tpt), name), args) = annotationToTree(ann)
+ val reifiedAtp = mirrorCall(nme.Select, mirrorCall(nme.New, mirrorCall(nme.TypeTree, reifyType(tpt.tpe))), reify(name))
+ val reifiedAnnRepr = mirrorCall(nme.Apply, reifiedAtp, reifyList(args))
+ mirrorFactoryCall(nme.Annotation, reifiedAnnRepr)
}
}
diff --git a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
index 2965db17c6..52ddcb154b 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenSymbols.scala
@@ -13,7 +13,7 @@ trait GenSymbols {
* Keeps track of auxiliary symbols that are necessary for this reification session.
* These include:
* 1) Free vars (terms, types and existentials),
- * 2) Non-locatable symbols (sometimes, e.g. for RefinedTypes, we need to reify these; to do that we create their local copies in the reificode)
+ * 2) Non-locatable symbols (sometimes, e.g. for RefinedTypes, we need to reify these; to do that we create their copies in the reificode)
* 3) Non-locatable symbols that are referred by #1, #2 and #3
*
* Exposes three main methods:
@@ -90,7 +90,7 @@ trait GenSymbols {
mirrorBuildCall(nme.selectTerm, rowner, rname)
}
} else {
- // todo. make sure that free methods and free local defs work correctly
+ // todo. make sure that free methods work correctly
if (sym.isExistential) reifySymDef(sym)
else if (sym.isTerm) reifyFreeTerm(Ident(sym))
else reifyFreeType(Ident(sym)) // TODO: reify refinement classes
diff --git a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
index b082796757..743fe131c4 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenTrees.scala
@@ -39,7 +39,7 @@ trait GenTrees {
//
// why bother? because this brings method to the madness
// the first prototype of reification reified all types and symbols for all trees => this quickly became unyieldy
- // the second prototype reified external types, but avoided reifying local ones => this created an ugly irregularity
+ // the second prototype reified external types, but avoided reifying ones local to the reifee => this created an ugly irregularity
// current approach is uniform and compact
var rtree: Tree = tree match {
case FreeDef(_, _, _, _, _) => reifyNestedFreeDef(tree)
@@ -102,7 +102,7 @@ trait GenTrees {
if (reifyDebug) println("inlining the splicee")
// all free vars local to the enclosing reifee should've already been inlined by `Metalevels`
for (sym <- inlinedSymtab.syms if sym.isLocalToReifee)
- abort("local free var, should have already been inlined by Metalevels: " + inlinedSymtab.symDef(sym))
+ abort("free var local to the reifee, should have already been inlined by Metalevels: " + inlinedSymtab.symDef(sym))
state.symtab ++= inlinedSymtab
rtree
case tree =>
@@ -129,11 +129,11 @@ trait GenTrees {
else if (sym.isClass && !sym.isModuleClass) {
if (reifyDebug) println("This for %s, reified as freeVar".format(sym))
if (reifyDebug) println("Free: " + sym)
- mirrorBuildCall(nme.Ident, reifyFreeTerm(This(sym)))
+ mirrorBuildCall(nme.mkIdent, reifyFreeTerm(This(sym)))
}
else {
if (reifyDebug) println("This for %s, reified as This".format(sym))
- mirrorBuildCall(nme.This, reify(sym))
+ mirrorBuildCall(nme.mkThis, reify(sym))
}
case Ident(name) =>
@@ -146,15 +146,15 @@ trait GenTrees {
else if (!sym.isLocalToReifee) {
if (sym.isVariable && sym.owner.isTerm) {
captureVariable(sym) // Note order dependency: captureVariable needs to come before reification here.
- mirrorCall(nme.Select, mirrorBuildCall(nme.Ident, reify(sym)), reify(nme.elem))
+ mirrorCall(nme.Select, mirrorBuildCall(nme.mkIdent, reify(sym)), reify(nme.elem))
}
- else mirrorBuildCall(nme.Ident, reify(sym))
+ else mirrorBuildCall(nme.mkIdent, reify(sym))
}
else mirrorCall(nme.Ident, reify(name))
case Select(qual, name) =>
if (qual.symbol != null && qual.symbol.isPackage) {
- mirrorBuildCall(nme.Ident, reify(sym))
+ mirrorBuildCall(nme.mkIdent, reify(sym))
} else {
val effectiveName = if (sym != null && sym != NoSymbol) sym.name else name
reifyProduct(Select(qual, effectiveName))
@@ -173,7 +173,7 @@ trait GenTrees {
assert(tpe != null, "unexpected: bound type that doesn't have a tpe: " + showRaw(tree))
// if a symbol or a type of the scrutinee are local to reifee
- // (e.g. point to a locally declared class or to a path-dependent thingie that depends on a local variable)
+ // (e.g. point to a locally declared class or to a path-dependent thingie that depends on a variable defined within the reifee)
// then we can reify the scrutinee as a symless AST and that will definitely be hygienic
// why? because then typechecking of a scrutinee doesn't depend on the environment external to the quasiquote
// otherwise we need to reify the corresponding type
@@ -187,7 +187,7 @@ trait GenTrees {
if (spliced == EmptyTree) {
if (reifyDebug) println("splicing failed: reify as is")
- mirrorBuildCall(nme.TypeTree, reify(tpe))
+ mirrorBuildCall(nme.mkTypeTree, reify(tpe))
}
else spliced match {
case TypeRefToFreeType(freeType) =>
@@ -195,7 +195,7 @@ trait GenTrees {
Ident(freeType)
case _ =>
if (reifyDebug) println("splicing succeeded: " + spliced)
- mirrorBuildCall(nme.TypeTree, spliced)
+ mirrorBuildCall(nme.mkTypeTree, spliced)
}
}
else tree match {
@@ -207,10 +207,10 @@ trait GenTrees {
mirrorCall(nme.SelectFromTypeTree, reify(qual), reify(name))
case _ if sym.isLocatable =>
if (reifyDebug) println(s"tpe is locatable: reify as Ident($sym)")
- mirrorBuildCall(nme.Ident, reify(sym))
+ mirrorBuildCall(nme.mkIdent, reify(sym))
case _ =>
if (reifyDebug) println(s"tpe is not locatable: reify as TypeTree($tpe)")
- mirrorBuildCall(nme.TypeTree, reify(tpe))
+ mirrorBuildCall(nme.mkTypeTree, reify(tpe))
}
}
}
diff --git a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala
index a90a3a338b..a6b69e239f 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenTypes.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenTypes.scala
@@ -45,21 +45,21 @@ trait GenTypes {
case tpe @ ThisType(clazz) if clazz.isModuleClass && clazz.isStatic =>
val module = reify(clazz.sourceModule)
val moduleClass = Select(Select(module, nme.asModule), nme.moduleClass)
- mirrorFactoryCall(nme.ThisType, moduleClass)
- case tpe @ ThisType(_) =>
- reifyProduct(tpe)
+ mirrorBuildCall(nme.ThisType, moduleClass)
+ case tpe @ ThisType(sym) =>
+ reifyBuildCall(nme.ThisType, sym)
case tpe @ SuperType(thistpe, supertpe) =>
- reifyProduct(tpe)
+ reifyBuildCall(nme.SuperType, thistpe, supertpe)
case tpe @ SingleType(pre, sym) =>
- reifyProduct(tpe)
+ reifyBuildCall(nme.SingleType, pre, sym)
case tpe @ ConstantType(value) =>
- mirrorFactoryCall(nme.ConstantType, reifyProduct(value))
+ mirrorBuildCall(nme.ConstantType, reifyProduct(value))
case tpe @ TypeRef(pre, sym, args) =>
- reifyProduct(tpe)
+ reifyBuildCall(nme.TypeRef, pre, sym, args)
case tpe @ TypeBounds(lo, hi) =>
- reifyProduct(tpe)
+ reifyBuildCall(nme.TypeBounds, lo, hi)
case tpe @ NullaryMethodType(restpe) =>
- reifyProduct(tpe)
+ reifyBuildCall(nme.NullaryMethodType, restpe)
case tpe @ AnnotatedType(anns, underlying) =>
reifyAnnotatedType(tpe)
case _ =>
@@ -119,7 +119,8 @@ trait GenTypes {
// todo. write a test for this
if (ReflectRuntimeUniverse == NoSymbol) CannotConvertManifestToTagWithoutScalaReflect(tpe, manifestInScope)
val cm = typer.typed(Ident(ReflectRuntimeCurrentMirror))
- val tagTree = gen.mkMethodCall(ReflectRuntimeUniverse, nme.manifestToTypeTag, List(tpe), List(cm, manifestInScope))
+ val internal = gen.mkAttributedSelect(gen.mkAttributedRef(ReflectRuntimeUniverse), UniverseInternal)
+ val tagTree = gen.mkMethodCall(Select(internal, nme.manifestToTypeTag), List(tpe), List(cm, manifestInScope))
Select(Apply(Select(tagTree, nme.in), List(Ident(nme.MIRROR_SHORT))), nme.tpe)
case _ =>
EmptyTree
@@ -157,13 +158,13 @@ trait GenTypes {
*/
private def reifySemiConcreteTypeMember(tpe: Type): Tree = tpe match {
case tpe @ TypeRef(pre @ SingleType(prepre, presym), sym, args) if sym.isAbstractType && !sym.isExistential =>
- mirrorFactoryCall(nme.TypeRef, reify(pre), mirrorBuildCall(nme.selectType, reify(sym.owner), reify(sym.name.toString)), reify(args))
+ mirrorBuildCall(nme.TypeRef, reify(pre), mirrorBuildCall(nme.selectType, reify(sym.owner), reify(sym.name.toString)), reify(args))
}
/** Reify an annotated type, i.e. the one that makes us deal with AnnotationInfos */
private def reifyAnnotatedType(tpe: AnnotatedType): Tree = {
val AnnotatedType(anns, underlying) = tpe
- mirrorFactoryCall(nme.AnnotatedType, mkList(anns map reifyAnnotationInfo), reify(underlying))
+ mirrorBuildCall(nme.AnnotatedType, mkList(anns map reifyAnnotationInfo), reify(underlying))
}
/** Reify a tough type, i.e. the one that leads to creation of auxiliary symbols */
@@ -172,25 +173,25 @@ trait GenTypes {
def reifyScope(scope: Scope): Tree = {
scope foreach reifySymDef
- mirrorCall(nme.newScopeWith, scope.toList map reify: _*)
+ mirrorBuildCall(nme.newScopeWith, scope.toList map reify: _*)
}
tpe match {
case tpe @ RefinedType(parents, decls) =>
reifySymDef(tpe.typeSymbol)
- mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol))
+ mirrorBuildCall(nme.RefinedType, reify(parents), reifyScope(decls), reify(tpe.typeSymbol))
case tpe @ ExistentialType(tparams, underlying) =>
tparams foreach reifySymDef
- mirrorFactoryCall(tpe, reify(tparams), reify(underlying))
+ reifyBuildCall(nme.ExistentialType, tparams, underlying)
case tpe @ ClassInfoType(parents, decls, clazz) =>
reifySymDef(clazz)
- mirrorFactoryCall(tpe, reify(parents), reifyScope(decls), reify(tpe.typeSymbol))
+ mirrorBuildCall(nme.ClassInfoType, reify(parents), reifyScope(decls), reify(tpe.typeSymbol))
case tpe @ MethodType(params, restpe) =>
params foreach reifySymDef
- mirrorFactoryCall(tpe, reify(params), reify(restpe))
+ reifyBuildCall(nme.MethodType, params, restpe)
case tpe @ PolyType(tparams, underlying) =>
tparams foreach reifySymDef
- mirrorFactoryCall(tpe, reify(tparams), reify(underlying))
+ reifyBuildCall(nme.PolyType, tparams, underlying)
case _ =>
throw new Error("internal error: %s (%s) is not supported".format(tpe, tpe.kind))
}
diff --git a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
index de9fec0df5..4512b2cb6f 100644
--- a/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
+++ b/src/compiler/scala/reflect/reify/codegen/GenUtils.scala
@@ -5,6 +5,10 @@ trait GenUtils {
self: Reifier =>
import global._
+ import treeInfo._
+ import definitions._
+ private val runDefinitions = currentRun.runDefinitions
+ import runDefinitions._
def reifyList(xs: List[Any]): Tree =
mkList(xs map reify)
diff --git a/src/compiler/scala/reflect/reify/phases/Calculate.scala b/src/compiler/scala/reflect/reify/phases/Calculate.scala
index abd179b24b..a0035d73d6 100644
--- a/src/compiler/scala/reflect/reify/phases/Calculate.scala
+++ b/src/compiler/scala/reflect/reify/phases/Calculate.scala
@@ -26,7 +26,7 @@ trait Calculate {
}
/**
- * Merely traverses the reifiee and records local symbols along with their metalevels.
+ * Merely traverses the reifiee and records symbols local to the reifee along with their metalevels.
*/
val calculate = new Traverser {
// see the explanation of metalevels in `Metalevels`
diff --git a/src/compiler/scala/reflect/reify/utils/Extractors.scala b/src/compiler/scala/reflect/reify/utils/Extractors.scala
index d052127956..4ec4de28c4 100644
--- a/src/compiler/scala/reflect/reify/utils/Extractors.scala
+++ b/src/compiler/scala/reflect/reify/utils/Extractors.scala
@@ -183,12 +183,12 @@ trait Extractors {
tree match {
case
ValDef(_, name, _, Apply(
- Select(Select(uref1 @ Ident(_), build1), freeTermFactory),
+ Select(Select(Select(uref1 @ Ident(_), internal1), rs1), freeTermFactory),
_ :+
- ApplyCall(Select(Select(uref2 @ Ident(_), build2), flagsRepr), List(Literal(Constant(flags: Long)))) :+
+ ApplyCall(Select(Select(Select(uref2 @ Ident(_), internal2), rs2), flagsRepr), List(Literal(Constant(flags: Long)))) :+
Literal(Constant(origin: String))))
- if uref1.name == nme.UNIVERSE_SHORT && build1 == nme.build && acceptFreeTermFactory(freeTermFactory) &&
- uref2.name == nme.UNIVERSE_SHORT && build2 == nme.build && flagsRepr == nme.FlagsRepr =>
+ if uref1.name == nme.UNIVERSE_SHORT && internal1 == nme.internal && rs1 == nme.reificationSupport && acceptFreeTermFactory(freeTermFactory) &&
+ uref2.name == nme.UNIVERSE_SHORT && internal2 == nme.internal && rs2 == nme.reificationSupport && flagsRepr == nme.FlagsRepr =>
Some((uref1, name, reifyBinding(tree), flags, origin))
case _ =>
None
@@ -201,8 +201,8 @@ trait Extractors {
object FreeRef {
def unapply(tree: Tree): Option[(Tree, TermName)] = tree match {
- case Apply(Select(Select(uref @ Ident(_), build), ident), List(Ident(name: TermName)))
- if build == nme.build && ident == nme.Ident && name.startsWith(nme.REIFY_FREE_PREFIX) =>
+ case Apply(Select(Select(Select(uref @ Ident(_), internal), rs), mkIdent), List(Ident(name: TermName)))
+ if internal == nme.internal && rs == nme.reificationSupport && mkIdent == nme.mkIdent && name.startsWith(nme.REIFY_FREE_PREFIX) =>
Some((uref, name))
case _ =>
None
@@ -213,15 +213,15 @@ trait Extractors {
def unapply(tree: Tree): Option[(Tree, TermName, Long, Boolean)] = tree match {
case
ValDef(_, name, _, Apply(
- Select(Select(uref1 @ Ident(_), build1), newNestedSymbol),
+ Select(Select(Select(uref1 @ Ident(_), internal1), rs1), newNestedSymbol),
List(
_,
_,
_,
- ApplyCall(Select(Select(uref2 @ Ident(_), build2), flagsRepr), List(Literal(Constant(flags: Long)))),
+ ApplyCall(Select(Select(Select(uref2 @ Ident(_), internal2), rs2), flagsRepr), List(Literal(Constant(flags: Long)))),
Literal(Constant(isClass: Boolean)))))
- if uref1.name == nme.UNIVERSE_SHORT && build1 == nme.build && newNestedSymbol == nme.newNestedSymbol &&
- uref2.name == nme.UNIVERSE_SHORT && build2 == nme.build && flagsRepr == nme.FlagsRepr =>
+ if uref1.name == nme.UNIVERSE_SHORT && internal1 == nme.internal && rs1 == nme.reificationSupport && newNestedSymbol == nme.newNestedSymbol &&
+ uref2.name == nme.UNIVERSE_SHORT && internal2 == nme.internal && rs2 == nme.reificationSupport && flagsRepr == nme.FlagsRepr =>
Some((uref1, name, flags, isClass))
case _ =>
None
diff --git a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
index e37b861461..3b91d28360 100644
--- a/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
+++ b/src/compiler/scala/reflect/reify/utils/NodePrinters.scala
@@ -32,7 +32,7 @@ trait NodePrinters {
s = "List\\[List\\[.*?\\].*?\\]".r.replaceAllIn(s, "List")
s = "List\\[.*?\\]".r.replaceAllIn(s, "List")
s = s.replace("immutable.this.Nil", "List()")
- s = """build\.FlagsRepr\((\d+)[lL]\)""".r.replaceAllIn(s, m => {
+ s = """internal\.reificationSupport\.FlagsRepr\((\d+)[lL]\)""".r.replaceAllIn(s, m => {
flagsAreUsed = true
show(m.group(1).toLong)
})
@@ -76,7 +76,6 @@ trait NodePrinters {
if (mirrorIsUsed) printout += mirror.replace("Mirror[", "scala.reflect.api.Mirror[").trim
val imports = scala.collection.mutable.ListBuffer[String]()
imports += nme.UNIVERSE_SHORT.toString
- // if (buildIsUsed) imports += nme.build
if (mirrorIsUsed) imports += nme.MIRROR_SHORT.toString
if (flagsAreUsed) imports += nme.Flag.toString
printout += s"""import ${imports map (_ + "._") mkString ", "}"""
diff --git a/src/compiler/scala/reflect/reify/utils/SymbolTables.scala b/src/compiler/scala/reflect/reify/utils/SymbolTables.scala
index 5f8de9894f..b6ae3b8952 100644
--- a/src/compiler/scala/reflect/reify/utils/SymbolTables.scala
+++ b/src/compiler/scala/reflect/reify/utils/SymbolTables.scala
@@ -162,7 +162,7 @@ trait SymbolTables {
else if (isFreeTerm) sym.tpe
else sym.info
} else NoType
- val rset = reifier.mirrorBuildCall(nme.setTypeSignature, currtab.symRef(sym), reifier.reify(signature))
+ val rset = reifier.mirrorBuildCall(nme.setInfo, currtab.symRef(sym), reifier.reify(signature))
// `Symbol.annotations` doesn't initialize the symbol, so we don't need to do anything special here
// also since we call `sym.info` a few lines above, by now the symbol will be initialized (if possible)
// so the annotations will be filled in and will be waiting to be reified (unless symbol initialization is prohibited as described above)
diff --git a/src/compiler/scala/tools/nsc/Global.scala b/src/compiler/scala/tools/nsc/Global.scala
index 81e96b76ac..03b76ed99e 100644
--- a/src/compiler/scala/tools/nsc/Global.scala
+++ b/src/compiler/scala/tools/nsc/Global.scala
@@ -15,6 +15,7 @@ import scala.collection.{ mutable, immutable }
import io.{ SourceReader, AbstractFile, Path }
import reporters.{ Reporter, ConsoleReporter }
import util.{ ClassPath, MergedClassPath, StatisticsInfo, returning, stackTraceString }
+import scala.reflect.ClassTag
import scala.reflect.internal.util.{ OffsetPosition, SourceFile, NoSourceFile, BatchSourceFile, ScriptSourceFile }
import scala.reflect.internal.pickling.{ PickleBuffer, PickleFormat }
import scala.reflect.io.VirtualFile
@@ -33,6 +34,7 @@ import backend.jvm.GenASM
import backend.opt.{ Inliners, InlineExceptionHandlers, ConstantOptimization, ClosureElimination, DeadCodeElimination }
import backend.icode.analysis._
import scala.language.postfixOps
+import scala.tools.nsc.ast.{TreeGen => AstTreeGen}
class Global(var currentSettings: Settings, var reporter: Reporter)
extends SymbolTable
@@ -49,11 +51,15 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
override def isCompilerUniverse = true
override val useOffsetPositions = !currentSettings.Yrangepos
+ type RuntimeClass = java.lang.Class[_]
+ implicit val RuntimeClassTag: ClassTag[RuntimeClass] = ClassTag[RuntimeClass](classOf[RuntimeClass])
+
class GlobalMirror extends Roots(NoSymbol) {
val universe: self.type = self
def rootLoader: LazyType = new loaders.PackageLoader(classPath)
override def toString = "compiler mirror"
}
+ implicit val MirrorTag: ClassTag[Mirror] = ClassTag[Mirror](classOf[GlobalMirror])
lazy val rootMirror: Mirror = {
val rm = new GlobalMirror
@@ -100,13 +106,10 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
// sub-components --------------------------------------------------
- /** Generate ASTs */
- type TreeGen = scala.tools.nsc.ast.TreeGen
-
/** Tree generation, usually based on existing symbols. */
override object gen extends {
val global: Global.this.type = Global.this
- } with TreeGen {
+ } with AstTreeGen {
def mkAttributedCast(tree: Tree, pt: Type): Tree =
typer.typed(mkCast(tree, pt))
}
@@ -1348,7 +1351,7 @@ class Global(var currentSettings: Settings, var reporter: Reporter)
val toReload = mutable.Set[String]()
for (sym <- root.info.decls) {
if (sym.isInitialized && clearOnNextRun(sym))
- if (sym.isPackage) {
+ if (sym.hasPackageFlag) {
resetProjectClasses(sym.moduleClass)
openPackageModule(sym.moduleClass)
} else {
diff --git a/src/compiler/scala/tools/nsc/ast/TreeGen.scala b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
index a87a04472a..0575b9703e 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeGen.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeGen.scala
@@ -142,7 +142,7 @@ abstract class TreeGen extends scala.reflect.internal.TreeGen with TreeDSL {
* x.asInstanceOf[`pt`]() if after uncurry but before erasure
* x.$asInstanceOf[`pt`]() if at or after erasure
*/
- def mkCast(tree: Tree, pt: Type): Tree = {
+ override def mkCast(tree: Tree, pt: Type): Tree = {
debuglog("casting " + tree + ":" + tree.tpe + " to " + pt + " at phase: " + phase)
assert(!tree.tpe.isInstanceOf[MethodType], tree)
assert(pt eq pt.normalize, tree +" : "+ debugString(pt) +" ~>"+ debugString(pt.normalize))
diff --git a/src/compiler/scala/tools/nsc/ast/Trees.scala b/src/compiler/scala/tools/nsc/ast/Trees.scala
index 7a7d4ac0b2..d33ea5bb5c 100644
--- a/src/compiler/scala/tools/nsc/ast/Trees.scala
+++ b/src/compiler/scala/tools/nsc/ast/Trees.scala
@@ -6,6 +6,7 @@
package scala.tools.nsc
package ast
+import scala.reflect.ClassTag
import scala.reflect.internal.Flags.BYNAMEPARAM
import scala.reflect.internal.Flags.DEFAULTPARAM
import scala.reflect.internal.Flags.IMPLICIT
@@ -102,6 +103,7 @@ trait Trees extends scala.reflect.internal.Trees { self: Global =>
def InjectDerivedValue(tree: Tree, arg: Tree): InjectDerivedValue
def TypeTreeWithDeferredRefCheck(tree: Tree): TypeTreeWithDeferredRefCheck
}
+ implicit val TreeCopierTag: ClassTag[TreeCopier] = ClassTag[TreeCopier](classOf[TreeCopier])
def newStrictTreeCopier: TreeCopier = new StrictTreeCopier
def newLazyTreeCopier: TreeCopier = new LazyTreeCopier
diff --git a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
index 8271363527..3542fe5945 100644
--- a/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/parser/Parsers.scala
@@ -2231,7 +2231,7 @@ self =>
} else { // XX-METHOD-INFER
accept(COLON)
if (in.token == ARROW) {
- if (owner.isTypeName && !mods.hasLocalFlag)
+ if (owner.isTypeName && !mods.isLocalToThis)
syntaxError(
in.offset,
(if (mods.isMutable) "`var'" else "`val'") +
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index b650cdfa09..81fbbfcabf 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -869,7 +869,7 @@ abstract class GenICode extends SubComponent {
case Ident(name) =>
def genLoadIdent = {
val sym = tree.symbol
- if (!sym.isPackage) {
+ if (!sym.hasPackageFlag) {
if (sym.isModule) {
genLoadModule(ctx, tree)
generatedType = toTypeKind(sym.info)
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
index c8845344e9..53142fbd87 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/BCodeBodyBuilder.scala
@@ -350,7 +350,7 @@ abstract class BCodeBodyBuilder extends BCodeSkelBuilder {
case Ident(name) =>
val sym = tree.symbol
- if (!sym.isPackage) {
+ if (!sym.hasPackageFlag) {
val tk = symInfoTK(sym)
if (sym.isModule) { genLoadModule(tree) }
else { locals.load(sym) }
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index 2f9cc01c0b..ea600bc586 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -561,14 +561,14 @@ abstract class ClassfileParser {
// if this is a non-static inner class, remove the explicit outer parameter
val paramsNoOuter = innerClasses getEntry currentClass match {
case Some(entry) if !isScalaRaw && !entry.jflags.isStatic =>
- /* About `clazz.owner.isPackage` below: SI-5957
+ /* About `clazz.owner.hasPackageFlag` below: SI-5957
* For every nested java class A$B, there are two symbols in the scala compiler.
* 1. created by SymbolLoader, because of the existence of the A$B.class file, owner: package
* 2. created by ClassfileParser of A when reading the inner classes, owner: A
* If symbol 1 gets completed (e.g. because the compiled source mentions `A$B`, not `A#B`), the
* ClassfileParser for 1 executes, and clazz.owner is the package.
*/
- assert(params.head.tpe.typeSymbol == clazz.owner || clazz.owner.isPackage, params.head.tpe.typeSymbol + ": " + clazz.owner)
+ assert(params.head.tpe.typeSymbol == clazz.owner || clazz.owner.hasPackageFlag, params.head.tpe.typeSymbol + ": " + clazz.owner)
params.tail
case _ =>
params
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
index 55f45257dc..592c5497b5 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/Pickler.scala
@@ -99,7 +99,7 @@ abstract class Pickler extends SubComponent {
* added to fix that bug, but there may be a better way.
*/
private def localizedOwner(sym: Symbol) =
- if (isLocal(sym) && !isRootSym(sym) && !isLocal(sym.owner))
+ if (isLocalToPickle(sym) && !isRootSym(sym) && !isLocalToPickle(sym.owner))
// don't use a class as the localized owner for type parameters that are not owned by a class: those are not instantiated by asSeenFrom
// however, they would suddenly be considered by asSeenFrom if their localized owner became a class (causing the crashes of #4079, #2741)
(if ((sym.isTypeParameter || sym.isValueParameter) && !sym.owner.isClass) nonClassRoot
@@ -110,14 +110,14 @@ abstract class Pickler extends SubComponent {
* anyway? This is the case if symbol is a refinement class,
* an existentially bound variable, or a higher-order type parameter.
*/
- private def isLocal(sym: Symbol): Boolean = (sym != NoSymbol) && !sym.isPackageClass && (
+ private def isLocalToPickle(sym: Symbol): Boolean = (sym != NoSymbol) && !sym.isPackageClass && (
isRootSym(sym)
|| sym.isRefinementClass
|| sym.isAbstractType && sym.hasFlag(EXISTENTIAL) // existential param
|| sym.isParameter
- || isLocal(sym.owner)
+ || isLocalToPickle(sym.owner)
)
- private def isExternalSymbol(sym: Symbol): Boolean = (sym != NoSymbol) && !isLocal(sym)
+ private def isExternalSymbol(sym: Symbol): Boolean = (sym != NoSymbol) && !isLocalToPickle(sym)
// Phase 1 methods: Populate entries/index ------------------------------------
@@ -174,7 +174,7 @@ abstract class Pickler extends SubComponent {
val sym = deskolemize(sym0)
if (putEntry(sym)) {
- if (isLocal(sym)) {
+ if (isLocalToPickle(sym)) {
putEntry(sym.name)
putSymbol(sym.owner)
putSymbol(sym.privateWithin)
@@ -428,7 +428,7 @@ abstract class Pickler extends SubComponent {
}
def writeSymbolBody(sym: Symbol) {
if (sym ne NoSymbol) {
- if (isLocal(sym))
+ if (isLocalToPickle(sym))
writeLocalSymbolBody(sym)
else
writeExtSymbolBody(sym)
diff --git a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
index d81a5d5755..1468680fe0 100644
--- a/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
+++ b/src/compiler/scala/tools/nsc/transform/Delambdafy.scala
@@ -130,7 +130,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
if (!thisProxy.exists) {
target setFlag STATIC
}
- val params = ((optionSymbol(thisProxy) map {proxy:Symbol => ValDef(proxy)}) ++ (target.paramss.flatten map ValDef)).toList
+ val params = ((optionSymbol(thisProxy) map {proxy:Symbol => ValDef(proxy)}) ++ (target.paramss.flatten map ValDef.apply)).toList
val methSym = oldClass.newMethod(unit.freshTermName(nme.accessor.toString()), target.pos, FINAL | BRIDGE | SYNTHETIC | PROTECTED | STATIC)
@@ -393,7 +393,7 @@ abstract class Delambdafy extends Transform with TypingTransformers with ast.Tre
declared += tree.symbol
case Ident(_) =>
val sym = tree.symbol
- if ((sym != NoSymbol) && sym.isLocal && sym.isTerm && !sym.isMethod && !declared.contains(sym)) freeVars += sym
+ if ((sym != NoSymbol) && sym.isLocalToBlock && sym.isTerm && !sym.isMethod && !declared.contains(sym)) freeVars += sym
case _ =>
}
super.traverse(tree)
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 4db74e70f2..bd2f6f0018 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -600,7 +600,7 @@ abstract class Erasure extends AddInterfaces
if (tree.symbol == NoSymbol) {
tree
} else if (name == nme.CONSTRUCTOR) {
- if (tree.symbol.owner == AnyValClass) tree.symbol = ObjectClass.primaryConstructor
+ if (tree.symbol.owner == AnyValClass) tree.symbol = ObjectClass.info.decl(nme.CONSTRUCTOR)
tree
} else if (tree.symbol == Any_asInstanceOf)
adaptMember(atPos(tree.pos)(Select(qual, Object_asInstanceOf)))
@@ -740,7 +740,7 @@ abstract class Erasure extends AddInterfaces
/** TODO - adapt SymbolPairs so it can be used here. */
private def checkNoDeclaredDoubleDefs(base: Symbol) {
val decls = base.info.decls
-
+
// SI-8010 force infos, otherwise makeNotPrivate in ExplicitOuter info transformer can trigger
// a scope rehash while were iterating and we can see the same entry twice!
// Inspection of SymbolPairs (the basis of OverridingPairs), suggests that it is immune
@@ -751,13 +751,13 @@ abstract class Erasure extends AddInterfaces
// we do these checks, so that we're comparing same-named methods based on the expanded names that actually
// end up in the bytecode.
exitingPostErasure(decls.foreach(_.info))
-
+
var e = decls.elems
while (e ne null) {
if (e.sym.isTerm) {
var e1 = decls lookupNextEntry e
while (e1 ne null) {
- assert(e.sym ne e1.sym, s"Internal error: encountered ${e.sym.debugLocationString} twice during scope traversal. This might be related to SI-8010.")
+ assert(e.sym ne e1.sym, s"Internal error: encountered ${e.sym.debugLocationString} twice during scope traversal. This might be related to SI-8010.")
if (sameTypeAfterErasure(e.sym, e1.sym))
doubleDefError(new SymbolPair(base, e.sym, e1.sym))
diff --git a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
index b2e071579e..0447e23e9e 100644
--- a/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
+++ b/src/compiler/scala/tools/nsc/transform/ExplicitOuter.scala
@@ -206,7 +206,7 @@ abstract class ExplicitOuter extends InfoTransform
// On the other hand, mixing in the trait into a separately compiled
// class needs to have a common naming scheme, independently of whether
// the field was accessed from an inner class or not. See #2946
- if (sym.owner.isTrait && sym.hasLocalFlag &&
+ if (sym.owner.isTrait && sym.isLocalToThis &&
(sym.getter(sym.owner.toInterface) == NoSymbol))
sym.makeNotPrivate(sym.owner)
tp
diff --git a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
index acef2a50d8..e38c034f4d 100644
--- a/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
+++ b/src/compiler/scala/tools/nsc/transform/LambdaLift.scala
@@ -122,7 +122,7 @@ abstract class LambdaLift extends InfoTransform {
* and the owner of `sym`.
* Return `true` if there is no class between `enclosure` and
* the owner of sym.
- * pre: sym.isLocal, (enclosure.isMethod || enclosure.isClass)
+ * pre: sym.isLocalToBlock, (enclosure.isMethod || enclosure.isClass)
*
* The idea of `markFree` is illustrated with an example:
*
@@ -180,7 +180,7 @@ abstract class LambdaLift extends InfoTransform {
tree match {
case ClassDef(_, _, _, _) =>
liftedDefs(tree.symbol) = Nil
- if (sym.isLocal) {
+ if (sym.isLocalToBlock) {
// Don't rename implementation classes independently of their interfaces. If
// the interface is to be renamed, then we will rename the implementation
// class at that time. You'd think we could call ".implClass" on the trait
@@ -201,7 +201,7 @@ abstract class LambdaLift extends InfoTransform {
}
}
case DefDef(_, _, _, _, _, _) =>
- if (sym.isLocal) {
+ if (sym.isLocalToBlock) {
renamable += sym
sym setFlag (PrivateLocal | FINAL)
} else if (sym.isPrimaryConstructor) {
@@ -210,14 +210,14 @@ abstract class LambdaLift extends InfoTransform {
case Ident(name) =>
if (sym == NoSymbol) {
assert(name == nme.WILDCARD)
- } else if (sym.isLocal) {
+ } else if (sym.isLocalToBlock) {
val owner = currentOwner.logicallyEnclosingMember
if (sym.isTerm && !sym.isMethod) markFree(sym, owner)
else if (sym.isMethod) markCalled(sym, owner)
//symSet(called, owner) += sym
}
case Select(_, _) =>
- if (sym.isConstructor && sym.owner.isLocal)
+ if (sym.isConstructor && sym.owner.isLocalToBlock)
markCalled(sym, currentOwner.logicallyEnclosingMember)
case _ =>
}
@@ -362,7 +362,7 @@ abstract class LambdaLift extends InfoTransform {
private def proxyRef(sym: Symbol) = {
val psym = proxy(sym)
- if (psym.isLocal) gen.mkAttributedIdent(psym) else memberRef(psym)
+ if (psym.isLocalToBlock) gen.mkAttributedIdent(psym) else memberRef(psym)
}
private def addFreeArgs(pos: Position, sym: Symbol, args: List[Tree]) = {
@@ -459,10 +459,10 @@ abstract class LambdaLift extends InfoTransform {
tree match {
case ClassDef(_, _, _, _) =>
val tree1 = addFreeParams(tree, sym)
- if (sym.isLocal) liftDef(tree1) else tree1
+ if (sym.isLocalToBlock) liftDef(tree1) else tree1
case DefDef(_, _, _, _, _, _) =>
val tree1 = addFreeParams(tree, sym)
- if (sym.isLocal) liftDef(tree1) else tree1
+ if (sym.isLocalToBlock) liftDef(tree1) else tree1
case ValDef(mods, name, tpt, rhs) =>
if (sym.isCapturedVariable) {
val tpt1 = TypeTree(sym.tpe) setPos tpt.pos
@@ -499,7 +499,7 @@ abstract class LambdaLift extends InfoTransform {
if (sym.isTerm && !sym.isLabel)
if (sym.isMethod)
atPos(tree.pos)(memberRef(sym))
- else if (sym.isLocal && !isSameOwnerEnclosure(sym))
+ else if (sym.isLocalToBlock && !isSameOwnerEnclosure(sym))
atPos(tree.pos)(proxyRef(sym))
else tree
else tree
diff --git a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
index c59b726076..02e55241b3 100644
--- a/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
+++ b/src/compiler/scala/tools/nsc/transform/SpecializeTypes.scala
@@ -716,7 +716,6 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
enterMember(specVal)
// create accessors
- // debuglog("m: " + m + " isLocal: " + nme.isLocalName(m.name) + " specVal: " + specVal.name + " isLocal: " + nme.isLocalName(specVal.name))
if (nme.isLocalName(m.name)) {
val specGetter = mkAccessor(specVal, specVal.getterName) setInfo MethodType(Nil, specVal.info)
@@ -1653,7 +1652,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
case SpecialOverload(original, env) =>
debuglog("completing specialized " + symbol.fullName + " calling " + original)
debuglog("special overload " + original + " -> " + env)
- val t = DefDef(symbol, { vparamss =>
+ val t = DefDef(symbol, { vparamss: List[List[Symbol]] =>
val fun = Apply(Select(This(symbol.owner), original),
makeArguments(original, vparamss.head))
@@ -1751,7 +1750,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
// flag. nobody has to see this anyway :)
sym.setFlag(SPECIALIZED)
// create empty bodies for specializations
- localTyper.typed(Block(norm.tail.map(sym => DefDef(sym, { vparamss => EmptyTree })), ddef))
+ localTyper.typed(Block(norm.tail.map(sym => DefDef(sym, { vparamss: List[List[Symbol]] => EmptyTree })), ddef))
} else
tree
case _ =>
@@ -1816,7 +1815,7 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
val newBody = symSubstituter(body(source).duplicate)
tpt modifyType (_.substSym(oldtparams, newtparams))
- copyDefDef(tree)(vparamss = List(newSyms map ValDef), rhs = newBody)
+ copyDefDef(tree)(vparamss = List(newSyms map ValDef.apply), rhs = newBody)
}
/** Create trees for specialized members of 'sClass', based on the
@@ -1853,9 +1852,9 @@ abstract class SpecializeTypes extends InfoTransform with TypingTransformers {
}
// ctor
- mbrs += DefDef(m, Modifiers(m.flags), mmap(List(vparams))(ValDef), EmptyTree)
+ mbrs += DefDef(m, Modifiers(m.flags), mmap(List(vparams))(ValDef.apply), EmptyTree)
} else {
- mbrs += DefDef(m, { paramss => EmptyTree })
+ mbrs += DefDef(m, { paramss: List[List[Symbol]] => EmptyTree })
}
} else if (m.isValue) {
mbrs += ValDef(m).setType(NoType)
diff --git a/src/compiler/scala/tools/nsc/transform/UnCurry.scala b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
index e7ea686bc8..8a7d30235f 100644
--- a/src/compiler/scala/tools/nsc/transform/UnCurry.scala
+++ b/src/compiler/scala/tools/nsc/transform/UnCurry.scala
@@ -412,7 +412,7 @@ abstract class UnCurry extends InfoTransform
val sym = tree.symbol
// true if the taget is a lambda body that's been lifted into a method
- def isLiftedLambdaBody(target: Tree) = target.symbol.isLocal && target.symbol.isArtifact && target.symbol.name.containsName(nme.ANON_FUN_NAME)
+ def isLiftedLambdaBody(target: Tree) = target.symbol.isLocalToBlock && target.symbol.isArtifact && target.symbol.name.containsName(nme.ANON_FUN_NAME)
val result = (
// TODO - settings.noassertions.value temporarily retained to avoid
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 974c0842d3..98ee4ad94d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -516,7 +516,7 @@ trait Contexts { self: Analyzer =>
argContext.scope enter e.sym
}
}
- if (c.isLocal && !c.owner.isLocalDummy) {
+ if (c.owner.isTerm && !c.owner.isLocalDummy) {
enterElems(c.outer)
enterLocalElems(c.scope.elems)
}
@@ -589,9 +589,6 @@ trait Contexts { self: Analyzer =>
else if (bufferErrors) reportBuffer += (pos -> msg)
}
- /** Is the owning symbol of this context a term? */
- final def isLocal: Boolean = owner.isTerm
-
// nextOuter determines which context is searched next for implicits
// (after `this`, which contributes `newImplicits` below.) In
// most cases, it is simply the outer context: if we're owned by
@@ -714,7 +711,7 @@ trait Contexts { self: Analyzer =>
( (ab.isTerm || ab == rootMirror.RootClass)
|| (accessWithin(ab) || accessWithinLinked(ab)) &&
- ( !sym.hasLocalFlag
+ ( !sym.isLocalToThis
|| sym.owner.isImplClass // allow private local accesses to impl classes
|| sym.isProtected && isSubThisType(pre, sym.owner)
|| pre =:= sym.owner.thisType
@@ -980,7 +977,7 @@ trait Contexts { self: Analyzer =>
// 2) sym.owner is inherited by the correct package object class
// We try to establish 1) by inspecting the owners directly, and then we try
// to rule out 2), and only if both those fail do we resort to looking in the info.
- !sym.isPackage && sym.owner.exists && (
+ !sym.hasPackageFlag && sym.owner.exists && (
if (sym.owner.isPackageObjectClass)
sym.owner.owner == pkgClass
else
diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
index 8f5778862d..2bb874a8aa 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala
@@ -402,8 +402,8 @@ trait Implicits {
}
def complexity(tp: Type): Int = tp.dealias match {
case NoPrefix => 0
- case SingleType(pre, sym) => if (sym.isPackage) 0 else complexity(tp.dealiasWiden)
- case ThisType(sym) => if (sym.isPackage) 0 else 1
+ case SingleType(pre, sym) => if (sym.hasPackageFlag) 0 else complexity(tp.dealiasWiden)
+ case ThisType(sym) => if (sym.hasPackageFlag) 0 else 1
case TypeRef(pre, sym, args) => complexity(pre) + (args map complexity).sum + 1
case RefinedType(parents, _) => (parents map complexity).sum + 1
case _ => 1
@@ -425,11 +425,11 @@ trait Implicits {
* expected type.
* Detect infinite search trees for implicits.
*
- * @param info The given implicit info describing the implicit definition
- * @param isLocal Is the implicit in the local scope of the call site?
- * @pre `info.tpe` does not contain an error
+ * @param info The given implicit info describing the implicit definition
+ * @param isLocalToCallsite Is the implicit in the local scope of the call site?
+ * @pre `info.tpe` does not contain an error
*/
- private def typedImplicit(info: ImplicitInfo, ptChecked: Boolean, isLocal: Boolean): SearchResult = {
+ private def typedImplicit(info: ImplicitInfo, ptChecked: Boolean, isLocalToCallsite: Boolean): SearchResult = {
// SI-7167 let implicit macros decide what amounts for a divergent implicit search
// imagine a macro writer which wants to synthesize a complex implicit Complex[T] by making recursive calls to Complex[U] for its parts
// e.g. we have `class Foo(val bar: Bar)` and `class Bar(val x: Int)`
@@ -450,7 +450,7 @@ trait Implicits {
try {
context.openImplicits = OpenImplicit(info, pt, tree) :: context.openImplicits
// println(" "*context.openImplicits.length+"typed implicit "+info+" for "+pt) //@MDEBUG
- val result = typedImplicit0(info, ptChecked, isLocal)
+ val result = typedImplicit0(info, ptChecked, isLocalToCallsite)
if (result.isDivergent) {
//println("DivergentImplicit for pt:"+ pt +", open implicits:"+context.openImplicits) //@MDEBUG
if (context.openImplicits.tail.isEmpty && !pt.isErroneous)
@@ -574,24 +574,24 @@ trait Implicits {
case _ => false
}
- private def typedImplicit0(info: ImplicitInfo, ptChecked: Boolean, isLocal: Boolean): SearchResult = {
+ private def typedImplicit0(info: ImplicitInfo, ptChecked: Boolean, isLocalToCallsite: Boolean): SearchResult = {
if (Statistics.canEnable) Statistics.incCounter(plausiblyCompatibleImplicits)
val ok = ptChecked || matchesPt(info) && {
- def word = if (isLocal) "local " else ""
+ def word = if (isLocalToCallsite) "local " else ""
typingLog("match", s"$word$info")
true
}
- if (ok) typedImplicit1(info, isLocal) else SearchFailure
+ if (ok) typedImplicit1(info, isLocalToCallsite) else SearchFailure
}
- private def typedImplicit1(info: ImplicitInfo, isLocal: Boolean): SearchResult = {
+ private def typedImplicit1(info: ImplicitInfo, isLocalToCallsite: Boolean): SearchResult = {
if (Statistics.canEnable) Statistics.incCounter(matchingImplicits)
// workaround for deficient context provided by ModelFactoryImplicitSupport#makeImplicitConstraints
val isScalaDoc = context.tree == EmptyTree
val itree0 = atPos(pos.focus) {
- if (isLocal && !isScalaDoc) {
+ if (isLocalToCallsite && !isScalaDoc) {
// SI-4270 SI-5376 Always use an unattributed Ident for implicits in the local scope,
// rather than an attributed Select, to detect shadowing.
Ident(info.name)
@@ -661,7 +661,7 @@ trait Implicits {
fail("hasMatchingSymbol reported error: " + context.firstError.get.errMsg)
else if (itree3.isErroneous)
fail("error typechecking implicit candidate")
- else if (isLocal && !hasMatchingSymbol(itree2))
+ else if (isLocalToCallsite && !hasMatchingSymbol(itree2))
fail("candidate implicit %s is shadowed by %s".format(
info.sym.fullLocationString, itree2.symbol.fullLocationString))
else {
@@ -776,12 +776,12 @@ trait Implicits {
/** Prune ImplicitInfos down to either all the eligible ones or the best one.
*
- * @param iss list of list of infos
- * @param isLocal if true, `iss` represents in-scope implicits, which must respect the normal rules of
- * shadowing. The head of the list `iss` must represent implicits from the closest
- * enclosing scope, and so on.
+ * @param iss list of list of infos
+ * @param isLocalToCallsite if true, `iss` represents in-scope implicits, which must respect the normal rules of
+ * shadowing. The head of the list `iss` must represent implicits from the closest
+ * enclosing scope, and so on.
*/
- class ImplicitComputation(iss: Infoss, isLocal: Boolean) {
+ class ImplicitComputation(iss: Infoss, isLocalToCallsite: Boolean) {
abstract class Shadower {
def addInfos(infos: Infos)
def isShadowed(name: Name): Boolean
@@ -800,7 +800,7 @@ trait Implicits {
def addInfos(infos: Infos) {}
def isShadowed(name: Name) = false
}
- if (isLocal) new LocalShadower else NoShadower
+ if (isLocalToCallsite) new LocalShadower else NoShadower
}
private var best: SearchResult = SearchFailure
@@ -870,7 +870,7 @@ trait Implicits {
@tailrec private def rankImplicits(pending: Infos, acc: Infos): Infos = pending match {
case Nil => acc
case i :: is =>
- DivergentImplicitRecovery(typedImplicit(i, ptChecked = true, isLocal), i) match {
+ DivergentImplicitRecovery(typedImplicit(i, ptChecked = true, isLocalToCallsite), i) match {
case sr if sr.isDivergent =>
Nil
case sr if sr.isFailure =>
@@ -898,7 +898,7 @@ trait Implicits {
/** Returns all eligible ImplicitInfos and their SearchResults in a map.
*/
- def findAll() = mapFrom(eligible)(typedImplicit(_, ptChecked = false, isLocal))
+ def findAll() = mapFrom(eligible)(typedImplicit(_, ptChecked = false, isLocalToCallsite))
/** Returns the SearchResult of the best match.
*/
@@ -940,15 +940,15 @@ trait Implicits {
/** Computes from a list of lists of implicit infos a map which takes
* infos which are applicable for given expected type `pt` to their attributed trees.
*
- * @param iss The given list of lists of implicit infos
- * @param isLocal Is implicit definition visible without prefix?
- * If this is the case then symbols in preceding lists shadow
- * symbols of the same name in succeeding lists.
- * @return map from infos to search results
+ * @param iss The given list of lists of implicit infos
+ * @param isLocalToCallsite Is implicit definition visible without prefix?
+ * If this is the case then symbols in preceding lists shadow
+ * symbols of the same name in succeeding lists.
+ * @return map from infos to search results
*/
- def applicableInfos(iss: Infoss, isLocal: Boolean): Map[ImplicitInfo, SearchResult] = {
+ def applicableInfos(iss: Infoss, isLocalToCallsite: Boolean): Map[ImplicitInfo, SearchResult] = {
val start = if (Statistics.canEnable) Statistics.startCounter(subtypeAppInfos) else null
- val computation = new ImplicitComputation(iss, isLocal) { }
+ val computation = new ImplicitComputation(iss, isLocalToCallsite) { }
val applicable = computation.findAll()
if (Statistics.canEnable) Statistics.stopCounter(subtypeAppInfos, start)
@@ -959,14 +959,14 @@ trait Implicits {
* If found return a search result with a tree from found implicit info
* which is typed with expected type `pt`. Otherwise return SearchFailure.
*
- * @param implicitInfoss The given list of lists of implicit infos
- * @param isLocal Is implicit definition visible without prefix?
- * If this is the case then symbols in preceding lists shadow
- * symbols of the same name in succeeding lists.
+ * @param implicitInfoss The given list of lists of implicit infos
+ * @param isLocalToCallsite Is implicit definition visible without prefix?
+ * If this is the case then symbols in preceding lists shadow
+ * symbols of the same name in succeeding lists.
*/
- def searchImplicit(implicitInfoss: Infoss, isLocal: Boolean): SearchResult =
+ def searchImplicit(implicitInfoss: Infoss, isLocalToCallsite: Boolean): SearchResult =
if (implicitInfoss.forall(_.isEmpty)) SearchFailure
- else new ImplicitComputation(implicitInfoss, isLocal) findBest()
+ else new ImplicitComputation(implicitInfoss, isLocalToCallsite) findBest()
/** Produce an implicict info map, i.e. a map from the class symbols C of all parts of this type to
* the implicit infos in the companion objects of these class symbols C.
@@ -1271,7 +1271,8 @@ trait Implicits {
return SearchFailure
}
val cm = typed(Ident(ReflectRuntimeCurrentMirror))
- val interop = gen.mkMethodCall(ReflectRuntimeUniverse, nme.typeTagToManifest, List(tp), List(cm, tagInScope))
+ val internal = gen.mkAttributedSelect(gen.mkAttributedRef(ReflectRuntimeUniverse), UniverseInternal)
+ val interop = gen.mkMethodCall(Select(internal, nme.typeTagToManifest), List(tp), List(cm, tagInScope))
wrapResult(interop)
}
} else {
@@ -1326,7 +1327,7 @@ trait Implicits {
val failstart = if (Statistics.canEnable) Statistics.startTimer(inscopeFailNanos) else null
val succstart = if (Statistics.canEnable) Statistics.startTimer(inscopeSucceedNanos) else null
- var result = searchImplicit(context.implicitss, isLocal = true)
+ var result = searchImplicit(context.implicitss, isLocalToCallsite = true)
if (result.isFailure) {
if (Statistics.canEnable) Statistics.stopTimer(inscopeFailNanos, failstart)
@@ -1344,7 +1345,7 @@ trait Implicits {
// `materializeImplicit` does some preprocessing for `pt`
// is it only meant for manifests/tags or we need to do the same for `implicitsOfExpectedType`?
if (result.isFailure && !wasAmbigious)
- result = searchImplicit(implicitsOfExpectedType, isLocal = false)
+ result = searchImplicit(implicitsOfExpectedType, isLocalToCallsite = false)
if (result.isFailure) {
context.updateBuffer(previousErrs)
@@ -1383,8 +1384,11 @@ trait Implicits {
}
def allImplicits: List[SearchResult] = {
- def search(iss: Infoss, isLocal: Boolean) = applicableInfos(iss, isLocal).values
- (search(context.implicitss, isLocal = true) ++ search(implicitsOfExpectedType, isLocal = false)).toList.filter(_.tree ne EmptyTree)
+ def search(iss: Infoss, isLocalToCallsite: Boolean) = applicableInfos(iss, isLocalToCallsite).values
+ (
+ search(context.implicitss, isLocalToCallsite = true) ++
+ search(implicitsOfExpectedType, isLocalToCallsite = false)
+ ).toList.filter(_.tree ne EmptyTree)
}
// find all implicits for some type that contains type variables
@@ -1392,8 +1396,8 @@ trait Implicits {
def allImplicitsPoly(tvars: List[TypeVar]): List[(SearchResult, List[TypeConstraint])] = {
def resetTVars() = tvars foreach { _.constr = new TypeConstraint }
- def eligibleInfos(iss: Infoss, isLocal: Boolean) = {
- val eligible = new ImplicitComputation(iss, isLocal).eligible
+ def eligibleInfos(iss: Infoss, isLocalToCallsite: Boolean) = {
+ val eligible = new ImplicitComputation(iss, isLocalToCallsite).eligible
eligible.toList.flatMap {
(ii: ImplicitInfo) =>
// each ImplicitInfo contributes a distinct set of constraints (generated indirectly by typedImplicit)
@@ -1402,12 +1406,13 @@ trait Implicits {
// any previous errors should not affect us now
context.flushBuffer()
- val res = typedImplicit(ii, ptChecked = false, isLocal)
+ val res = typedImplicit(ii, ptChecked = false, isLocalToCallsite)
if (res.tree ne EmptyTree) List((res, tvars map (_.constr)))
else Nil
}
}
- eligibleInfos(context.implicitss, isLocal = true) ++ eligibleInfos(implicitsOfExpectedType, isLocal = false)
+ eligibleInfos(context.implicitss, isLocalToCallsite = true) ++
+ eligibleInfos(implicitsOfExpectedType, isLocalToCallsite = false)
}
}
diff --git a/src/compiler/scala/tools/nsc/typechecker/Namers.scala b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
index 9b5b0e1f37..23dc57d5b9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Namers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Namers.scala
@@ -374,7 +374,7 @@ trait Namers extends MethodSynthesis {
}
val existing = pkgOwner.info.decls.lookup(pid.name)
- if (existing.isPackage && pkgOwner == existing.owner)
+ if (existing.hasPackageFlag && pkgOwner == existing.owner)
existing
else {
val pkg = pkgOwner.newPackage(pid.name.toTermName, pos)
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index 916b8a3e0c..b166bf988d 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -908,7 +908,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
var index = -1
for (stat <- stats) {
index = index + 1
- def enterSym(sym: Symbol) = if (sym.isLocal) {
+ def enterSym(sym: Symbol) = if (sym.isLocalToBlock) {
currentLevel.scope.enter(sym)
symIndex(sym) = index
}
@@ -925,7 +925,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
}
private def enterReference(pos: Position, sym: Symbol) {
- if (sym.isLocal) {
+ if (sym.isLocalToBlock) {
val e = currentLevel.scope.lookupEntry(sym.name)
if ((e ne null) && sym == e.sym) {
var l = currentLevel
@@ -1230,7 +1230,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
if (tree1.symbol.isLazy) tree1 :: Nil
else {
val lazySym = tree.symbol.lazyAccessorOrSelf
- if (lazySym.isLocal && index <= currentLevel.maxindex) {
+ if (lazySym.isLocalToBlock && index <= currentLevel.maxindex) {
debuglog("refsym = " + currentLevel.refsym)
unit.error(currentLevel.refpos, "forward reference extends over definition of " + lazySym)
}
@@ -1549,7 +1549,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
if (!sym.exists)
devWarning("Select node has NoSymbol! " + tree + " / " + tree.tpe)
- else if (sym.hasLocalFlag)
+ else if (sym.isLocalToThis)
varianceValidator.checkForEscape(sym, currentClass)
def checkSuper(mix: Name) =
@@ -1758,7 +1758,7 @@ abstract class RefChecks extends InfoTransform with scala.reflect.internal.trans
result match {
case ClassDef(_, _, _, _)
| TypeDef(_, _, _, _) =>
- if (result.symbol.isLocal || result.symbol.isTopLevel)
+ if (result.symbol.isLocalToBlock || result.symbol.isTopLevel)
varianceValidator.traverse(result)
case tt @ TypeTree() if tt.original != null =>
varianceValidator.traverse(tt.original) // See SI-7872
diff --git a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
index 06796eca8e..87da565142 100644
--- a/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/SuperAccessors.scala
@@ -71,7 +71,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
acc setInfoAndEnter (tpe cloneInfo acc)
// Diagnostic for SI-7091
if (!accDefs.contains(clazz))
- reporter.error(sel.pos, s"Internal error: unable to store accessor definition in ${clazz}. clazz.isPackage=${clazz.isPackage}. Accessor required for ${sel} (${showRaw(sel)})")
+ reporter.error(sel.pos, s"Internal error: unable to store accessor definition in ${clazz}. clazz.hasPackageFlag=${clazz.hasPackageFlag}. Accessor required for ${sel} (${showRaw(sel)})")
else storeAccessorDefinition(clazz, DefDef(acc, EmptyTree))
acc
}
@@ -224,7 +224,7 @@ abstract class SuperAccessors extends transform.Transform with transform.TypingT
if (settings.lint) {
if (sym.isPrivateLocal && sym.paramss.isEmpty) {
qual.symbol.ancestors foreach { parent =>
- parent.info.decls filterNot (x => x.isPrivate || x.hasLocalFlag) foreach { m2 =>
+ parent.info.decls filterNot (x => x.isPrivate || x.isLocalToThis) foreach { m2 =>
if (sym.name == m2.name && m2.isGetter && m2.accessed.isMutable) {
unit.warning(sel.pos,
sym.accessString + " " + sym.fullLocationString + " shadows mutable " + m2.name
diff --git a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
index fd8f9bebba..a2f52e1905 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TreeCheckers.scala
@@ -376,7 +376,7 @@ abstract class TreeCheckers extends Analyzer {
def isOk(sym: Symbol) = treeSym hasTransOwner sym.enclosingSuchThat(x => !x.isTypeParameterOrSkolem) // account for higher order type params
def isEligible(sym: Symbol) = (sym ne NoSymbol) && (
sym.isTypeParameter
- || sym.isLocal
+ || sym.isLocalToBlock
)
val referencedSymbols = (treeSym :: referencesInType(treeInfo)).distinct filter (sym => isEligible(sym) && !isOk(sym))
def mk[T](what: String, x: T, str: T => String = (x: T) => "" + x): ((Any, String)) =
diff --git a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
index dfa1b6db0f..60346e7be1 100644
--- a/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/TypeDiagnostics.scala
@@ -452,10 +452,10 @@ trait TypeDiagnostics {
val treeTypes = mutable.Set[Type]()
def defnSymbols = defnTrees.toList map (_.symbol)
- def localVars = defnSymbols filter (t => t.isLocal && t.isVar)
+ def localVars = defnSymbols filter (t => t.isLocalToBlock && t.isVar)
def qualifiesTerm(sym: Symbol) = (
- (sym.isModule || sym.isMethod || sym.isPrivateLocal || sym.isLocal)
+ (sym.isModule || sym.isMethod || sym.isPrivateLocal || sym.isLocalToBlock)
&& !nme.isLocalName(sym.name)
&& !sym.isParameter
&& !sym.isParamAccessor // could improve this, but it's a pain
@@ -499,12 +499,12 @@ trait TypeDiagnostics {
def isUnusedType(m: Symbol): Boolean = (
m.isType
&& !m.isTypeParameterOrSkolem // would be nice to improve this
- && (m.isPrivate || m.isLocal)
+ && (m.isPrivate || m.isLocalToBlock)
&& !(treeTypes.exists(tp => tp exists (t => t.typeSymbolDirect == m)))
)
def isUnusedTerm(m: Symbol): Boolean = (
(m.isTerm)
- && (m.isPrivate || m.isLocal)
+ && (m.isPrivate || m.isLocalToBlock)
&& !targets(m)
&& !(m.name == nme.WILDCARD) // e.g. val _ = foo
&& !ignoreNames(m.name.toTermName) // serialization methods
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index f4d2a2cea0..8721450dc9 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -393,7 +393,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
if (sym.isPrivate && !sym.hasFlag(SYNTHETIC_PRIVATE)) {
var o = owner
while (o != NoSymbol && o != sym.owner && o != sym.owner.linkedClassOfClass &&
- !o.isLocal && !o.isPrivate &&
+ !o.isLocalToBlock && !o.isPrivate &&
!o.privateWithin.hasTransOwner(sym.owner))
o = o.owner
if (o == sym.owner || o == sym.owner.linkedClassOfClass)
@@ -3015,7 +3015,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
/* 'accessor' and 'accessed' are so similar it becomes very difficult to
* follow the logic, so I renamed one to something distinct.
*/
- def accesses(looker: Symbol, accessed: Symbol) = accessed.hasLocalFlag && (
+ def accesses(looker: Symbol, accessed: Symbol) = accessed.isLocalToThis && (
(accessed.isParamAccessor)
|| (looker.hasAccessorFlag && !accessed.hasAccessorFlag && accessed.isPrivate)
)
diff --git a/src/compiler/scala/tools/reflect/ReflectGlobal.scala b/src/compiler/scala/tools/reflect/ReflectGlobal.scala
index 6f369212ad..ac63232967 100644
--- a/src/compiler/scala/tools/reflect/ReflectGlobal.scala
+++ b/src/compiler/scala/tools/reflect/ReflectGlobal.scala
@@ -37,5 +37,13 @@ class ReflectGlobal(currentSettings: Settings, reporter: Reporter, override val
// (each mirror has its own set package symbols, because of the peculiarities of symbol loading in scala),
// that `Predef` symbol only has a single owner, and this messes up visibility, which is calculated based on owners, not scopes.
override def runtimeMirror(cl: ClassLoader): Mirror = rootMirror
+
+ // Mirror and RuntimeClass come from both Global and reflect.runtime.SymbolTable
+ // so here the compiler needs an extra push to help decide between those (in favor of the latter)
+ import scala.reflect.ClassTag
+ override type Mirror = JavaMirror
+ override implicit val MirrorTag: ClassTag[Mirror] = ClassTag[Mirror](classOf[Mirror])
+ override type RuntimeClass = java.lang.Class[_]
+ override implicit val RuntimeClassTag: ClassTag[RuntimeClass] = ClassTag[RuntimeClass](classOf[RuntimeClass])
}
diff --git a/src/compiler/scala/tools/reflect/StdTags.scala b/src/compiler/scala/tools/reflect/StdTags.scala
index 5c53c81e8b..ee352c5e02 100644
--- a/src/compiler/scala/tools/reflect/StdTags.scala
+++ b/src/compiler/scala/tools/reflect/StdTags.scala
@@ -18,8 +18,7 @@ trait StdTags {
new TypeCreator {
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))
+ u.appliedType(u.definitions.ListClass.toType, List(u.definitions.StringClass.toType))
}
})
diff --git a/src/compiler/scala/tools/reflect/ToolBox.scala b/src/compiler/scala/tools/reflect/ToolBox.scala
index 4a3db09909..dfe53be6c9 100644
--- a/src/compiler/scala/tools/reflect/ToolBox.scala
+++ b/src/compiler/scala/tools/reflect/ToolBox.scala
@@ -21,19 +21,39 @@ trait ToolBox[U <: scala.reflect.api.Universe] {
*/
def frontEnd: FrontEnd
+ /** Represents mode of operations of the typechecker underlying `c.typecheck` calls.
+ * Is necessary since the shape of the typechecked tree alone is not enough to guess how it should be typechecked.
+ * Can be EXPRmode (typecheck as a term), TYPEmode (typecheck as a type) or PATTERNmode (typecheck as a pattern).
+ */
+ type TypecheckMode
+
+ /** Indicates that an argument to `c.typecheck` should be typechecked as a term.
+ * This is the default typechecking mode in Scala 2.11 and the only one supported in Scala 2.10.
+ */
+ val TERMmode: TypecheckMode
+
+ /** Indicates that an argument to `c.typecheck` should be typechecked as a type.
+ */
+ val TYPEmode: TypecheckMode
+
+ /** Indicates that an argument to `c.typecheck` should be typechecked as a pattern.
+ */
+ val PATTERNmode: TypecheckMode
+
/** @see `Typers.typecheck`
*/
@deprecated("Use `tb.typecheck` instead", "2.11.0")
def typeCheck(tree: u.Tree, pt: u.Type = u.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree =
- typecheck(tree, pt, silent, withImplicitViewsDisabled, withMacrosDisabled)
+ typecheck(tree, TERMmode, pt, silent, withImplicitViewsDisabled, withMacrosDisabled)
- /** Typechecks a tree using this ToolBox.
+ /** Typechecks a tree against the expected type `pt`
+ * under typechecking mode specified in `mode` with [[EXPRmode]] being default.
* This populates symbols and types of the tree and possibly transforms it to reflect certain desugarings.
*
* If the tree has unresolved type variables (represented as instances of `FreeTypeSymbol` symbols),
* then they all have to be resolved first using `Tree.substituteTypes`, or an error occurs.
*
- * If `silent` is false, `TypeError` will be thrown in case of a typecheck error.
+ * If `silent` is false, `ToolBoxError` will be thrown in case of a typecheck error.
* If `silent` is true, the typecheck is silent and will return `EmptyTree` if an error occurs.
* Such errors don't vanish and can be inspected by turning on -Ydebug.
*
@@ -41,7 +61,7 @@ trait ToolBox[U <: scala.reflect.api.Universe] {
* `withImplicitViewsDisabled` recursively prohibits implicit views (though, implicit vals will still be looked up and filled in), default value is false
* `withMacrosDisabled` recursively prohibits macro expansions and macro-based implicits, default value is false
*/
- def typecheck(tree: u.Tree, pt: u.Type = u.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree
+ def typecheck(tree: u.Tree, mode: TypecheckMode = TERMmode, pt: u.Type = u.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree
/** Infers an implicit value of the expected type `pt` in top-level context.
* Optional `pos` parameter provides a position that will be associated with the implicit search.
@@ -50,7 +70,7 @@ trait ToolBox[U <: scala.reflect.api.Universe] {
* this API won't take into account the lexical context of the callsite, because
* currently it's impossible to reify it.
*
- * If `silent` is false, `TypeError` will be thrown in case of an inference error.
+ * If `silent` is false, `ToolBoxError` will be thrown in case of an inference error.
* If `silent` is true, the typecheck is silent and will return `EmptyTree` if an error occurs.
* Such errors don't vanish and can be inspected by turning on -Xlog-implicits.
* Unlike in `typecheck`, `silent` is true by default.
@@ -64,7 +84,7 @@ trait ToolBox[U <: scala.reflect.api.Universe] {
* this API won't take into account the lexical context of the callsite, because
* currently it's impossible to reify it.
*
- * If `silent` is false, `TypeError` will be thrown in case of an inference error.
+ * If `silent` is false, `ToolBoxError` will be thrown in case of an inference error.
* If `silent` is true, the typecheck is silent and will return `EmptyTree` if an error occurs.
* Such errors don't vanish and can be inspected by turning on -Xlog-implicits.
* Unlike in `typecheck`, `silent` is true by default.
diff --git a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
index 6fabac9fe8..3b12086cc7 100644
--- a/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
+++ b/src/compiler/scala/tools/reflect/ToolBoxFactory.scala
@@ -116,8 +116,9 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
(expr, freeTermNames)
}
- def transformDuringTyper(expr: Tree, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean)(transform: (analyzer.Typer, Tree) => Tree): Tree = {
- wrappingIntoTerm(verify(expr))(expr1 => {
+ def transformDuringTyper(expr: Tree, mode: scala.reflect.internal.Mode, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean)(transform: (analyzer.Typer, Tree) => Tree): Tree = {
+ def withWrapping(tree: Tree)(op: Tree => Tree) = if (mode == TERMmode) wrappingIntoTerm(tree)(op) else op(tree)
+ withWrapping(verify(expr))(expr1 => {
// need to extract free terms, because otherwise you won't be able to typecheck macros against something that contains them
val exprAndFreeTerms = extractFreeTerms(expr1, wrapFreeTermRefs = false)
var expr2 = exprAndFreeTerms._1
@@ -130,7 +131,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
// rather than polluting the empty package with synthetics.
// [Eugene] how can we implement that?
val ownerClass = rootMirror.EmptyPackageClass.newClassSymbol(newTypeName("<expression-owner>"))
- build.setTypeSignature(ownerClass, ClassInfoType(List(ObjectTpe), newScope, ownerClass))
+ build.setInfo(ownerClass, ClassInfoType(List(ObjectTpe), newScope, ownerClass))
val owner = ownerClass.newLocalDummy(expr2.pos)
val currentTyper = analyzer.newTyper(analyzer.rootContext(NoCompilationUnit, EmptyTree).make(expr2, owner))
val withImplicitFlag = if (!withImplicitViewsDisabled) (currentTyper.context.withImplicitsEnabled[Tree] _) else (currentTyper.context.withImplicitsDisabled[Tree] _)
@@ -163,11 +164,11 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
})
}
- def typecheck(expr: Tree, pt: Type, silent: Boolean, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean): Tree =
- transformDuringTyper(expr, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)(
+ def typecheck(expr: Tree, pt: Type, mode: scala.reflect.internal.Mode, silent: Boolean, withImplicitViewsDisabled: Boolean, withMacrosDisabled: Boolean): Tree =
+ transformDuringTyper(expr, mode, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)(
(currentTyper, expr) => {
trace("typing (implicit views = %s, macros = %s): ".format(!withImplicitViewsDisabled, !withMacrosDisabled))(showAttributed(expr, true, true, settings.Yshowsymowners.value, settings.Yshowsymkinds.value))
- currentTyper.silent(_.typed(expr, pt), reportAmbiguousErrors = false) match {
+ currentTyper.silent(_.typed(expr, mode, pt), reportAmbiguousErrors = false) match {
case analyzer.SilentResultValue(result) =>
trace("success: ")(showAttributed(result, true, true, settings.Yshowsymkinds.value))
result
@@ -179,7 +180,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
})
def inferImplicit(tree: Tree, pt: Type, isView: Boolean, silent: Boolean, withMacrosDisabled: Boolean, pos: Position): Tree =
- transformDuringTyper(tree, withImplicitViewsDisabled = false, withMacrosDisabled = withMacrosDisabled)(
+ transformDuringTyper(tree, TERMmode, withImplicitViewsDisabled = false, withMacrosDisabled = withMacrosDisabled)(
(currentTyper, tree) => {
trace("inferring implicit %s (macros = %s): ".format(if (isView) "view" else "value", !withMacrosDisabled))(showAttributed(pt, true, true, settings.Yshowsymowners.value, settings.Yshowsymkinds.value))
analyzer.inferImplicit(tree, pt, isView, currentTyper.context, silent, withMacrosDisabled, pos, (pos, msg) => throw ToolBoxError(msg))
@@ -209,7 +210,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
val (expr, freeTerms) = extractFreeTerms(expr0, wrapFreeTermRefs = true)
val (obj, _) = rootMirror.EmptyPackageClass.newModuleAndClassSymbol(
- nextWrapperModuleName())
+ nextWrapperModuleName(), NoPosition, NoFlags)
val minfo = ClassInfoType(List(ObjectTpe), newScope, obj.moduleClass)
obj.moduleClass setInfo minfo
@@ -356,7 +357,13 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
}
}
- def typecheck(tree: u.Tree, expectedType: u.Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree = withCompilerApi { compilerApi =>
+ type TypecheckMode = scala.reflect.internal.Mode
+ val TypecheckMode = scala.reflect.internal.Mode
+ val TERMmode = TypecheckMode.EXPRmode
+ val TYPEmode = TypecheckMode.TYPEmode | TypecheckMode.FUNmode
+ val PATTERNmode = TypecheckMode.PATTERNmode
+
+ def typecheck(tree: u.Tree, mode: TypecheckMode = TERMmode, expectedType: u.Type, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): u.Tree = withCompilerApi { compilerApi =>
import compilerApi._
if (compiler.settings.verbose) println("importing "+tree+", expectedType = "+expectedType)
@@ -364,7 +371,7 @@ abstract class ToolBoxFactory[U <: JavaUniverse](val u: U) { factorySelf =>
val cexpectedType: compiler.Type = importer.importType(expectedType)
if (compiler.settings.verbose) println("typing "+ctree+", expectedType = "+expectedType)
- val ttree: compiler.Tree = compiler.typecheck(ctree, cexpectedType, silent = silent, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)
+ val ttree: compiler.Tree = compiler.typecheck(ctree, cexpectedType, mode, silent = silent, withImplicitViewsDisabled = withImplicitViewsDisabled, withMacrosDisabled = withMacrosDisabled)
val uttree = exporter.importTree(ttree)
uttree
}
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
index 2027d43264..c2f1bf430d 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
@@ -120,8 +120,8 @@ trait Holes { self: Quasiquotes =>
}
private def toStats(tree: Tree): Tree =
- // q"$u.build.toStats($tree)"
- Apply(Select(Select(u, nme.build), nme.toStats), tree :: Nil)
+ // q"$u.internal.reificationSupport.toStats($tree)"
+ Apply(Select(Select(Select(u, nme.internal), nme.reificationSupport), nme.toStats), tree :: Nil)
private def toList(tree: Tree, tpe: Type): Tree =
if (isListType(tpe)) tree
@@ -234,10 +234,10 @@ trait Holes { self: Quasiquotes =>
}
val lifter = inferUnliftable(tpe)
assert(helperName.isTermName)
- // q"val $name: $u.build.${helperName.toTypeName} = $u.build.$helperName($lifter)"
+ // q"val $name: $u.internal.reificationSupport.${helperName.toTypeName} = $u.internal.reificationSupport.$helperName($lifter)"
ValDef(NoMods, name,
- AppliedTypeTree(Select(Select(u, nme.build), helperName.toTypeName), List(TypeTree(tpe))),
- Apply(Select(Select(u, nme.build), helperName), lifter :: Nil))
+ AppliedTypeTree(Select(Select(Select(u, nme.internal), nme.reificationSupport), helperName.toTypeName), List(TypeTree(tpe))),
+ Apply(Select(Select(Select(u, nme.internal), nme.reificationSupport), helperName), lifter :: Nil))
}
}
}
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala
index 130a01332b..e7730f878f 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala
@@ -42,7 +42,7 @@ trait Placeholders { self: Quasiquotes =>
case nme.apply => args
case nme.unapply =>
val (dummy @ Ident(nme.SELECTOR_DUMMY)) :: Nil = args
- dummy.attachments.get[SubpatternsAttachment].get.patterns
+ internal.subpatterns(dummy).get
case _ => global.abort("unreachable")
}
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
index 70580adbce..339937adc3 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
@@ -7,7 +7,7 @@ import scala.reflect.internal.Flags._
trait Reifiers { self: Quasiquotes =>
import global._
- import global.build.{Select => _, Ident => _, TypeTree => _, _}
+ import global.build._
import global.treeInfo._
import global.definitions._
import Cardinality._
@@ -64,9 +64,9 @@ trait Reifiers { self: Quasiquotes =>
val FreshName(prefix) = origname
val nameTypeName = if (origname.isTermName) tpnme.TermName else tpnme.TypeName
val freshName = if (origname.isTermName) nme.freshTermName else nme.freshTypeName
- // q"val ${names.head}: $u.$nameTypeName = $u.build.$freshName($prefix)"
+ // q"val ${names.head}: $u.$nameTypeName = $u.internal.reificationSupport.$freshName($prefix)"
ValDef(NoMods, names.head, Select(u, nameTypeName),
- Apply(Select(Select(u, nme.build), freshName), Literal(Constant(prefix)) :: Nil))
+ Apply(Select(Select(Select(u, nme.internal), nme.reificationSupport), freshName), Literal(Constant(prefix)) :: Nil))
}.toList
// q"..$freshdefs; $tree"
SyntacticBlock(freshdefs :+ tree)
@@ -146,7 +146,7 @@ trait Reifiers { self: Quasiquotes =>
override def reifyTreeSyntactically(tree: Tree) = tree match {
case RefTree(qual, SymbolPlaceholder(Hole(tree, _))) if isReifyingExpressions =>
- mirrorBuildCall(nme.RefTree, reify(qual), tree)
+ mirrorBuildCall(nme.mkRefTree, reify(qual), tree)
case This(SymbolPlaceholder(Hole(tree, _))) if isReifyingExpressions =>
mirrorCall(nme.This, tree)
case SyntacticTraitDef(mods, name, tparams, earlyDefs, parents, selfdef, body) =>
@@ -365,7 +365,7 @@ trait Reifiers { self: Quasiquotes =>
Apply(Select(universe, name), args.toList)
override def mirrorBuildCall(name: TermName, args: Tree*): Tree =
- Apply(Select(Select(universe, nme.build), name), args.toList)
+ Apply(Select(Select(Select(universe, nme.internal), nme.reificationSupport), name), args.toList)
override def scalaFactoryCall(name: String, args: Tree*): Tree =
call("scala." + name, args: _*)
diff --git a/src/reflect/scala/reflect/api/Annotations.scala b/src/reflect/scala/reflect/api/Annotations.scala
index e19e0cefad..b880fad756 100644
--- a/src/reflect/scala/reflect/api/Annotations.scala
+++ b/src/reflect/scala/reflect/api/Annotations.scala
@@ -5,11 +5,11 @@ package api
import scala.collection.immutable.ListMap
/**
- * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
+ * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
*
- * This trait provides annotation support for the reflection API.
+ * This trait provides annotation support for the reflection API.
*
- * The API distinguishes between two kinds of annotations:
+ * In Scala, annotations belong to one of the two categories:
*
* <ul>
* <li>''Java annotations'': annotations on definitions produced by the Java compiler, i.e., subtypes of [[java.lang.annotation.Annotation]]
@@ -22,16 +22,13 @@ import scala.collection.immutable.ListMap
* it is stored as special attributes in the corresponding classfile, and not as a Java annotation. Note that subclassing
* just [[scala.annotation.Annotation]] is not enough to have the corresponding metadata persisted for runtime reflection.
*
- * The distinction between Java and Scala annotations is manifested in the contract of [[scala.reflect.api.Annotations#Annotation]], which exposes
- * both `scalaArgs` and `javaArgs`. For Scala or Java annotations extending [[scala.annotation.ClassfileAnnotation]] `scalaArgs` is empty
- * and arguments are stored in `javaArgs`. For all other Scala annotations, arguments are stored in `scalaArgs` and `javaArgs` is empty.
+ * Both Java and Scala annotations are represented as typed trees carrying constructor invocations corresponding
+ * to the annotation. For instance, the annotation in `@ann(1, 2) class C` is represented as `q"@new ann(1, 2)"`.
*
- * Arguments in `scalaArgs` are represented as typed trees. Note that these trees are not transformed by any phases
- * following the type-checker. Arguments in `javaArgs` are repesented as a map from [[scala.reflect.api.Names#Name]] to
- * [[scala.reflect.api.Annotations#JavaArgument]]. Instances of `JavaArgument` represent different kinds of Java annotation arguments:
- * - literals (primitive and string constants),
- * - arrays and
- * - nested annotations.
+ * Unlike Java reflection, Scala reflection does not support evaluation of constructor invocations stored in annotations
+ * into underlying objects. For instance it's impossible to go from `@ann(1, 2) class C` to `ann(1, 2)`, so one
+ * has to analyze trees representing annotation arguments to manually extract corresponding values. Towards that end,
+ * arguments of an annotation can be obtained via `annotation.tree.children.tail`.
*
* For more information about `Annotation`s, see the [[http://docs.scala-lang.org/overviews/reflection/annotations-names-scopes.html Reflection Guide: Annotations, Names, Scopes, and More]]
*
@@ -46,17 +43,22 @@ trait Annotations { self: Universe =>
*/
type Annotation >: Null <: AnyRef with AnnotationApi
- /** The constructor/extractor for `Annotation` instances.
- * @group Extractors
- */
- val Annotation: AnnotationExtractor
+ /** The constructor/extractor for `Annotation` instances.
+ * @group Extractors
+ */
+ val Annotation: AnnotationExtractor
/** An extractor class to create and pattern match with syntax `Annotation(tpe, scalaArgs, javaArgs)`.
* Here, `tpe` is the annotation type, `scalaArgs` the payload of Scala annotations, and `javaArgs` the payload of Java annotations.
* @group Extractors
*/
abstract class AnnotationExtractor {
+ def apply(tree: Tree): Annotation = treeToAnnotation(tree)
+
+ @deprecated("Use `apply(tree: Tree): Annotation` instead", "2.11.0")
def apply(tpe: Type, scalaArgs: List[Tree], javaArgs: ListMap[Name, JavaArgument]): Annotation
+
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
def unapply(ann: Annotation): Option[(Type, List[Tree], ListMap[Name, JavaArgument])]
}
@@ -65,44 +67,64 @@ trait Annotations { self: Universe =>
* @group API
*/
trait AnnotationApi {
+ /** The tree underlying the annotation. */
+ def tree: Tree = annotationToTree(this.asInstanceOf[Annotation])
+
/** The type of the annotation. */
+ @deprecated("Use `tree.tpe` instead", "2.11.0")
def tpe: Type
/** Payload of the Scala annotation: a list of abstract syntax trees that represent the argument.
* Empty for Java annotations.
*/
+ @deprecated("Use `tree.children.tail` instead", "2.11.0")
def scalaArgs: List[Tree]
/** Payload of the Java annotation: a list of name-value pairs.
* Empty for Scala annotations.
*/
+ @deprecated("Use `tree.children.tail` instead", "2.11.0")
def javaArgs: ListMap[Name, JavaArgument]
}
+ protected[scala] def annotationToTree(ann: Annotation): Tree
+ protected[scala] def treeToAnnotation(tree: Tree): Annotation
+
/** A Java annotation argument
* @template
* @group Annotations
*/
- type JavaArgument >: Null <: AnyRef
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
+ type JavaArgument >: Null <: AnyRef with JavaArgumentApi
+ /** Has no special methods. Is here to provides erased identity for `CompoundType`.
+ * @group API
+ */
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
+ trait JavaArgumentApi
/** A literal argument to a Java annotation as `"Use X instead"` in `@Deprecated("Use X instead")`
* @template
* @group Annotations
*/
- type LiteralArgument >: Null <: AnyRef with JavaArgument with LiteralArgumentApi
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
+ type LiteralArgument >: Null <: LiteralArgumentApi with JavaArgument
/** The constructor/extractor for `LiteralArgument` instances.
* @group Extractors
*/
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
val LiteralArgument: LiteralArgumentExtractor
/** An extractor class to create and pattern match with syntax `LiteralArgument(value)`
* where `value` is the constant argument.
* @group Extractors
*/
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
abstract class LiteralArgumentExtractor {
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
def apply(value: Constant): LiteralArgument
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
def unapply(arg: LiteralArgument): Option[Constant]
}
@@ -110,8 +132,10 @@ trait Annotations { self: Universe =>
* The main source of information about annotations is the [[scala.reflect.api.Annotations]] page.
* @group API
*/
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
trait LiteralArgumentApi {
/** The underlying compile-time constant value. */
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
def value: Constant
}
@@ -119,19 +143,24 @@ trait Annotations { self: Universe =>
* @template
* @group Annotations
*/
- type ArrayArgument >: Null <: AnyRef with JavaArgument with ArrayArgumentApi
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
+ type ArrayArgument >: Null <: ArrayArgumentApi with JavaArgument
/** The constructor/extractor for `ArrayArgument` instances.
* @group Extractors
*/
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
val ArrayArgument: ArrayArgumentExtractor
/** An extractor class to create and pattern match with syntax `ArrayArgument(args)`
* where `args` is the argument array.
* @group Extractors
*/
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
abstract class ArrayArgumentExtractor {
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
def apply(args: Array[JavaArgument]): ArrayArgument
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
def unapply(arg: ArrayArgument): Option[Array[JavaArgument]]
}
@@ -139,8 +168,10 @@ trait Annotations { self: Universe =>
* The main source of information about annotations is the [[scala.reflect.api.Annotations]] page.
* @group API
*/
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
trait ArrayArgumentApi {
/** The underlying array of Java annotation arguments. */
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
def args: Array[JavaArgument]
}
@@ -148,19 +179,24 @@ trait Annotations { self: Universe =>
* @template
* @group Annotations
*/
- type NestedArgument >: Null <: AnyRef with JavaArgument with NestedArgumentApi
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
+ type NestedArgument >: Null <: NestedArgumentApi with JavaArgument
/** The constructor/extractor for `NestedArgument` instances.
* @group Extractors
*/
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
val NestedArgument: NestedArgumentExtractor
/** An extractor class to create and pattern match with syntax `NestedArgument(annotation)`
* where `annotation` is the nested annotation.
* @group Extractors
*/
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
abstract class NestedArgumentExtractor {
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
def apply(annotation: Annotation): NestedArgument
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
def unapply(arg: NestedArgument): Option[Annotation]
}
@@ -168,8 +204,10 @@ trait Annotations { self: Universe =>
* The main source of information about annotations is the [[scala.reflect.api.Annotations]] page.
* @group API
*/
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
trait NestedArgumentApi {
/** The underlying nested annotation. */
+ @deprecated("Use `Annotation.tree` to inspect annotation arguments", "2.11.0")
def annotation: Annotation
}
}
diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala
deleted file mode 100644
index 57dc7da6cc..0000000000
--- a/src/reflect/scala/reflect/api/BuildUtils.scala
+++ /dev/null
@@ -1,306 +0,0 @@
-package scala
-package reflect
-package api
-
-/**
- * This is an internal implementation class.
- * @groupname TreeBuilders Tree Building
- */
-private[reflect] trait BuildUtils { self: Universe =>
-
- /** @group TreeBuilders */
- val build: BuildApi
-
- // this API abstracts away the functionality necessary for reification
- // it's too gimmicky and unstructured to be exposed directly in the universe
- // but we need it in a publicly available place for reification to work
-
- /** @group TreeBuilders */
- abstract class BuildApi {
- /** Selects type symbol with given simple name `name` from the defined members of `owner`.
- */
- def selectType(owner: Symbol, name: String): TypeSymbol
-
- /** Selects term symbol with given name and type from the defined members of prefix type
- */
- def selectTerm(owner: Symbol, name: String): TermSymbol
-
- /** Selects overloaded method symbol with given name and index
- */
- def selectOverloadedMethod(owner: Symbol, name: String, index: Int): MethodSymbol
-
- /** A fresh symbol with given name `name`, position `pos` and flags `flags` that has
- * the current symbol as its owner.
- */
- def newNestedSymbol(owner: Symbol, name: Name, pos: Position, flags: FlagSet, isClass: Boolean): Symbol
-
- /** Create a fresh free term symbol.
- * @param name the name of the free variable
- * @param value the value of the free variable at runtime
- * @param flags (optional) flags of the free variable
- * @param origin debug information that tells where this symbol comes from
- */
- def newFreeTerm(name: String, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTermSymbol
-
- /** Create a fresh free type symbol.
- * @param name the name of the free variable
- * @param flags (optional) flags of the free variable
- * @param origin debug information that tells where this symbol comes from
- */
- def newFreeType(name: String, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol
-
- /** Set symbol's type signature to given type.
- * @return the symbol itself
- */
- def setTypeSignature[S <: Symbol](sym: S, tpe: Type): S
-
- /** Set symbol's annotations to given annotations `annots`.
- */
- def setAnnotations[S <: Symbol](sym: S, annots: List[Annotation]): S
-
- def This(sym: Symbol): Tree
-
- def Select(qualifier: Tree, sym: Symbol): Select
-
- def Ident(sym: Symbol): Ident
-
- def TypeTree(tp: Type): TypeTree
-
- def thisPrefix(sym: Symbol): Type
-
- def setType[T <: Tree](tree: T, tpe: Type): T
-
- def setSymbol[T <: Tree](tree: T, sym: Symbol): T
-
- def toStats(tree: Tree): List[Tree]
-
- def mkAnnotation(tree: Tree): Tree
-
- def mkAnnotation(trees: List[Tree]): List[Tree]
-
- def mkRefineStat(stat: Tree): Tree
-
- def mkRefineStat(stats: List[Tree]): List[Tree]
-
- def mkPackageStat(stat: Tree): Tree
-
- def mkPackageStat(stats: List[Tree]): List[Tree]
-
- def mkEarlyDef(defn: Tree): Tree
-
- def mkEarlyDef(defns: List[Tree]): List[Tree]
-
- def RefTree(qual: Tree, sym: Symbol): Tree
-
- def freshTermName(prefix: String): TermName
-
- def freshTypeName(prefix: String): TypeName
-
- val ImplicitParams: ImplicitParamsExtractor
-
- trait ImplicitParamsExtractor {
- def apply(paramss: List[List[ValDef]], implparams: List[ValDef]): List[List[ValDef]]
- def unapply(vparamss: List[List[ValDef]]): Some[(List[List[ValDef]], List[ValDef])]
- }
-
- val ScalaDot: ScalaDotExtractor
-
- trait ScalaDotExtractor {
- def apply(name: Name): Tree
- def unapply(tree: Tree): Option[Name]
- }
-
- val FlagsRepr: FlagsReprExtractor
-
- trait FlagsReprExtractor {
- def apply(value: Long): FlagSet
- def unapply(flags: Long): Some[Long]
- }
-
- val SyntacticTypeApplied: SyntacticTypeAppliedExtractor
-
- trait SyntacticTypeAppliedExtractor {
- def apply(tree: Tree, targs: List[Tree]): Tree
- def unapply(tree: Tree): Some[(Tree, List[Tree])]
- }
-
- val SyntacticApplied: SyntacticAppliedExtractor
-
- trait SyntacticAppliedExtractor {
- def apply(tree: Tree, argss: List[List[Tree]]): Tree
- def unapply(tree: Tree): Some[(Tree, List[List[Tree]])]
- }
-
- val SyntacticClassDef: SyntacticClassDefExtractor
-
- trait SyntacticClassDefExtractor {
- def apply(mods: Modifiers, name: TypeName, tparams: List[Tree],
- constrMods: Modifiers, vparamss: List[List[Tree]],
- earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef
- def unapply(tree: Tree): Option[(Modifiers, TypeName, List[TypeDef], Modifiers, List[List[ValDef]],
- List[Tree], List[Tree], ValDef, List[Tree])]
- }
-
- val SyntacticTraitDef: SyntacticTraitDefExtractor
-
- trait SyntacticTraitDefExtractor {
- def apply(mods: Modifiers, name: TypeName, tparams: List[Tree],
- earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef
- def unapply(tree: Tree): Option[(Modifiers, TypeName, List[TypeDef],
- List[Tree], List[Tree], ValDef, List[Tree])]
- }
-
- val SyntacticObjectDef: SyntacticObjectDefExtractor
-
- trait SyntacticObjectDefExtractor {
- def apply(mods: Modifiers, name: TermName, earlyDefs: List[Tree],
- parents: List[Tree], selfType: Tree, body: List[Tree]): ModuleDef
- def unapply(tree: Tree): Option[(Modifiers, TermName, List[Tree], List[Tree], ValDef, List[Tree])]
- }
-
- val SyntacticPackageObjectDef: SyntacticPackageObjectDefExtractor
-
- trait SyntacticPackageObjectDefExtractor {
- def apply(name: TermName, earlyDefs: List[Tree],
- parents: List[Tree], selfType: Tree, body: List[Tree]): PackageDef
- def unapply(tree: Tree): Option[(TermName, List[Tree], List[Tree], ValDef, List[Tree])]
- }
-
- val SyntacticTuple: SyntacticTupleExtractor
- val SyntacticTupleType: SyntacticTupleExtractor
-
- trait SyntacticTupleExtractor {
- def apply(args: List[Tree]): Tree
- def unapply(tree: Tree): Option[List[Tree]]
- }
-
- val SyntacticBlock: SyntacticBlockExtractor
-
- trait SyntacticBlockExtractor {
- def apply(stats: List[Tree]): Tree
- def unapply(tree: Tree): Option[List[Tree]]
- }
-
- val SyntacticNew: SyntacticNewExtractor
-
- trait SyntacticNewExtractor {
- def apply(earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): Tree
- def unapply(tree: Tree): Option[(List[Tree], List[Tree], ValDef, List[Tree])]
- }
-
- val SyntacticFunctionType: SyntacticFunctionTypeExtractor
-
- trait SyntacticFunctionTypeExtractor {
- def apply(argtpes: List[Tree], restpe: Tree): Tree
- def unapply(tree: Tree): Option[(List[Tree], Tree)]
- }
-
- val SyntacticFunction: SyntacticFunctionExtractor
-
- trait SyntacticFunctionExtractor {
- def apply(params: List[Tree], body: Tree): Function
-
- def unapply(tree: Function): Option[(List[ValDef], Tree)]
- }
-
- val SyntacticDefDef: SyntacticDefDefExtractor
-
- trait SyntacticDefDefExtractor {
- def apply(mods: Modifiers, name: TermName, tparams: List[Tree],
- vparamss: List[List[Tree]], tpt: Tree, rhs: Tree): DefDef
-
- def unapply(tree: Tree): Option[(Modifiers, TermName, List[TypeDef], List[List[ValDef]], Tree, Tree)]
- }
-
- val SyntacticValDef: SyntacticValDefExtractor
- val SyntacticVarDef: SyntacticValDefExtractor
-
- trait SyntacticValDefExtractor {
- def apply(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree): ValDef
- def unapply(tree: Tree): Option[(Modifiers, TermName, Tree, Tree)]
- }
-
- val SyntacticPatDef: SyntacticPatDefExtractor
-
- trait SyntacticPatDefExtractor {
- def apply(mods: Modifiers, pat: Tree, tpt: Tree, rhs: Tree): List[ValDef]
- }
-
- val SyntacticAssign: SyntacticAssignExtractor
-
- trait SyntacticAssignExtractor {
- def apply(lhs: Tree, rhs: Tree): Tree
- def unapply(tree: Tree): Option[(Tree, Tree)]
- }
-
- val SyntacticValFrom: SyntacticValFromExtractor
-
- trait SyntacticValFromExtractor {
- def apply(pat: Tree, rhs: Tree): Tree
- def unapply(tree: Tree): Option[(Tree, Tree)]
- }
-
- val SyntacticValEq: SyntacticValEqExtractor
-
- trait SyntacticValEqExtractor {
- def apply(pat: Tree, rhs: Tree): Tree
- def unapply(tree: Tree): Option[(Tree, Tree)]
- }
-
- val SyntacticFilter: SyntacticFilterExtractor
-
- trait SyntacticFilterExtractor {
- def apply(test: Tree): Tree
- def unapply(tree: Tree): Option[(Tree)]
- }
-
- val SyntacticEmptyTypeTree: SyntacticEmptyTypeTreeExtractor
-
- trait SyntacticEmptyTypeTreeExtractor {
- def apply(): TypeTree
- def unapply(tt: TypeTree): Boolean
- }
-
- val SyntacticFor: SyntacticForExtractor
- val SyntacticForYield: SyntacticForExtractor
-
- trait SyntacticForExtractor {
- def apply(enums: List[Tree], body: Tree): Tree
- def unapply(tree: Tree): Option[(List[Tree], Tree)]
- }
-
- def UnliftListElementwise[T](unliftable: Unliftable[T]): UnliftListElementwise[T]
- trait UnliftListElementwise[T] {
- def unapply(lst: List[Tree]): Option[List[T]]
- }
-
- def UnliftListOfListsElementwise[T](unliftable: Unliftable[T]): UnliftListOfListsElementwise[T]
- trait UnliftListOfListsElementwise[T] {
- def unapply(lst: List[List[Tree]]): Option[List[List[T]]]
- }
-
- val SyntacticMatch: SyntacticMatchExtractor
- trait SyntacticMatchExtractor {
- def apply(selector: Tree, cases: List[Tree]): Match
- def unapply(tree: Match): Option[(Tree, List[CaseDef])]
- }
-
- val SyntacticTry: SyntacticTryExtractor
- trait SyntacticTryExtractor {
- def apply(block: Tree, catches: List[Tree], finalizer: Tree): Try
- def unapply(tree: Try): Option[(Tree, List[CaseDef], Tree)]
- }
-
- val SyntacticIdent: SyntacticIdentExtractor
- trait SyntacticIdentExtractor {
- def apply(name: Name, isBackquoted: Boolean = false): Ident
- def unapply(tree: Ident): Option[(Name, Boolean)]
- }
-
- val SyntacticImport: SyntacticImportExtractor
- trait SyntacticImportExtractor {
- def apply(expr: Tree, selectors: List[Tree]): Import
- def unapply(imp: Import): Some[(Tree, List[Tree])]
- }
- }
-}
diff --git a/src/reflect/scala/reflect/api/Constants.scala b/src/reflect/scala/reflect/api/Constants.scala
index c654961f4a..e73c5ffa91 100644
--- a/src/reflect/scala/reflect/api/Constants.scala
+++ b/src/reflect/scala/reflect/api/Constants.scala
@@ -69,7 +69,7 @@ package api
* val enumRef = jarg("enumRef").symbolValue
* println(enumRef) // value BAR
*
- * val siblings = enumRef.owner.typeSignature.declarations
+ * val siblings = enumRef.owner.info.decls
* val enumValues = siblings.filter(sym => sym.isVal && sym.isPublic)
* println(enumValues) // Scope{
* // final val FOO: JavaSimpleEnumeration;
@@ -165,7 +165,7 @@ trait Constants {
* // ideally one should match instead of casting
* println(enumRef) // value BAR
*
- * val siblings = enumRef.owner.typeSignature.declarations
+ * val siblings = enumRef.owner.info.decls
* val enumValues = siblings.filter(sym => sym.isVal && sym.isPublic)
* println(enumValues) // Scope{
* // final val FOO: JavaSimpleEnumeration;
diff --git a/src/reflect/scala/reflect/api/FlagSets.scala b/src/reflect/scala/reflect/api/FlagSets.scala
index 54b65166d8..bf4d6353df 100644
--- a/src/reflect/scala/reflect/api/FlagSets.scala
+++ b/src/reflect/scala/reflect/api/FlagSets.scala
@@ -131,8 +131,8 @@ trait FlagSets { self: Universe =>
/** Flag indicating that tree has `protected` modifier set */
val PROTECTED: FlagSet
- /** Flag indicating that tree represents a member local to current class
- * (i.e. private[this] or protected[this].
+ /** Flag indicating that tree represents a member local to current class,
+ * i.e. private[this] or protected[this].
* This requires having either PRIVATE or PROTECTED set as well.
*/
val LOCAL: FlagSet
@@ -167,9 +167,6 @@ trait FlagSets { self: Universe =>
/** Flag indicating that tree represents a variable or a member initialized to the default value */
val DEFAULTINIT: FlagSet
- /** Flag indicating that tree was generated by the compiler */
- val SYNTHETIC: FlagSet
-
/** Flag indicating that tree represents an enum.
*
* It can only appear at
@@ -177,6 +174,82 @@ trait FlagSets { self: Universe =>
* - enum constants
**/
val ENUM: FlagSet
+
+ /** Flag indicating that tree represents a parameter of the primary constructor of some class
+ * or a synthetic member underlying thereof. E.g. here's how 'class C(val x: Int)' is represented:
+ *
+ * [[syntax trees at end of parser]]// Scala source: tmposDU52
+ * class C extends scala.AnyRef {
+ * <paramaccessor> val x: Int = _;
+ * def <init>(x: Int) = {
+ * super.<init>();
+ * ()
+ * }
+ * }
+ * ClassDef(
+ * Modifiers(), TypeName("C"), List(),
+ * Template(
+ * List(Select(Ident(scala), TypeName("AnyRef"))),
+ * noSelfType,
+ * List(
+ * ValDef(Modifiers(PARAMACCESSOR), TermName("x"), Ident(TypeName("Int")), EmptyTree),
+ * DefDef(
+ * Modifiers(), nme.CONSTRUCTOR, List(),
+ * List(List(ValDef(Modifiers(PARAM | PARAMACCESSOR), TermName("x"), Ident(TypeName("Int")), EmptyTree))), TypeTree(),
+ * Block(List(pendingSuperCall), Literal(Constant(())))))))))
+ */
+ val PARAMACCESSOR: FlagSet
+
+ /** Flag indicating that tree represents a parameter of the primary constructor of some case class
+ * or a synthetic member underlying thereof. E.g. here's how 'case class C(val x: Int)' is represented:
+ *
+ * [[syntax trees at end of parser]]// Scala source: tmpnHkJ3y
+ * case class C extends scala.Product with scala.Serializable {
+ * <caseaccessor> <paramaccessor> val x: Int = _;
+ * def <init>(x: Int) = {
+ * super.<init>();
+ * ()
+ * }
+ * }
+ * ClassDef(
+ * Modifiers(CASE), TypeName("C"), List(),
+ * Template(
+ * List(Select(Ident(scala), TypeName("Product")), Select(Ident(scala), TypeName("Serializable"))),
+ * noSelfType,
+ * List(
+ * ValDef(Modifiers(CASEACCESSOR | PARAMACCESSOR), TermName("x"), Ident(TypeName("Int")), EmptyTree),
+ * DefDef(
+ * Modifiers(), nme.CONSTRUCTOR, List(),
+ * List(List(ValDef(Modifiers(PARAM | PARAMACCESSOR), TermName("x"), Ident(TypeName("Int")), EmptyTree))), TypeTree(),
+ * Block(List(pendingSuperCall), Literal(Constant(())))))))))
+ */
+ val CASEACCESSOR: FlagSet
+
+ /** Flag used to distinguish programmatically generated definitions from user-written ones.
+ * @see ARTIFACT
+ */
+ val SYNTHETIC: FlagSet
+
+ /** Flag used to distinguish platform-specific implementation details.
+ * Trees and symbols which are currently marked ARTIFACT by scalac:
+ * * $outer fields and accessors
+ * * super accessors
+ * * protected accessors
+ * * lazy local accessors
+ * * bridge methods
+ * * default argument getters
+ * * evaluation-order preserving locals for right-associative and out-of-order named arguments
+ * * catch-expression storing vals
+ * * anything else which feels a setFlag(ARTIFACT)
+ *
+ * @see SYNTHETIC
+ */
+ val ARTIFACT: FlagSet
+
+ /** Flag that indicates methods that are supposed to be stable
+ * (e.g. synthetic getters of valdefs).
+ */
+ val STABLE: FlagSet
}
/** The empty set of flags
diff --git a/src/reflect/scala/reflect/api/ImplicitTags.scala b/src/reflect/scala/reflect/api/ImplicitTags.scala
index 1b654a4a8d..aca0692d0d 100644
--- a/src/reflect/scala/reflect/api/ImplicitTags.scala
+++ b/src/reflect/scala/reflect/api/ImplicitTags.scala
@@ -51,8 +51,6 @@ trait ImplicitTags {
implicit val TypeSymbolTag: ClassTag[TypeSymbol]
implicit val ModuleSymbolTag: ClassTag[ModuleSymbol]
implicit val ClassSymbolTag: ClassTag[ClassSymbol]
- implicit val FreeTermSymbolTag: ClassTag[FreeTermSymbol]
- implicit val FreeTypeSymbolTag: ClassTag[FreeTypeSymbol]
// Tags for misc Tree relatives.
implicit val PositionTag: ClassTag[Position]
@@ -91,7 +89,6 @@ trait ImplicitTags {
implicit val NewTag: ClassTag[New]
implicit val PackageDefTag: ClassTag[PackageDef]
implicit val RefTreeTag: ClassTag[RefTree]
- implicit val ReferenceToBoxedTag: ClassTag[ReferenceToBoxed]
implicit val ReturnTag: ClassTag[Return]
implicit val SelectFromTypeTreeTag: ClassTag[SelectFromTypeTree]
implicit val SelectTag: ClassTag[Select]
@@ -114,4 +111,9 @@ trait ImplicitTags {
implicit val UnApplyTag: ClassTag[UnApply]
implicit val ValDefTag: ClassTag[ValDef]
implicit val ValOrDefDefTag: ClassTag[ValOrDefDef]
+
+ // Miscellaneous
+ implicit val TreeCopierTag: ClassTag[TreeCopier]
+ implicit val RuntimeClassTag: ClassTag[RuntimeClass]
+ implicit val MirrorTag: ClassTag[Mirror]
}
diff --git a/src/reflect/scala/reflect/api/Importers.scala b/src/reflect/scala/reflect/api/Importers.scala
deleted file mode 100644
index 6539137cee..0000000000
--- a/src/reflect/scala/reflect/api/Importers.scala
+++ /dev/null
@@ -1,104 +0,0 @@
-package scala
-package reflect
-package api
-
-/**
- * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
- *
- * This trait provides support for importers, a facility to migrate reflection artifacts between universes.
- * ''Note: this trait should typically be used only rarely.''
- *
- * Reflection artifacts, such as [[scala.reflect.api.Symbols Symbols]] and [[scala.reflect.api.Types Types]],
- * are contained in [[scala.reflect.api.Universe Universe]]s. Typically all processing happens
- * within a single `Universe` (e.g. a compile-time macro `Universe` or a runtime reflection `Universe`), but sometimes
- * there is a need to migrate artifacts from one `Universe` to another. For example, runtime compilation works by
- * importing runtime reflection trees into a runtime compiler universe, compiling the importees and exporting the
- * result back.
- *
- * Reflection artifacts are firmly grounded in their `Universe`s, which is reflected by the fact that types of artifacts
- * from different universes are not compatible. By using `Importer`s, however, they be imported from one universe
- * into another. For example, to import `foo.bar.Baz` from the source `Universe` to the target `Universe`,
- * an importer will first check whether the entire owner chain exists in the target `Universe`.
- * If it does, then nothing else will be done. Otherwise, the importer will recreate the entire owner chain
- * and will import the corresponding type signatures into the target `Universe`.
- *
- * Since importers match `Symbol` tables of the source and the target `Universe`s using plain string names,
- * it is programmer's responsibility to make sure that imports don't distort semantics, e.g., that
- * `foo.bar.Baz` in the source `Universe` means the same that `foo.bar.Baz` does in the target `Universe`.
- *
- * === Example ===
- *
- * Here's how one might implement a macro that performs compile-time evaluation of its argument
- * by using a runtime compiler to compile and evaluate a tree that belongs to a compile-time compiler:
- *
- * {{{
- * def staticEval[T](x: T) = macro staticEval[T]
- *
- * def staticEval[T](c: scala.reflect.macros.blackbox.Context)(x: c.Expr[T]) = {
- * // creates a runtime reflection universe to host runtime compilation
- * import scala.reflect.runtime.{universe => ru}
- * val mirror = ru.runtimeMirror(c.libraryClassLoader)
- * import scala.tools.reflect.ToolBox
- * val toolBox = mirror.mkToolBox()
- *
- * // runtime reflection universe and compile-time macro universe are different
- * // therefore an importer is needed to bridge them
- * // currently mkImporter requires a cast to correctly assign the path-dependent types
- * val importer0 = ru.mkImporter(c.universe)
- * val importer = importer0.asInstanceOf[ru.Importer { val from: c.universe.type }]
- *
- * // the created importer is used to turn a compiler tree into a runtime compiler tree
- * // both compilers use the same classpath, so semantics remains intact
- * val imported = importer.importTree(tree)
- *
- * // after the tree is imported, it can be evaluated as usual
- * val tree = toolBox.untypecheck(imported.duplicate)
- * val valueOfX = toolBox.eval(imported).asInstanceOf[T]
- * ...
- * }
- * }}}
- *
- * @group ReflectionAPI
- */
-trait Importers { self: Universe =>
-
- /** Creates an importer that moves reflection artifacts between universes.
- * @group Importers
- */
- def mkImporter(from0: Universe): Importer { val from: from0.type }
-
- /** The API of importers.
- * The main source of information about importers is the [[scala.reflect.api.Importers]] page.
- * @group Importers
- */
- trait Importer {
- /** The source universe of reflection artifacts that will be processed.
- * The target universe is universe that created this importer with `mkImporter`.
- */
- val from: Universe
-
- /** An importer that works in reverse direction, namely:
- * imports reflection artifacts from the current universe to the universe specified in `from`.
- */
- val reverse: from.Importer { val from: self.type }
-
- /** In the current universe, locates or creates a symbol that corresponds to the provided symbol in the source universe.
- * If necessary imports the owner chain, companions, type signature, annotations and attachments.
- */
- def importSymbol(sym: from.Symbol): Symbol
-
- /** In the current universe, locates or creates a type that corresponds to the provided type in the source universe.
- * If necessary imports the underlying symbols, annotations, scopes and trees.
- */
- def importType(tpe: from.Type): Type
-
- /** In the current universe, creates a tree that corresponds to the provided tree in the source universe.
- * If necessary imports the underlying symbols, types and attachments.
- */
- def importTree(tree: from.Tree): Tree
-
- /** In the current universe, creates a position that corresponds to the provided position in the source universe.
- */
- def importPosition(pos: from.Position): Position
- }
-}
diff --git a/src/reflect/scala/reflect/api/Internals.scala b/src/reflect/scala/reflect/api/Internals.scala
new file mode 100644
index 0000000000..01700345d1
--- /dev/null
+++ b/src/reflect/scala/reflect/api/Internals.scala
@@ -0,0 +1,1183 @@
+package scala
+package reflect
+package api
+
+import scala.language.implicitConversions
+import scala.language.higherKinds
+
+/**
+ * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
+ *
+ * This trait assembles APIs occasionally necessary for performing low-level operations on reflection artifacts.
+ * See [[Internals#InternalApi]] for more information about nature, usefulness and compatibility guarantees of these APIs.
+ *
+ * @group ReflectionAPI
+ */
+trait Internals { self: Universe =>
+
+ /** @see [[InternalApi]]
+ * @group Internal
+ */
+ val internal: Internal
+
+ /** @see [[InternalApi]]
+ * @group Internal
+ */
+ type Internal <: InternalApi
+
+ /** Reflection API exhibits a tension inherent to experimental things:
+ * on the one hand we want it to grow into a beautiful and robust API,
+ * but on the other hand we have to deal with immaturity of underlying mechanisms
+ * by providing not very pretty solutions to enable important use cases.
+ *
+ * In Scala 2.10, which was our first stab at reflection API, we didn't have a systematic
+ * approach to dealing with this tension, sometimes exposing too much of internals (e.g. Symbol.deSkolemize)
+ * and sometimes exposing too little (e.g. there's still no facility to change owners, to do typing
+ * transformations, etc). This resulted in certain confusion with some internal APIs
+ * living among public ones, scaring the newcomers, and some internal APIs only available via casting,
+ * which requires intimate knowledge of the compiler and breaks compatibility guarantees.
+ *
+ * This led to creation of the `internal` API module for the reflection API, which
+ * provides advanced APIs necessary for macros that push boundaries of the state of the art,
+ * clearly demarcating them from the more or less straightforward rest and
+ * providing compatibility guarantees on par with the rest of the reflection API
+ * (full compatibility within minor releases, best effort towards backward compatibility within major releases,
+ * clear replacement path in case of rare incompatible changes in major releases).
+ *
+ * The `internal` module itself (the value that implements [[InternalApi]]) isn't defined here,
+ * in [[scala.reflect.api.Universe]], but is provided on per-implementation basis. Runtime API endpoint
+ * ([[scala.reflect.runtime.universe]]) provides `universe.compat: InternalApi`, whereas compile-time API endpoints
+ * (instances of [[scala.reflect.macros.Context]]) provide `c.compat: ContextInternalApi`, which extends `InternalApi`
+ * with additional universe-specific and context-specific functionality.
+ *
+ * @group Internal
+ */
+ trait InternalApi { internal =>
+ /** This is an internal implementation module.
+ */
+ val reificationSupport: ReificationSupportApi
+
+ /** Creates an importer that moves reflection artifacts between universes.
+ * @see [[Importer]]
+ */
+ // SI-6241: move importers to a mirror
+ def createImporter(from0: Universe): Importer { val from: from0.type }
+
+ /**
+ * Convert a [[scala.reflect.api.TypeTags#TypeTag]] to a [[scala.reflect.Manifest]].
+ *
+ * Compiler usually generates these conversions automatically, when a type tag for a type `T` is in scope,
+ * and an implicit of type `Manifest[T]` is requested, but this method can also be called manually.
+ * For example:
+ * {{{
+ * typeTagToManifest(scala.reflect.runtime.currentMirror, implicitly[TypeTag[String]])
+ * }}}
+ * @group TagInterop
+ */
+ def typeTagToManifest[T: ClassTag](mirror: Any, tag: Universe#TypeTag[T]): Manifest[T] =
+ throw new UnsupportedOperationException("This universe does not support tag -> manifest conversions. Use a JavaUniverse, e.g. the scala.reflect.runtime.universe.")
+
+ /**
+ * Convert a [[scala.reflect.Manifest]] to a [[scala.reflect.api.TypeTags#TypeTag]].
+ *
+ * Compiler usually generates these conversions automatically, when a manifest for a type `T` is in scope,
+ * and an implicit of type `TypeTag[T]` is requested, but this method can also be called manually.
+ * For example:
+ * {{{
+ * manifestToTypeTag(scala.reflect.runtime.currentMirror, implicitly[Manifest[String]])
+ * }}}
+ * @group TagInterop
+ */
+ def manifestToTypeTag[T](mirror: Any, manifest: Manifest[T]): Universe#TypeTag[T] =
+ throw new UnsupportedOperationException("This universe does not support manifest -> tag conversions. Use a JavaUniverse, e.g. the scala.reflect.runtime.universe.")
+
+ /** Create a new scope with the given initial elements.
+ */
+ def newScopeWith(elems: Symbol*): Scope
+
+ /** Extracts free term symbols from a tree that is reified or contains reified subtrees.
+ */
+ def freeTerms(tree: Tree): List[FreeTermSymbol]
+
+ /** Extracts free type symbols from a tree that is reified or contains reified subtrees.
+ */
+ def freeTypes(tree: Tree): List[FreeTypeSymbol]
+
+ /** Substitute symbols in `to` for corresponding occurrences of references to
+ * symbols `from` in this type.
+ */
+ def substituteSymbols(tree: Tree, from: List[Symbol], to: List[Symbol]): Tree
+
+ /** Substitute types in `to` for corresponding occurrences of references to
+ * symbols `from` in this tree.
+ */
+ def substituteTypes(tree: Tree, from: List[Symbol], to: List[Type]): Tree
+
+ /** Substitute given tree `to` for occurrences of nodes that represent
+ * `C.this`, where `C` referes to the given class `clazz`.
+ */
+ def substituteThis(tree: Tree, clazz: Symbol, to: Tree): Tree
+
+ /** A factory method for `ClassDef` nodes.
+ */
+ def classDef(sym: Symbol, impl: Template): ClassDef
+
+ /** A factory method for `ModuleDef` nodes.
+ */
+ def moduleDef(sym: Symbol, impl: Template): ModuleDef
+
+ /** A factory method for `ValDef` nodes.
+ */
+ def valDef(sym: Symbol, rhs: Tree): ValDef
+
+ /** A factory method for `ValDef` nodes.
+ */
+ def valDef(sym: Symbol): ValDef
+
+ /** A factory method for `DefDef` nodes.
+ */
+ def defDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef
+
+ /** A factory method for `DefDef` nodes.
+ */
+ def defDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef
+
+ /** A factory method for `DefDef` nodes.
+ */
+ def defDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef
+
+ /** A factory method for `DefDef` nodes.
+ */
+ def defDef(sym: Symbol, rhs: Tree): DefDef
+
+ /** A factory method for `DefDef` nodes.
+ */
+ def defDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef
+
+ /** A factory method for `TypeDef` nodes.
+ */
+ def typeDef(sym: Symbol, rhs: Tree): TypeDef
+
+ /** A factory method for `TypeDef` nodes.
+ */
+ def typeDef(sym: Symbol): TypeDef
+
+ /** A factory method for `LabelDef` nodes.
+ */
+ def labelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef
+
+ /** Does this symbol represent a free term captured by reification?
+ * If yes, `isTerm` is also guaranteed to be true.
+ */
+ def isFreeTerm(symbol: Symbol): Boolean
+
+ /** This symbol cast to a free term symbol.
+ * @throws ScalaReflectionException if `isFreeTerm` is false.
+ */
+ def asFreeTerm(symbol: Symbol): FreeTermSymbol
+
+ /** Does this symbol represent a free type captured by reification?
+ * If yes, `isType` is also guaranteed to be true.
+ */
+ def isFreeType(symbol: Symbol): Boolean
+
+ /** This symbol cast to a free type symbol.
+ * @throws ScalaReflectionException if `isFreeType` is false.
+ */
+ def asFreeType(symbol: Symbol): FreeTypeSymbol
+
+ def newTermSymbol(owner: Symbol, name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TermSymbol
+
+ def newModuleAndClassSymbol(owner: Symbol, name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol)
+
+ def newMethodSymbol(owner: Symbol, name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): MethodSymbol
+
+ def newTypeSymbol(owner: Symbol, name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TypeSymbol
+
+ def newClassSymbol(owner: Symbol, name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): ClassSymbol
+
+ def newFreeTerm(name: String, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTermSymbol
+
+ def newFreeType(name: String, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol
+
+ /** Does this symbol or its underlying type represent a typechecking error?
+ */
+ def isErroneous(symbol: Symbol): Boolean
+
+ /** Does this symbol represent the definition of a skolem?
+ * Skolems are used during typechecking to represent type parameters viewed from inside their scopes.
+ */
+ def isSkolem(symbol: Symbol): Boolean
+
+ /** If this symbol is a skolem, its corresponding type parameter, otherwise the symbol itself.
+ *
+ * [[https://groups.google.com/forum/#!msg/scala-internals/0j8laVNTQsI/kRXMF_c8bGsJ To quote Martin Odersky]],
+ * skolems are synthetic type "constants" that are copies of existentially bound or universally
+ * bound type variables. E.g. if one is inside the right-hand side of a method:
+ *
+ * {{{
+ * def foo[T](x: T) = ... foo[List[T]]....
+ * }}}
+ *
+ * the skolem named `T` refers to the unknown type instance of `T` when `foo` is called. It needs to be different
+ * from the type parameter because in a recursive call as in the `foo[List[T]]` above the type parameter gets
+ * substituted with `List[T]`, but the ''type skolem'' stays what it is.
+ *
+ * The other form of skolem is an ''existential skolem''. Say one has a function
+ *
+ * {{{
+ * def bar(xs: List[T] forSome { type T }) = xs.head
+ * }}}
+ *
+ * then each occurrence of `xs` on the right will have type `List[T']` where `T'` is a fresh copy of `T`.
+ */
+ def deSkolemize(symbol: Symbol): Symbol
+
+ /** Forces all outstanding completers associated with this symbol.
+ * After this call returns, the symbol becomes immutable and thread-safe.
+ */
+ def initialize(symbol: Symbol): symbol.type
+
+ /** Calls [[initialize]] on the owner and all the value and type parameters of the symbol.
+ */
+ def fullyInitialize(symbol: Symbol): symbol.type
+
+ /** Calls [[initialize]] on all the value and type parameters of the type.
+ */
+ def fullyInitialize(tp: Type): tp.type
+
+ /** Calls [[initialize]] on all the symbols that the scope consists of.
+ */
+ def fullyInitialize(scope: Scope): scope.type
+
+ /** Returns internal flags associated with the symbol.
+ */
+ def flags(symbol: Symbol): FlagSet
+
+ /** A creator for `ThisType` types.
+ */
+ def thisType(sym: Symbol): Type
+
+ /** A creator for `SingleType` types.
+ */
+ def singleType(pre: Type, sym: Symbol): Type
+
+ /** A creator for `SuperType` types.
+ */
+ def superType(thistpe: Type, supertpe: Type): Type
+
+ /** A creator for `ConstantType` types.
+ */
+ def constantType(value: Constant): ConstantType
+
+ /** A creator for `TypeRef` types.
+ */
+ def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type
+
+ /** A creator for `RefinedType` types.
+ */
+ def refinedType(parents: List[Type], decls: Scope): RefinedType
+
+ /** A creator for `RefinedType` types.
+ */
+ def refinedType(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType
+
+ /** A creator for `RefinedType` types.
+ */
+ def refinedType(parents: List[Type], owner: Symbol): Type
+
+ /** A creator for `RefinedType` types.
+ */
+ def refinedType(parents: List[Type], owner: Symbol, decls: Scope): Type
+
+ /** A creator for `RefinedType` types.
+ */
+ def refinedType(parents: List[Type], owner: Symbol, decls: Scope, pos: Position): Type
+
+ /** A creator for intersection type where intersections of a single type are
+ * replaced by the type itself.
+ */
+ def intersectionType(tps: List[Type]): Type
+
+ /** A creator for intersection type where intersections of a single type are
+ * replaced by the type itself, and repeated parent classes are merged.
+ *
+ * !!! Repeated parent classes are not merged - is this a bug in the
+ * comment or in the code?
+ */
+ def intersectionType(tps: List[Type], owner: Symbol): Type
+
+ /** A creator for `ClassInfoType` types.
+ */
+ def classInfoType(parents: List[Type], decls: Scope, typeSymbol: Symbol): ClassInfoType
+
+ /** A creator for `MethodType` types.
+ */
+ def methodType(params: List[Symbol], resultType: Type): MethodType
+
+ /** A creator for `NullaryMethodType` types.
+ */
+ def nullaryMethodType(resultType: Type): NullaryMethodType
+
+ /** A creator for type parameterizations that strips empty type parameter lists.
+ * Use this factory method to indicate the type has kind * (it's a polymorphic value)
+ * until we start tracking explicit kinds equivalent to typeFun (except that the latter requires tparams nonEmpty).
+ */
+ def polyType(tparams: List[Symbol], tpe: Type): PolyType
+
+ /** A creator for `ExistentialType` types.
+ */
+ def existentialType(quantified: List[Symbol], underlying: Type): ExistentialType
+
+ /** A creator for existential types. This generates:
+ *
+ * {{{
+ * tpe1 where { tparams }
+ * }}}
+ *
+ * where `tpe1` is the result of extrapolating `tpe` with regard to `tparams`.
+ * Extrapolating means that type variables in `tparams` occurring
+ * in covariant positions are replaced by upper bounds, (minus any
+ * SingletonClass markers), type variables in `tparams` occurring in
+ * contravariant positions are replaced by upper bounds, provided the
+ * resulting type is legal with regard to stability, and does not contain
+ * any type variable in `tparams`.
+ *
+ * The abstraction drops all type parameters that are not directly or
+ * indirectly referenced by type `tpe1`. If there are no remaining type
+ * parameters, simply returns result type `tpe`.
+ * @group TypeCreators
+ */
+ def existentialAbstraction(tparams: List[Symbol], tpe0: Type): Type
+
+ /** A creator for `AnnotatedType` types.
+ */
+ def annotatedType(annotations: List[Annotation], underlying: Type): AnnotatedType
+
+ /** A creator for `TypeBounds` types.
+ */
+ def typeBounds(lo: Type, hi: Type): TypeBounds
+
+ /** A creator for `BoundedWildcardType` types.
+ */
+ def boundedWildcardType(bounds: TypeBounds): BoundedWildcardType
+
+ /** Syntactic conveniences for additional internal APIs for trees, symbols and types */
+ type Decorators <: DecoratorApi
+
+ /** @see [[Decorators]] */
+ val decorators: Decorators
+
+ /** @see [[Decorators]] */
+ trait DecoratorApi {
+ /** Extension methods for trees */
+ type TreeDecorator[T <: Tree] <: TreeDecoratorApi[T]
+
+ /** @see [[TreeDecorator]] */
+ implicit def treeDecorator[T <: Tree](tree: T): TreeDecorator[T]
+
+ /** @see [[TreeDecorator]] */
+ class TreeDecoratorApi[T <: Tree](val tree: T) {
+ /** @see [[internal.freeTerms]] */
+ def freeTerms: List[FreeTermSymbol] = internal.freeTerms(tree)
+
+ /** @see [[internal.freeTypes]] */
+ def freeTypes: List[FreeTypeSymbol] = internal.freeTypes(tree)
+
+ /** @see [[internal.substituteSymbols]] */
+ def substituteSymbols(from: List[Symbol], to: List[Symbol]): Tree = internal.substituteSymbols(tree, from, to)
+
+ /** @see [[internal.substituteTypes]] */
+ def substituteTypes(from: List[Symbol], to: List[Type]): Tree = internal.substituteTypes(tree, from, to)
+
+ /** @see [[internal.substituteThis]] */
+ def substituteThis(clazz: Symbol, to: Tree): Tree = internal.substituteThis(tree, clazz, to)
+ }
+
+ /** Extension methods for symbols */
+ type SymbolDecorator[T <: Symbol] <: SymbolDecoratorApi[T]
+
+ /** @see [[SymbolDecorator]] */
+ implicit def symbolDecorator[T <: Symbol](symbol: T): SymbolDecorator[T]
+
+ /** @see [[SymbolDecorator]] */
+ class SymbolDecoratorApi[T <: Symbol](val symbol: T) {
+ /** @see [[internal.isFreeTerm]] */
+ def isFreeTerm: Boolean = internal.isFreeTerm(symbol)
+
+ /** @see [[internal.asFreeTerm]] */
+ def asFreeTerm: FreeTermSymbol = internal.asFreeTerm(symbol)
+
+ /** @see [[internal.isFreeType]] */
+ def isFreeType: Boolean = internal.isFreeType(symbol)
+
+ /** @see [[internal.asFreeType]] */
+ def asFreeType: FreeTypeSymbol = internal.asFreeType(symbol)
+
+ /** @see [[internal.newTermSymbol]] */
+ def newTermSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TermSymbol = internal.newTermSymbol(symbol, name, pos, flags)
+
+ /** @see [[internal.newModuleAndClassSymbol]] */
+ def newModuleAndClassSymbol(name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol) = internal.newModuleAndClassSymbol(symbol, name, pos, flags)
+
+ /** @see [[internal.newMethodSymbol]] */
+ def newMethodSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): MethodSymbol = internal.newMethodSymbol(symbol, name, pos, flags)
+
+ /** @see [[internal.newTypeSymbol]] */
+ def newTypeSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TypeSymbol = internal.newTypeSymbol(symbol, name, pos, flags)
+
+ /** @see [[internal.newClassSymbol]] */
+ def newClassSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): ClassSymbol = internal.newClassSymbol(symbol, name, pos, flags)
+
+ /** @see [[internal.isErroneous]] */
+ def isErroneous: Boolean = internal.isErroneous(symbol)
+
+ /** @see [[internal.isSkolem]] */
+ def isSkolem: Boolean = internal.isSkolem(symbol)
+
+ /** @see [[internal.deSkolemize]] */
+ def deSkolemize: Symbol = internal.deSkolemize(symbol)
+
+ /** @see [[internal.initialize]] */
+ def initialize: T = internal.initialize(symbol)
+
+ /** @see [[internal.fullyInitialize]] */
+ def fullyInitialize: T = internal.fullyInitialize(symbol)
+
+ /** @see [[internal.flags]] */
+ def flags: FlagSet = internal.flags(symbol)
+ }
+
+ /** Extension methods for types */
+ type TypeDecorator[T <: Type] <: TypeDecoratorApi[T]
+
+ /** @see [[TypeDecorator]] */
+ implicit def typeDecorator[T <: Type](tp: T): TypeDecorator[T]
+
+ /** @see [[TypeDecorator]] */
+ implicit class TypeDecoratorApi[T <: Type](val tp: T) {
+ /** @see [[internal.fullyInitialize]] */
+ def fullyInitialize: T = internal.fullyInitialize(tp)
+ }
+ }
+ }
+
+ /** This is an internal implementation class.
+ * @group Internal
+ */
+ // this API abstracts away the functionality necessary for reification and quasiquotes
+ // it's too gimmicky and unstructured to be exposed directly in the universe
+ // but we need it in a publicly available place for reification to work
+ trait ReificationSupportApi {
+ /** Selects type symbol with given simple name `name` from the defined members of `owner`.
+ */
+ def selectType(owner: Symbol, name: String): TypeSymbol
+
+ /** Selects term symbol with given name and type from the defined members of prefix type
+ */
+ def selectTerm(owner: Symbol, name: String): TermSymbol
+
+ /** Selects overloaded method symbol with given name and index
+ */
+ def selectOverloadedMethod(owner: Symbol, name: String, index: Int): MethodSymbol
+
+ /** A fresh symbol with given name `name`, position `pos` and flags `flags` that has
+ * the current symbol as its owner.
+ */
+ def newNestedSymbol(owner: Symbol, name: Name, pos: Position, flags: FlagSet, isClass: Boolean): Symbol
+
+ def newScopeWith(elems: Symbol*): Scope
+
+ /** Create a fresh free term symbol.
+ * @param name the name of the free variable
+ * @param value the value of the free variable at runtime
+ * @param flags (optional) flags of the free variable
+ * @param origin debug information that tells where this symbol comes from
+ */
+ def newFreeTerm(name: String, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTermSymbol
+
+ /** Create a fresh free type symbol.
+ * @param name the name of the free variable
+ * @param flags (optional) flags of the free variable
+ * @param origin debug information that tells where this symbol comes from
+ */
+ def newFreeType(name: String, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol
+
+ /** Set symbol's type signature to given type.
+ * @return the symbol itself
+ */
+ def setInfo[S <: Symbol](sym: S, tpe: Type): S
+
+ /** Set symbol's annotations to given annotations `annots`.
+ */
+ def setAnnotations[S <: Symbol](sym: S, annots: List[Annotation]): S
+
+ def mkThis(sym: Symbol): Tree
+
+ def mkSelect(qualifier: Tree, sym: Symbol): Select
+
+ def mkIdent(sym: Symbol): Ident
+
+ def mkTypeTree(tp: Type): TypeTree
+
+ def ThisType(sym: Symbol): Type
+
+ def SingleType(pre: Type, sym: Symbol): Type
+
+ def SuperType(thistpe: Type, supertpe: Type): Type
+
+ def ConstantType(value: Constant): ConstantType
+
+ def TypeRef(pre: Type, sym: Symbol, args: List[Type]): Type
+
+ def RefinedType(parents: List[Type], decls: Scope, typeSymbol: Symbol): RefinedType
+
+ def ClassInfoType(parents: List[Type], decls: Scope, typeSymbol: Symbol): ClassInfoType
+
+ def MethodType(params: List[Symbol], resultType: Type): MethodType
+
+ def NullaryMethodType(resultType: Type): NullaryMethodType
+
+ def PolyType(typeParams: List[Symbol], resultType: Type): PolyType
+
+ def ExistentialType(quantified: List[Symbol], underlying: Type): ExistentialType
+
+ def AnnotatedType(annotations: List[Annotation], underlying: Type): AnnotatedType
+
+ def TypeBounds(lo: Type, hi: Type): TypeBounds
+
+ def BoundedWildcardType(bounds: TypeBounds): BoundedWildcardType
+
+ def thisPrefix(sym: Symbol): Type
+
+ def setType[T <: Tree](tree: T, tpe: Type): T
+
+ def setSymbol[T <: Tree](tree: T, sym: Symbol): T
+
+ def toStats(tree: Tree): List[Tree]
+
+ def mkAnnotation(tree: Tree): Tree
+
+ def mkAnnotation(trees: List[Tree]): List[Tree]
+
+ def mkRefineStat(stat: Tree): Tree
+
+ def mkRefineStat(stats: List[Tree]): List[Tree]
+
+ def mkPackageStat(stat: Tree): Tree
+
+ def mkPackageStat(stats: List[Tree]): List[Tree]
+
+ def mkEarlyDef(defn: Tree): Tree
+
+ def mkEarlyDef(defns: List[Tree]): List[Tree]
+
+ def mkRefTree(qual: Tree, sym: Symbol): Tree
+
+ def freshTermName(prefix: String): TermName
+
+ def freshTypeName(prefix: String): TypeName
+
+ val ImplicitParams: ImplicitParamsExtractor
+
+ trait ImplicitParamsExtractor {
+ def apply(paramss: List[List[ValDef]], implparams: List[ValDef]): List[List[ValDef]]
+ def unapply(vparamss: List[List[ValDef]]): Some[(List[List[ValDef]], List[ValDef])]
+ }
+
+ val ScalaDot: ScalaDotExtractor
+
+ trait ScalaDotExtractor {
+ def apply(name: Name): Tree
+ def unapply(tree: Tree): Option[Name]
+ }
+
+ val FlagsRepr: FlagsReprExtractor
+
+ trait FlagsReprExtractor {
+ def apply(value: Long): FlagSet
+ def unapply(flags: Long): Some[Long]
+ }
+
+ val SyntacticTypeApplied: SyntacticTypeAppliedExtractor
+
+ trait SyntacticTypeAppliedExtractor {
+ def apply(tree: Tree, targs: List[Tree]): Tree
+ def unapply(tree: Tree): Some[(Tree, List[Tree])]
+ }
+
+ val SyntacticApplied: SyntacticAppliedExtractor
+
+ trait SyntacticAppliedExtractor {
+ def apply(tree: Tree, argss: List[List[Tree]]): Tree
+ def unapply(tree: Tree): Some[(Tree, List[List[Tree]])]
+ }
+
+ val SyntacticClassDef: SyntacticClassDefExtractor
+
+ trait SyntacticClassDefExtractor {
+ def apply(mods: Modifiers, name: TypeName, tparams: List[Tree],
+ constrMods: Modifiers, vparamss: List[List[Tree]],
+ earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef
+ def unapply(tree: Tree): Option[(Modifiers, TypeName, List[TypeDef], Modifiers, List[List[ValDef]],
+ List[Tree], List[Tree], ValDef, List[Tree])]
+ }
+
+ val SyntacticTraitDef: SyntacticTraitDefExtractor
+
+ trait SyntacticTraitDefExtractor {
+ def apply(mods: Modifiers, name: TypeName, tparams: List[Tree],
+ earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef
+ def unapply(tree: Tree): Option[(Modifiers, TypeName, List[TypeDef],
+ List[Tree], List[Tree], ValDef, List[Tree])]
+ }
+
+ val SyntacticObjectDef: SyntacticObjectDefExtractor
+
+ trait SyntacticObjectDefExtractor {
+ def apply(mods: Modifiers, name: TermName, earlyDefs: List[Tree],
+ parents: List[Tree], selfType: Tree, body: List[Tree]): ModuleDef
+ def unapply(tree: Tree): Option[(Modifiers, TermName, List[Tree], List[Tree], ValDef, List[Tree])]
+ }
+
+ val SyntacticPackageObjectDef: SyntacticPackageObjectDefExtractor
+
+ trait SyntacticPackageObjectDefExtractor {
+ def apply(name: TermName, earlyDefs: List[Tree],
+ parents: List[Tree], selfType: Tree, body: List[Tree]): PackageDef
+ def unapply(tree: Tree): Option[(TermName, List[Tree], List[Tree], ValDef, List[Tree])]
+ }
+
+ val SyntacticTuple: SyntacticTupleExtractor
+ val SyntacticTupleType: SyntacticTupleExtractor
+
+ trait SyntacticTupleExtractor {
+ def apply(args: List[Tree]): Tree
+ def unapply(tree: Tree): Option[List[Tree]]
+ }
+
+ val SyntacticBlock: SyntacticBlockExtractor
+
+ trait SyntacticBlockExtractor {
+ def apply(stats: List[Tree]): Tree
+ def unapply(tree: Tree): Option[List[Tree]]
+ }
+
+ val SyntacticNew: SyntacticNewExtractor
+
+ trait SyntacticNewExtractor {
+ def apply(earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): Tree
+ def unapply(tree: Tree): Option[(List[Tree], List[Tree], ValDef, List[Tree])]
+ }
+
+ val SyntacticFunctionType: SyntacticFunctionTypeExtractor
+
+ trait SyntacticFunctionTypeExtractor {
+ def apply(argtpes: List[Tree], restpe: Tree): Tree
+ def unapply(tree: Tree): Option[(List[Tree], Tree)]
+ }
+
+ val SyntacticFunction: SyntacticFunctionExtractor
+
+ trait SyntacticFunctionExtractor {
+ def apply(params: List[Tree], body: Tree): Function
+
+ def unapply(tree: Function): Option[(List[ValDef], Tree)]
+ }
+
+ val SyntacticDefDef: SyntacticDefDefExtractor
+
+ trait SyntacticDefDefExtractor {
+ def apply(mods: Modifiers, name: TermName, tparams: List[Tree],
+ vparamss: List[List[Tree]], tpt: Tree, rhs: Tree): DefDef
+
+ def unapply(tree: Tree): Option[(Modifiers, TermName, List[TypeDef], List[List[ValDef]], Tree, Tree)]
+ }
+
+ val SyntacticValDef: SyntacticValDefExtractor
+ val SyntacticVarDef: SyntacticValDefExtractor
+
+ trait SyntacticValDefExtractor {
+ def apply(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree): ValDef
+ def unapply(tree: Tree): Option[(Modifiers, TermName, Tree, Tree)]
+ }
+
+ val SyntacticPatDef: SyntacticPatDefExtractor
+
+ trait SyntacticPatDefExtractor {
+ def apply(mods: Modifiers, pat: Tree, tpt: Tree, rhs: Tree): List[ValDef]
+ }
+
+ val SyntacticAssign: SyntacticAssignExtractor
+
+ trait SyntacticAssignExtractor {
+ def apply(lhs: Tree, rhs: Tree): Tree
+ def unapply(tree: Tree): Option[(Tree, Tree)]
+ }
+
+ val SyntacticValFrom: SyntacticValFromExtractor
+
+ trait SyntacticValFromExtractor {
+ def apply(pat: Tree, rhs: Tree): Tree
+ def unapply(tree: Tree): Option[(Tree, Tree)]
+ }
+
+ val SyntacticValEq: SyntacticValEqExtractor
+
+ trait SyntacticValEqExtractor {
+ def apply(pat: Tree, rhs: Tree): Tree
+ def unapply(tree: Tree): Option[(Tree, Tree)]
+ }
+
+ val SyntacticFilter: SyntacticFilterExtractor
+
+ trait SyntacticFilterExtractor {
+ def apply(test: Tree): Tree
+ def unapply(tree: Tree): Option[(Tree)]
+ }
+
+ val SyntacticEmptyTypeTree: SyntacticEmptyTypeTreeExtractor
+
+ trait SyntacticEmptyTypeTreeExtractor {
+ def apply(): TypeTree
+ def unapply(tt: TypeTree): Boolean
+ }
+
+ val SyntacticFor: SyntacticForExtractor
+ val SyntacticForYield: SyntacticForExtractor
+
+ trait SyntacticForExtractor {
+ def apply(enums: List[Tree], body: Tree): Tree
+ def unapply(tree: Tree): Option[(List[Tree], Tree)]
+ }
+
+ def UnliftListElementwise[T](unliftable: Unliftable[T]): UnliftListElementwise[T]
+ trait UnliftListElementwise[T] {
+ def unapply(lst: List[Tree]): Option[List[T]]
+ }
+
+ def UnliftListOfListsElementwise[T](unliftable: Unliftable[T]): UnliftListOfListsElementwise[T]
+ trait UnliftListOfListsElementwise[T] {
+ def unapply(lst: List[List[Tree]]): Option[List[List[T]]]
+ }
+
+ val SyntacticMatch: SyntacticMatchExtractor
+ trait SyntacticMatchExtractor {
+ def apply(selector: Tree, cases: List[Tree]): Match
+ def unapply(tree: Match): Option[(Tree, List[CaseDef])]
+ }
+
+ val SyntacticTry: SyntacticTryExtractor
+ trait SyntacticTryExtractor {
+ def apply(block: Tree, catches: List[Tree], finalizer: Tree): Try
+ def unapply(tree: Try): Option[(Tree, List[CaseDef], Tree)]
+ }
+
+ val SyntacticIdent: SyntacticIdentExtractor
+ trait SyntacticIdentExtractor {
+ def apply(name: Name, isBackquoted: Boolean = false): Ident
+ def unapply(tree: Ident): Option[(Name, Boolean)]
+ }
+
+ val SyntacticImport: SyntacticImportExtractor
+ trait SyntacticImportExtractor {
+ def apply(expr: Tree, selectors: List[Tree]): Import
+ def unapply(imp: Import): Some[(Tree, List[Tree])]
+ }
+ }
+
+ @deprecated("Use `internal.reificationSupport` instead", "2.11.0")
+ val build: ReificationSupportApi
+
+ @deprecated("Use `internal.ReificationSupportApi` instead", "2.11.0")
+ type BuildApi = ReificationSupportApi
+
+ /** This trait provides support for importers, a facility to migrate reflection artifacts between universes.
+ * ''Note: this trait should typically be used only rarely.''
+ *
+ * Reflection artifacts, such as [[scala.reflect.api.Symbols Symbols]] and [[scala.reflect.api.Types Types]],
+ * are contained in [[scala.reflect.api.Universe Universe]]s. Typically all processing happens
+ * within a single `Universe` (e.g. a compile-time macro `Universe` or a runtime reflection `Universe`), but sometimes
+ * there is a need to migrate artifacts from one `Universe` to another. For example, runtime compilation works by
+ * importing runtime reflection trees into a runtime compiler universe, compiling the importees and exporting the
+ * result back.
+ *
+ * Reflection artifacts are firmly grounded in their `Universe`s, which is reflected by the fact that types of artifacts
+ * from different universes are not compatible. By using `Importer`s, however, they be imported from one universe
+ * into another. For example, to import `foo.bar.Baz` from the source `Universe` to the target `Universe`,
+ * an importer will first check whether the entire owner chain exists in the target `Universe`.
+ * If it does, then nothing else will be done. Otherwise, the importer will recreate the entire owner chain
+ * and will import the corresponding type signatures into the target `Universe`.
+ *
+ * Since importers match `Symbol` tables of the source and the target `Universe`s using plain string names,
+ * it is programmer's responsibility to make sure that imports don't distort semantics, e.g., that
+ * `foo.bar.Baz` in the source `Universe` means the same that `foo.bar.Baz` does in the target `Universe`.
+ *
+ * === Example ===
+ *
+ * Here's how one might implement a macro that performs compile-time evaluation of its argument
+ * by using a runtime compiler to compile and evaluate a tree that belongs to a compile-time compiler:
+ *
+ * {{{
+ * def staticEval[T](x: T) = macro staticEval[T]
+ *
+ * def staticEval[T](c: scala.reflect.macros.blackbox.Context)(x: c.Expr[T]) = {
+ * // creates a runtime reflection universe to host runtime compilation
+ * import scala.reflect.runtime.{universe => ru}
+ * val mirror = ru.runtimeMirror(c.libraryClassLoader)
+ * import scala.tools.reflect.ToolBox
+ * val toolBox = mirror.mkToolBox()
+ *
+ * // runtime reflection universe and compile-time macro universe are different
+ * // therefore an importer is needed to bridge them
+ * // currently mkImporter requires a cast to correctly assign the path-dependent types
+ * val importer0 = ru.internal.mkImporter(c.universe)
+ * val importer = importer0.asInstanceOf[ru.internal.Importer { val from: c.universe.type }]
+ *
+ * // the created importer is used to turn a compiler tree into a runtime compiler tree
+ * // both compilers use the same classpath, so semantics remains intact
+ * val imported = importer.importTree(tree)
+ *
+ * // after the tree is imported, it can be evaluated as usual
+ * val tree = toolBox.untypecheck(imported.duplicate)
+ * val valueOfX = toolBox.eval(imported).asInstanceOf[T]
+ * ...
+ * }
+ * }}}
+ *
+ * @group Internal
+ */
+ // SI-6241: move importers to a mirror
+ trait Importer {
+ /** The source universe of reflection artifacts that will be processed.
+ * The target universe is universe that created this importer with `mkImporter`.
+ */
+ val from: Universe
+
+ /** An importer that works in reverse direction, namely:
+ * imports reflection artifacts from the current universe to the universe specified in `from`.
+ */
+ val reverse: from.Importer { val from: self.type }
+
+ /** In the current universe, locates or creates a symbol that corresponds to the provided symbol in the source universe.
+ * If necessary imports the owner chain, companions, type signature, annotations and attachments.
+ */
+ def importSymbol(sym: from.Symbol): Symbol
+
+ /** In the current universe, locates or creates a type that corresponds to the provided type in the source universe.
+ * If necessary imports the underlying symbols, annotations, scopes and trees.
+ */
+ def importType(tpe: from.Type): Type
+
+ /** In the current universe, creates a tree that corresponds to the provided tree in the source universe.
+ * If necessary imports the underlying symbols, types and attachments.
+ */
+ def importTree(tree: from.Tree): Tree
+
+ /** In the current universe, creates a position that corresponds to the provided position in the source universe.
+ */
+ def importPosition(pos: from.Position): Position
+ }
+
+ @deprecated("Use `internal.createImporter` instead", "2.11.0")
+ def mkImporter(from0: Universe): Importer { val from: from0.type } = internal.createImporter(from0)
+
+ /** Marks underlying reference to id as boxed.
+ *
+ * <b>Precondition:<\b> id must refer to a captured variable
+ * A reference such marked will refer to the boxed entity, no dereferencing
+ * with `.elem` is done on it.
+ * This tree node can be emitted by macros such as reify that call referenceCapturedVariable.
+ * It is eliminated in LambdaLift, where the boxing conversion takes place.
+ * @group Internal
+ * @template
+ */
+ type ReferenceToBoxed >: Null <: ReferenceToBoxedApi with TermTree
+
+ /** The constructor/extractor for `ReferenceToBoxed` instances.
+ * @group Internal
+ */
+ val ReferenceToBoxed: ReferenceToBoxedExtractor
+
+ /** An extractor class to create and pattern match with syntax `ReferenceToBoxed(ident)`.
+ * This AST node does not have direct correspondence to Scala code,
+ * and is emitted by macros to reference capture vars directly without going through `elem`.
+ *
+ * For example:
+ *
+ * var x = ...
+ * fun { x }
+ *
+ * Will emit:
+ *
+ * Ident(x)
+ *
+ * Which gets transformed to:
+ *
+ * Select(Ident(x), "elem")
+ *
+ * If `ReferenceToBoxed` were used instead of Ident, no transformation would be performed.
+ * @group Internal
+ */
+ abstract class ReferenceToBoxedExtractor {
+ def apply(ident: Ident): ReferenceToBoxed
+ def unapply(referenceToBoxed: ReferenceToBoxed): Option[Ident]
+ }
+
+ /** The API that all references support
+ * @group Internal
+ */
+ trait ReferenceToBoxedApi extends TermTreeApi { this: ReferenceToBoxed =>
+ /** The underlying reference. */
+ def ident: Tree
+ }
+
+ /** Tag that preserves the identity of `ReferenceToBoxed` in the face of erasure.
+ * Can be used for pattern matching, instance tests, serialization and the like.
+ * @group Internal
+ */
+ implicit val ReferenceToBoxedTag: ClassTag[ReferenceToBoxed]
+
+ /** The type of free terms introduced by reification.
+ * @group Internal
+ * @template
+ */
+ type FreeTermSymbol >: Null <: FreeTermSymbolApi with TermSymbol
+
+ /** The API of free term symbols.
+ * The main source of information about symbols is the [[Symbols]] page.
+ *
+ * $SYMACCESSORS
+ * @group Internal
+ */
+ trait FreeTermSymbolApi extends TermSymbolApi { this: FreeTermSymbol =>
+ /** The place where this symbol has been spawned
+ *
+ * @group FreeTerm
+ */
+ def origin: String
+
+ /** The valus this symbol refers to
+ *
+ * @group FreeTerm
+ */
+ def value: Any
+ }
+
+ /** Tag that preserves the identity of `FreeTermSymbol` in the face of erasure.
+ * Can be used for pattern matching, instance tests, serialization and the like.
+ * @group Internal
+ */
+ implicit val FreeTermSymbolTag: ClassTag[FreeTermSymbol]
+
+ /** The type of free types introduced by reification.
+ * @group Internal
+ * @template
+ */
+ type FreeTypeSymbol >: Null <: FreeTypeSymbolApi with TypeSymbol
+
+ /** The API of free type symbols.
+ * The main source of information about symbols is the [[Symbols]] page.
+ *
+ * $SYMACCESSORS
+ * @group Internal
+ */
+ trait FreeTypeSymbolApi extends TypeSymbolApi { this: FreeTypeSymbol =>
+ /** The place where this symbol has been spawned
+ *
+ * @group FreeType
+ */
+ def origin: String
+ }
+
+ /** Tag that preserves the identity of `FreeTermSymbol` in the face of erasure.
+ * Can be used for pattern matching, instance tests, serialization and the like.
+ * @group Internal
+ */
+ implicit val FreeTypeSymbolTag: ClassTag[FreeTypeSymbol]
+
+ /** Provides enrichments to ensure source compatibility between Scala 2.10 and Scala 2.11.
+ * If in your reflective program for Scala 2.10 you've used something that's now become an internal API,
+ * a single `compat._` import will fix things for you.
+ * @group Internal
+ */
+ val compat: Compat
+
+ /** @see [[compat]]
+ * @group Internal
+ */
+ type Compat <: CompatApi
+
+ /** Presence of an implicit value of this type in scope
+ * indicates that source compatibility with Scala 2.10 has been enabled.
+ * @group Internal
+ */
+ @scala.annotation.implicitNotFound("This method has been removed from the public API. Import compat._ or migrate away.")
+ class CompatToken
+
+ /** @see [[compat]]
+ * @group Internal
+ */
+ trait CompatApi {
+ /** @see [[CompatToken]] */
+ implicit val token = new CompatToken
+
+ /** @see [[InternalApi.typeTagToManifest]] */
+ @deprecated("Use `internal.typeTagToManifest` instead", "2.11.0")
+ def typeTagToManifest[T: ClassTag](mirror: Any, tag: Universe#TypeTag[T]): Manifest[T] =
+ internal.typeTagToManifest(mirror, tag)
+
+ /** @see [[InternalApi.manifestToTypeTag]] */
+ @deprecated("Use `internal.manifestToTypeTag` instead", "2.11.0")
+ def manifestToTypeTag[T](mirror: Any, manifest: Manifest[T]): Universe#TypeTag[T] =
+ internal.manifestToTypeTag(mirror, manifest)
+
+ /** @see [[InternalApi.newScopeWith]] */
+ @deprecated("Use `internal.newScopeWith` instead", "2.11.0")
+ def newScopeWith(elems: Symbol*): Scope =
+ internal.newScopeWith(elems: _*)
+
+ /** Scala 2.10 compatibility enrichments for BuildApi. */
+ implicit class CompatibleBuildApi(api: BuildApi) {
+ /** @see [[BuildApi.setInfo]] */
+ @deprecated("Use `internal.reificationSupport.setInfo` instead", "2.11.0")
+ def setTypeSignature[S <: Symbol](sym: S, tpe: Type): S = internal.reificationSupport.setInfo(sym, tpe)
+
+ /** @see [[BuildApi.FlagsRepr]] */
+ @deprecated("Use `internal.reificationSupport.FlagsRepr` instead", "2.11.0")
+ def flagsFromBits(bits: Long): FlagSet = internal.reificationSupport.FlagsRepr(bits)
+
+ /** @see [[BuildApi.noSelfType]] */
+ @deprecated("Use `noSelfType` instead", "2.11.0")
+ def emptyValDef: ValDef = noSelfType
+
+ /** @see [[BuildApi.mkThis]] */
+ @deprecated("Use `internal.reificationSupport.mkThis` instead", "2.11.0")
+ def This(sym: Symbol): Tree = internal.reificationSupport.mkThis(sym)
+
+ /** @see [[BuildApi.mkSelect]] */
+ @deprecated("Use `internal.reificationSupport.mkSelect` instead", "2.11.0")
+ def Select(qualifier: Tree, sym: Symbol): Select = internal.reificationSupport.mkSelect(qualifier, sym)
+
+ /** @see [[BuildApi.mkIdent]] */
+ @deprecated("Use `internal.reificationSupport.mkIdent` instead", "2.11.0")
+ def Ident(sym: Symbol): Ident = internal.reificationSupport.mkIdent(sym)
+
+ /** @see [[BuildApi.mkTypeTree]] */
+ @deprecated("Use `internal.reificationSupport.mkTypeTree` instead", "2.11.0")
+ def TypeTree(tp: Type): TypeTree = internal.reificationSupport.mkTypeTree(tp)
+ }
+
+ /** Scala 2.10 compatibility enrichments for Tree. */
+ implicit class CompatibleTree(tree: Tree) {
+ /** @see [[InternalApi.freeTerms]] */
+ @deprecated("Use `internal.freeTerms` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def freeTerms: List[FreeTermSymbol] = internal.freeTerms(tree)
+
+ /** @see [[InternalApi.freeTypes]] */
+ @deprecated("Use `internal.freeTerms` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def freeTypes: List[FreeTypeSymbol] = internal.freeTypes(tree)
+
+ /** @see [[InternalApi.substituteSymbols]] */
+ @deprecated("Use `internal.substituteSymbols` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def substituteSymbols(from: List[Symbol], to: List[Symbol]): Tree = internal.substituteSymbols(tree, from, to)
+
+ /** @see [[InternalApi.substituteTypes]] */
+ @deprecated("Use `internal.substituteTypes` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def substituteTypes(from: List[Symbol], to: List[Type]): Tree = internal.substituteTypes(tree, from, to)
+
+ /** @see [[InternalApi.substituteThis]] */
+ @deprecated("Use `internal.substituteThis` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def substituteThis(clazz: Symbol, to: Tree): Tree = internal.substituteThis(tree, clazz, to)
+ }
+
+ /** Scala 2.10 compatibility enrichments for Tree. */
+ implicit class CompatibleSymbol(symbol: Symbol) {
+ @deprecated("This API is unreliable. Use `isPrivateThis` or `isProtectedThis` instead", "2.11.0")
+ def isLocal: Boolean = symbol.asInstanceOf[scala.reflect.internal.Symbols#Symbol].isLocal
+
+ @deprecated("This API is unreliable. Use `overrides.nonEmpty` instead", "2.11.0")
+ def isOverride: Boolean = symbol.asInstanceOf[scala.reflect.internal.Symbols#Symbol].isOverride
+
+ /** @see [[InternalApi.isFreeTerm]] */
+ @deprecated("Use `internal.isFreeTerm` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def isFreeTerm: Boolean = internal.isFreeTerm(symbol)
+
+ /** @see [[InternalApi.asFreeTerm]] */
+ @deprecated("Use `internal.asFreeTerm` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def asFreeTerm: FreeTermSymbol = internal.asFreeTerm(symbol)
+
+ /** @see [[InternalApi.isFreeType]] */
+ @deprecated("Use `internal.isFreeType` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def isFreeType: Boolean = internal.isFreeType(symbol)
+
+ /** @see [[InternalApi.asFreeType]] */
+ @deprecated("Use `internal.asFreeType` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def asFreeType: FreeTypeSymbol = internal.asFreeType(symbol)
+
+ /** @see [[InternalApi.asFreeType]] */
+ @deprecated("Use `internal.newTermSymbol` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def newTermSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TermSymbol = internal.newTermSymbol(symbol, name, pos, flags)
+
+ /** @see [[InternalApi.asFreeType]] */
+ @deprecated("Use `internal.newModuleAndClassSymbol` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def newModuleAndClassSymbol(name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol) = internal.newModuleAndClassSymbol(symbol, name, pos, flags)
+
+ /** @see [[InternalApi.asFreeType]] */
+ @deprecated("Use `internal.newMethodSymbol` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def newMethodSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): MethodSymbol = internal.newMethodSymbol(symbol, name, pos, flags)
+
+ /** @see [[InternalApi.asFreeType]] */
+ @deprecated("Use `internal.newTypeSymbol` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def newTypeSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TypeSymbol = internal.newTypeSymbol(symbol, name, pos, flags)
+
+ /** @see [[InternalApi.asFreeType]] */
+ @deprecated("Use `internal.newClassSymbol` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def newClassSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): ClassSymbol = internal.newClassSymbol(symbol, name, pos, flags)
+
+ /** @see [[InternalApi.asFreeType]] */
+ @deprecated("Use `internal.isErroneous` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def isErroneous: Boolean = internal.isErroneous(symbol)
+
+ /** @see [[InternalApi.asFreeType]] */
+ @deprecated("Use `internal.isSkolem` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def isSkolem: Boolean = internal.isSkolem(symbol)
+
+ /** @see [[InternalApi.asFreeType]] */
+ @deprecated("Use `internal.deSkolemize` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def deSkolemize: Symbol = internal.deSkolemize(symbol)
+ }
+
+ /** @see [[InternalApi.singleType]] */
+ @deprecated("Use `internal.singleType` instead", "2.11.0")
+ def singleType(pre: Type, sym: Symbol): Type = internal.singleType(pre, sym)
+
+ /** @see [[InternalApi.refinedType]] */
+ @deprecated("Use `internal.refinedType` instead", "2.11.0")
+ def refinedType(parents: List[Type], owner: Symbol, decls: Scope, pos: Position): Type = internal.refinedType(parents, owner, decls, pos)
+
+ /** @see [[InternalApi.refinedType]] */
+ @deprecated("Use `internal.refinedType` instead", "2.11.0")
+ def refinedType(parents: List[Type], owner: Symbol): Type = internal.refinedType(parents, owner)
+
+ /** @see [[InternalApi.typeRef]] */
+ @deprecated("Use `internal.typeRef` instead", "2.11.0")
+ def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type = internal.typeRef(pre, sym, args)
+
+ /** @see [[InternalApi.intersectionType]] */
+ @deprecated("Use `internal.intersectionType` instead", "2.11.0")
+ def intersectionType(tps: List[Type]): Type = internal.intersectionType(tps)
+
+ /** @see [[InternalApi.intersectionType]] */
+ @deprecated("Use `internal.intersectionType` instead", "2.11.0")
+ def intersectionType(tps: List[Type], owner: Symbol): Type = internal.intersectionType(tps, owner)
+
+ /** @see [[InternalApi.polyType]] */
+ @deprecated("Use `internal.polyType` instead", "2.11.0")
+ def polyType(tparams: List[Symbol], tpe: Type): Type = internal.polyType(tparams, tpe)
+
+ /** @see [[InternalApi.existentialAbstraction]] */
+ @deprecated("Use `internal.existentialAbstraction` instead", "2.11.0")
+ def existentialAbstraction(tparams: List[Symbol], tpe0: Type): Type = internal.existentialAbstraction(tparams, tpe0)
+ }
+}
diff --git a/src/reflect/scala/reflect/api/JavaMirrors.scala b/src/reflect/scala/reflect/api/JavaMirrors.scala
deleted file mode 100644
index 23abc23eb9..0000000000
--- a/src/reflect/scala/reflect/api/JavaMirrors.scala
+++ /dev/null
@@ -1,57 +0,0 @@
-package scala
-package reflect
-package api
-
-/**
- * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
- *
- * A refinement of [[scala.reflect.api.Mirror]] for runtime reflection using JVM classloaders.
- *
- * This refinement equips mirrors with reflection capabilities for the JVM. `JavaMirror` can
- * convert Scala reflection artifacts (symbols and types) into Java reflection artifacts (classes)
- * and vice versa. It can also perform reflective invocations (getting/setting field values,
- * calling methods, etc).
- *
- * For more information about `Mirrors`s, see [[scala.reflect.api.Mirrors]] or the
- * [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Mirrors]]
- *
- * @groupname JavaMirrors Java Mirrors
- * @group ReflectionAPI
- */
-trait JavaMirrors { self: JavaUniverse =>
-
- /** In runtime reflection universes, runtime representation of a class is `java.lang.Class`.
- * @group JavaMirrors
- */
- type RuntimeClass = java.lang.Class[_]
-
- /** In runtime reflection universes, mirrors are `JavaMirrors`.
- * @group JavaMirrors
- */
- override type Mirror >: Null <: JavaMirror
-
- /** A refinement of [[scala.reflect.api.Mirror]] for runtime reflection using JVM classloaders.
- *
- * With this upgrade, mirrors become capable of converting Scala reflection artifacts (symbols and types)
- * into Java reflection artifacts (classes) and vice versa. Consequently, refined mirrors
- * become capable of performing reflective invocations (getting/setting field values, calling methods, etc).
- *
- * For more information about `Mirrors`s, see [[scala.reflect.api.Mirrors]] or the
- * [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Mirrors]]
- *
- * @group JavaMirrors
- */
- trait JavaMirror extends scala.reflect.api.Mirror[self.type] with RuntimeMirror {
- val classLoader: ClassLoader
- override def toString = s"JavaMirror with ${runtime.ReflectionUtils.show(classLoader)}"
- }
-
- /** Creates a runtime reflection mirror from a JVM classloader.
- *
- * For more information about `Mirrors`s, see [[scala.reflect.api.Mirrors]] or the
- * [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Mirrors]]
- *
- * @group JavaMirrors
- */
- def runtimeMirror(cl: ClassLoader): Mirror
-}
diff --git a/src/reflect/scala/reflect/api/JavaUniverse.scala b/src/reflect/scala/reflect/api/JavaUniverse.scala
index df5e0699a5..88107ea117 100644
--- a/src/reflect/scala/reflect/api/JavaUniverse.scala
+++ b/src/reflect/scala/reflect/api/JavaUniverse.scala
@@ -3,12 +3,14 @@ package reflect
package api
/**
- * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
+ * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
*
- * A refinement of [[scala.reflect.api.Universe]] for runtime reflection using JVM classloaders.
+ * A refinement of [[scala.reflect.api.Universe]] for runtime reflection using JVM classloaders.
*
- * The refinement consists of an upgrade to the mirror API, which gets extended from [[scala.reflect.api.Mirror]]
- * to [[scala.reflect.api.JavaMirrors#JavaMirror]].
+ * This refinement equips mirrors with reflection capabilities for the JVM. `JavaMirror` can
+ * convert Scala reflection artifacts (symbols and types) into Java reflection artifacts (classes)
+ * and vice versa. It can also perform reflective invocations (getting/setting field values,
+ * calling methods, etc).
*
* See the [[http://docs.scala-lang.org/overviews/reflection/overview.html Reflection Guide]] for details on how to use runtime reflection.
*
@@ -17,31 +19,41 @@ package api
*
* @contentDiagram hideNodes "*Api"
*/
-trait JavaUniverse extends Universe with JavaMirrors { self =>
+trait JavaUniverse extends Universe { self =>
- /* @group JavaUniverse */
- override def typeTagToManifest[T: ClassTag](mirror0: Any, tag: Universe # TypeTag[T]): Manifest[T] = {
- // SI-6239: make this conversion more precise
- val mirror = mirror0.asInstanceOf[Mirror]
- val runtimeClass = mirror.runtimeClass(tag.in(mirror).tpe)
- Manifest.classType(runtimeClass).asInstanceOf[Manifest[T]]
+ /** In runtime reflection universes, runtime representation of a class is `java.lang.Class`.
+ * @group JavaMirrors
+ */
+ type RuntimeClass = java.lang.Class[_]
+ implicit val RuntimeClassTag: ClassTag[RuntimeClass] = ClassTag[RuntimeClass](classOf[RuntimeClass])
+
+ /** In runtime reflection universes, mirrors are `JavaMirrors`.
+ * @group JavaMirrors
+ */
+ override type Mirror >: Null <: JavaMirror
+
+ /** A refinement of [[scala.reflect.api.Mirror]] for runtime reflection using JVM classloaders.
+ *
+ * With this upgrade, mirrors become capable of converting Scala reflection artifacts (symbols and types)
+ * into Java reflection artifacts (classes) and vice versa. Consequently, refined mirrors
+ * become capable of performing reflective invocations (getting/setting field values, calling methods, etc).
+ *
+ * For more information about `Mirrors`s, see [[scala.reflect.api.Mirrors]] or the
+ * [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Mirrors]]
+ *
+ * @group JavaMirrors
+ */
+ trait JavaMirror extends scala.reflect.api.Mirror[self.type] with RuntimeMirror {
+ val classLoader: ClassLoader
+ override def toString = s"JavaMirror with ${runtime.ReflectionUtils.show(classLoader)}"
}
- /* @group JavaUniverse */
- 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: scala.reflect.api.Mirror[U]): U # Type = {
- mirror.universe match {
- case ju: JavaUniverse =>
- val jm = mirror.asInstanceOf[ju.Mirror]
- val sym = jm.classSymbol(manifest.runtimeClass)
- val tpe =
- if (manifest.typeArguments.isEmpty) sym.toType
- else ju.appliedType(sym.toTypeConstructor, manifest.typeArguments map (targ => ju.manifestToTypeTag(jm, targ)) map (_.in(jm).tpe))
- tpe.asInstanceOf[U # Type]
- case u =>
- u.manifestToTypeTag(mirror.asInstanceOf[u.Mirror], manifest).in(mirror).tpe
- }
- }
- })
-}
+ /** Creates a runtime reflection mirror from a JVM classloader.
+ *
+ * For more information about `Mirrors`s, see [[scala.reflect.api.Mirrors]] or the
+ * [[http://docs.scala-lang.org/overviews/reflection/environment-universes-mirrors.html Reflection Guide: Mirrors]]
+ *
+ * @group JavaMirrors
+ */
+ def runtimeMirror(cl: ClassLoader): Mirror
+} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/api/Mirror.scala b/src/reflect/scala/reflect/api/Mirror.scala
index e0219c9074..da3afd89ff 100644
--- a/src/reflect/scala/reflect/api/Mirror.scala
+++ b/src/reflect/scala/reflect/api/Mirror.scala
@@ -58,7 +58,7 @@ abstract class Mirror[U <: Universe with Singleton] {
* scala> cm.staticPackage("scala")
* res2: scala.reflect.runtime.universe.ModuleSymbol = package scala
*
- * scala> res2.moduleClass.typeSignature member newTypeName("List")
+ * scala> res2.moduleClass.info member newTypeName("List")
* res3: scala.reflect.runtime.universe.Symbol = type List
*
* scala> res3.fullName
@@ -79,11 +79,10 @@ abstract class Mirror[U <: Universe with Singleton] {
* }
*
* staticClass("foo.B") will resolve to the symbol corresponding to the class B declared in the package foo, and
- * staticClass("foo.A") will throw a MissingRequirementException (which is exactly what scalac would do if this
- * fully qualified class name is written inside any package in a Scala program).
+ * staticClass("foo.A") will throw a ScalaReflectionException.
*
* In the example above, to load a symbol that corresponds to the class B declared in the object foo,
- * use staticModule("foo") to load the module symbol and then navigate typeSignature.members of its moduleClass.
+ * use staticModule("foo") to load the module symbol and then navigate info.members of its moduleClass.
* @group Mirror
*/
def staticClass(fullName: String): U#ClassSymbol
@@ -106,11 +105,10 @@ abstract class Mirror[U <: Universe with Singleton] {
* }
*
* staticModule("foo.B") will resolve to the symbol corresponding to the object B declared in the package foo, and
- * staticModule("foo.A") will throw a MissingRequirementException (which is exactly what scalac would do if this
- * fully qualified class name is written inside any package in a Scala program).
+ * staticModule("foo.A") will throw a ScalaReflectionException
*
* In the example above, to load a symbol that corresponds to the object B declared in the object foo,
- * use staticModule("foo") to load the module symbol and then navigate typeSignature.members of its moduleClass.
+ * use staticModule("foo") to load the module symbol and then navigate info.members of its moduleClass.
* @group Mirror
*/
def staticModule(fullName: String): U#ModuleSymbol
diff --git a/src/reflect/scala/reflect/api/Mirrors.scala b/src/reflect/scala/reflect/api/Mirrors.scala
index f11b9a5c55..ec420d184c 100644
--- a/src/reflect/scala/reflect/api/Mirrors.scala
+++ b/src/reflect/scala/reflect/api/Mirrors.scala
@@ -62,7 +62,7 @@ package api
* The entry point to `Mirror`s for use at runtime is via `ru.runtimeMirror(<classloader>)`, where
* `ru` is [[scala.reflect.runtime.universe]].
*
- * The result of a [[scala.reflect.api.JavaMirrors#runtimeMirror]] call is a classloader mirror,
+ * The result of a [[scala.reflect.api.JavaUniverse#runtimeMirror]] call is a classloader mirror,
* of type [[scala.reflect.api.Mirrors#ReflectiveMirror]], which can load symbols by names as
* discussed above (in the “Compile-time” section).
*
@@ -225,7 +225,12 @@ trait Mirrors { self: Universe =>
/** Abstracts the runtime representation of a class on the underlying platform.
* @group Mirrors
*/
- type RuntimeClass >: Null
+ type RuntimeClass >: Null <: AnyRef
+
+ /** Has no special methods. Is here to provides erased identity for `RuntimeClass`.
+ * @group API
+ */
+ trait RuntimeClassApi
// todo. an improvement might be having mirrors reproduce the structure of the reflection domain
// e.g. a ClassMirror could also have a list of fields, methods, constructors and so on
@@ -255,8 +260,8 @@ trait Mirrors { self: Universe =>
* Note also that only accessor MethodMirrors, but not FieldMirrors will accurately reflect overriding behavior.
*
* To get a field symbol by the name of the field you would like to reflect,
- * use `<this mirror>.symbol.typeSignature.member(TermName(<name of the field>)).asTerm.accessed`.
- * For further information about member lookup refer to `Symbol.typeSignature`.
+ * use `<this mirror>.symbol.info.member(TermName(<name of the field>)).asTerm.accessed`.
+ * For further information about member lookup refer to `Symbol.info`.
*
* The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
* It must be a member (declared or inherited) of the class of the instance underlying this mirror.
@@ -275,8 +280,8 @@ trait Mirrors { self: Universe =>
* that can be used to invoke the method provided.
*
* To get a method symbol by the name of the method you would like to reflect,
- * use `<this mirror>.symbol.typeSignature.member(TermName(<name of the method>)).asMethod`.
- * For further information about member lookup refer to `Symbol.typeSignature`.
+ * use `<this mirror>.symbol.info.member(TermName(<name of the method>)).asMethod`.
+ * For further information about member lookup refer to `Symbol.info`.
*
* The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
* It must be a member (declared or inherited) of the instance underlying this mirror.
@@ -287,8 +292,8 @@ trait Mirrors { self: Universe =>
* that can be used to create instances of the class, inspect its companion object or perform further reflections.
*
* To get a class symbol by the name of the class you would like to reflect,
- * use `<this mirror>.symbol.typeSignature.member(newTypeName(<name of the class>)).asClass`.
- * For further information about member lookup refer to `Symbol.typeSignature`.
+ * use `<this mirror>.symbol.info.member(newTypeName(<name of the class>)).asClass`.
+ * For further information about member lookup refer to `Symbol.info`.
*
* The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
* It must be a member (declared or inherited) of the instance underlying this mirror.
@@ -299,8 +304,8 @@ trait Mirrors { self: Universe =>
* that can be used to get the instance of the object or inspect its companion class.
*
* To get a module symbol by the name of the object you would like to reflect,
- * use `<this mirror>.symbol.typeSignature.member(TermName(<name of the object>)).asModule`.
- * For further information about member lookup refer to `Symbol.typeSignature`.
+ * use `<this mirror>.symbol.info.member(TermName(<name of the object>)).asModule`.
+ * For further information about member lookup refer to `Symbol.info`.
*
* The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
* It must be a member (declared or inherited) of the instance underlying this mirror.
@@ -432,8 +437,8 @@ trait Mirrors { self: Universe =>
* that can be used to invoke it and construct instances of this mirror's symbols.
*
* To get a constructor symbol you would like to reflect,
- * use `<this mirror>.symbol.typeSignature.member(nme.CONSTRUCTOR).asMethod`.
- * For further information about member lookup refer to `Symbol.typeSignature`.
+ * use `<this mirror>.symbol.info.member(termNames.CONSTRUCTOR).asMethod`.
+ * For further information about member lookup refer to `Symbol.info`.
*
* The input symbol can be either private or non-private (Scala reflection transparently deals with visibility).
* It must be a member (declared or inherited) of the class underlying this mirror.
@@ -499,7 +504,7 @@ trait Mirrors { self: Universe =>
/** A class symbol for the specified runtime class.
* @return The class symbol for the runtime class in the current class loader.
* @throws java.lang.ClassNotFoundException if no class with that name exists
- * @throws scala.reflect.internal.MissingRequirementError if no corresponding symbol exists
+ * @throws scala.reflect.ScalaReflectionException if no corresponding symbol exists
* to do: throws anything else?
*/
def classSymbol(rtcls: RuntimeClass): ClassSymbol
@@ -507,7 +512,7 @@ trait Mirrors { self: Universe =>
/** A module symbol for the specified runtime class.
* @return The module symbol for the runtime class in the current class loader.
* @throws java.lang.ClassNotFoundException if no class with that name exists
- * @throws scala.reflect.internal.MissingRequirementError if no corresponding symbol exists
+ * @throws scala.reflect.ScalaReflectionException if no corresponding symbol exists
* to do: throws anything else?
*/
def moduleSymbol(rtcls: RuntimeClass): ModuleSymbol
diff --git a/src/reflect/scala/reflect/api/Names.scala b/src/reflect/scala/reflect/api/Names.scala
index 87d7f9fd8e..fe5f47c25d 100644
--- a/src/reflect/scala/reflect/api/Names.scala
+++ b/src/reflect/scala/reflect/api/Names.scala
@@ -33,28 +33,40 @@ trait Names {
* Enables an alternative notation `"map": TermName` as opposed to `newTermName("map")`.
* @group Names
*/
+ @deprecated("Use explicit `TermName(s)` instead", "2.11.0")
implicit def stringToTermName(s: String): TermName = TermName(s)
/** An implicit conversion from String to TypeName.
* Enables an alternative notation `"List": TypeName` as opposed to `newTypeName("List")`.
* @group Names
*/
+ @deprecated("Use explicit `TypeName(s)` instead", "2.11.0")
implicit def stringToTypeName(s: String): TypeName = TypeName(s)
/** The abstract type of names.
* @group Names
*/
- type Name >: Null <: NameApi
+ type Name >: Null <: AnyRef with NameApi
/** The abstract type of names representing terms.
* @group Names
*/
- type TypeName >: Null <: Name
+ type TypeName >: Null <: TypeNameApi with Name
+
+ /** Has no special methods. Is here to provides erased identity for `TypeName`.
+ * @group API
+ */
+ trait TypeNameApi
/** The abstract type of names representing types.
* @group Names
*/
- type TermName >: Null <: Name
+ type TermName >: Null <: TermNameApi with Name
+
+ /** Has no special methods. Is here to provides erased identity for `TermName`.
+ * @group API
+ */
+ trait TermNameApi
/** The API of Name instances.
* @group API
@@ -75,11 +87,13 @@ trait Names {
/** Replaces all occurrences of \$op_names in this name by corresponding operator symbols.
* Example: `foo_\$plus\$eq` becomes `foo_+=`
*/
+ @deprecated("Use `decodedName.toString` instead", "2.11.0")
def decoded: String
/** Replaces all occurrences of operator symbols in this name by corresponding \$op_names.
* Example: `foo_+=` becomes `foo_\$plus\$eq`.
*/
+ @deprecated("Use `encodedName.toString` instead", "2.11.0")
def encoded: String
/** The decoded name, still represented as a name.
diff --git a/src/reflect/scala/reflect/api/Position.scala b/src/reflect/scala/reflect/api/Position.scala
index 2019e2f1d9..9d1b7c3812 100644
--- a/src/reflect/scala/reflect/api/Position.scala
+++ b/src/reflect/scala/reflect/api/Position.scala
@@ -5,14 +5,48 @@ package api
import scala.reflect.macros.Attachments
/**
- * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
+ * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
*
- * Position tracks the origin of [[Symbols#Symbol symbols]] and [[Trees#Tree tree nodes]]. They are commonly used when
- * displaying warnings and errors, to indicate the incorrect point in the program.
+ * Position tracks the origin of [[Symbols#Symbol symbols]] and [[Trees#Tree tree nodes]]. They are commonly used when
+ * displaying warnings and errors, to indicate the incorrect point in the program.
*
- * <b>Please note that this trait may be refactored in future versions of the Scala reflection API.</b>
+ * Every non-empty position refers to a SourceFile and three character
+ * offsets within it: start, end, and point. The point is where the ^ belongs when
+ * issuing an error message, usually a Name. A range position can be designated
+ * as transparent, which excuses it from maintaining the invariants to follow. If
+ * a transparent position has opaque children, those are considered as if they were
+ * the direct children of the transparent position's parent.
*
- * For more information about `Position`s, see the [[http://docs.scala-lang.org/overviews/reflection/annotations-names-scopes.html Reflection Guide: Annotations, Names, Scopes, and More]]
+ * Note: some of these invariants actually apply to the trees which carry
+ * the positions, but they are phrased as if the positions themselves were
+ * the parent/children for conciseness.
+ *
+ * Invariant 1: in a focused/offset position, start == point == end
+ * Invariant 2: in a range position, start <= point < end
+ * Invariant 3: an offset position never has a child with a range position
+ * Invariant 4: every range position child of a range position parent is contained within its parent
+ * Invariant 5: opaque range position siblings overlap at most at a single point
+ *
+ * The following tests are useful on positions:
+ *
+ * pos.isDefined true if position is not an UndefinedPosition (those being NoPosition and FakePos)
+ * pos.isRange true if position is a range (opaque or transparent) which implies start < end
+ * pos.isOpaqueRange true if position is an opaque range
+ *
+ * The following accessor methods are provided - an exception will be thrown if
+ * point/start/end are attempted on an UndefinedPosition.
+ *
+ * pos.source The source file of the position, or NoSourceFile if unavailable
+ * pos.point The offset of the point
+ * pos.start The (inclusive) start offset, or the point of an offset position
+ * pos.end The (exclusive) end offset, or the point of an offset position
+ *
+ * The following conversion methods are often used:
+ *
+ * pos.focus Converts a range position to an offset position focused on the point
+ * pos.makeTransparent Convert an opaque range into a transparent range
+ *
+ * For more information about `Position`s, see the [[http://docs.scala-lang.org/overviews/reflection/annotations-names-scopes.html Reflection Guide: Annotations, Names, Scopes, and More]]
*
* @groupname Common Commonly used methods
* @group ReflectionAPI
@@ -20,23 +54,9 @@ import scala.reflect.macros.Attachments
trait Position extends Attachments {
/** @inheritdoc */
- 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.
- *
- * @group Common
- */
- def source: scala.reflect.internal.util.SourceFile
+ type Pos >: Null <: AnyRef with Position
- /** Is this position neither a NoPosition nor a FakePosition?
- * If isDefined is true, offset and source are both defined.
- * @group Common
- */
- def isDefined: Boolean
+ ////////////////// POSITION FLAVORS //////////////////
/** Is this position a range position? */
def isRange: Boolean
@@ -47,119 +67,141 @@ trait Position extends Attachments {
/** Is this position a non-transparent range position? */
def isOpaqueRange: Boolean
+ /** If this is a range position, the offset position of its point.
+ * Otherwise the position itself
+ */
+ def focus: Pos
+
/** If opaque range, make this position transparent. */
def makeTransparent: Pos
+ ////////////////// POSITION ESSENTIALS //////////////////
+
/** The start of the position's range, or the point if not a range position. */
def start: Int
- /** The start of the position's range, or point if not a range position. */
- @deprecated("Use `start` instead", "2.11.0") def startOrPoint: Int
-
/** The point (where the ^ is) of the position, which is easiest to access using the [[line]] and [[column]] values.
* The [[lineContent line content]] is also available.
* @group Common
*/
def point: Int
- /** The point (where the ^ is) of the position, or else `default` if undefined.
+ /** The end of the position's range, or the point if not a range position.
+ */
+ def end: Int
+
+ /** 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.
+ *
* @group Common
*/
- def pointOrElse(default: Int): Int
+ def source: scala.reflect.internal.util.SourceFile
- /** The end of the position's range, or the point if not a range position.
+ /** The position indicates a [[column `column`]] and the `line` in the source file.
+ * @group Common
*/
- def end: Int
+ def line: Int
- /** The end of the position's range, or point if not a range position.
+ /** The position indicates a `column` and the [[line `line`]] in the source file.
+ * @group Common
*/
- @deprecated("Use `end` instead", "2.11.0") def endOrPoint: Int
+ def column: Int
- /** The same position with a different start value (if a range).
+ ////////////////// POSITION FACTORIES //////////////////
+
+ /** Returns a new position with the same attributes, but a different start value (if a range).
*/
def withStart(off: Int): Pos
- /** The same position with a different end value (if a range).
+ /** Returns a new position with the same attributes, but 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).
+ /** Returns a new position with the same attributes, but 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
+ ////////////////// STUFF //////////////////
+
+ /** Is this position not a NoPosition?
+ * If isDefined is true, offset and source are both defined.
+ * @group Common
*/
- def union(pos: Pos): Pos
+ @deprecated("Removed from the public API", "2.11.0") def isDefined: Boolean
- /** If this is a range position, the offset position of its point.
- * Otherwise the position itself
+ /** The point (where the ^ is) of the position, or else `default` if undefined.
+ * @group Common
*/
- def focus: Pos
+ @deprecated("Removed from the public API", "2.11.0") def pointOrElse(default: Int): Int
+
+ /** The start of the position's range, or point if not a range position. */
+ @deprecated("Removed from the public API", "2.11.0") def startOrPoint: Int
+
+ /** The end of the position's range, or point if not a range position.
+ */
+ @deprecated("Removed from the public API", "2.11.0") def endOrPoint: Int
+
+ /** If this is a range, the union with the other range, with the point of this position.
+ * Otherwise, this position
+ */
+ @deprecated("Removed from the public API", "2.11.0") def union(pos: Pos): Pos
/** If this is a range position, the offset position of its start.
* Otherwise the position itself
*/
- def focusStart: Pos
+ @deprecated("Removed from the public API", "2.11.0") def focusStart: Pos
/** If this is a range position, the offset position of its end.
* Otherwise the position itself
*/
- def focusEnd: Pos
+ @deprecated("Removed from the public API", "2.11.0") 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
+ @deprecated("Removed from the public API", "2.11.0") 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
+ @deprecated("Removed from the public API", "2.11.0") 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
+ @deprecated("Removed from the public API", "2.11.0") 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
+ @deprecated("Removed from the public API", "2.11.0") 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
+ @deprecated("Removed from the public API", "2.11.0") 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
-
- /** The position indicates a [[column `column`]] and the `line` in the source file.
- * @group Common
- */
- def line: Int
-
- /** The position indicates a `column` and the [[line `line`]] in the source file.
- * @group Common
- */
- def column: Int
+ @deprecated("Removed from the public API", "2.11.0") def sameRange(pos: Pos): Boolean
/** Convert this to a position around `point` that spans a single source line
*/
- def toSingleLine: Pos
+ @deprecated("Removed from the public API", "2.11.0") def toSingleLine: Pos
/** The content of the line this Position refers to.
* @group Common
*/
- def lineContent: String
+ @deprecated("Removed from the public API", "2.11.0") def lineContent: String
/** Show a textual representation of the position.
*/
- def show: String
+ @deprecated("Use `universe.show(position)` instead", "2.11.0") def show: String
}
diff --git a/src/reflect/scala/reflect/api/Positions.scala b/src/reflect/scala/reflect/api/Positions.scala
index 8ad46418f8..63ad605656 100644
--- a/src/reflect/scala/reflect/api/Positions.scala
+++ b/src/reflect/scala/reflect/api/Positions.scala
@@ -19,7 +19,8 @@ trait Positions {
* The main documentation entry about positions is located at [[scala.reflect.api.Position]].
* @group Positions
*/
- type Position >: Null <: scala.reflect.api.Position { type Pos = Position }
+ type Position >: Null <: AnyRef with scala.reflect.api.Position { type Pos = Position }
+
/** A special "missing" position.
* @group Positions
*/
diff --git a/src/reflect/scala/reflect/api/Printers.scala b/src/reflect/scala/reflect/api/Printers.scala
index 637fcd782e..b262fdce68 100644
--- a/src/reflect/scala/reflect/api/Printers.scala
+++ b/src/reflect/scala/reflect/api/Printers.scala
@@ -252,8 +252,23 @@ trait Printers { self: Universe =>
*/
def show(flags: FlagSet): String
+ /** Renders a prettified representation of a position.
+ * @group Printers
+ */
+ def show(position: Position): String
+
/** Renders internal structure of a flag set.
* @group Printers
*/
def showRaw(flags: FlagSet): String = flags.toString
+
+ /** Renders internal structure of a position.
+ * @group Printers
+ */
+ def showRaw(position: Position): String = position.toString
+
+ /** Renders a string that represents a declaration of this symbol written in Scala.
+ * @group Printers
+ */
+ def showDecl(sym: Symbol): String
}
diff --git a/src/reflect/scala/reflect/api/Scopes.scala b/src/reflect/scala/reflect/api/Scopes.scala
index 2eb477f652..c9142fba47 100644
--- a/src/reflect/scala/reflect/api/Scopes.scala
+++ b/src/reflect/scala/reflect/api/Scopes.scala
@@ -16,7 +16,7 @@ package api
* there is the `newScopeWith` function.
*
* Additional functionality is exposed in member scopes that are returned by
- * `members` and `declarations` defined in [[scala.reflect.api.Types#TypeApi]].
+ * `members` and `decls` defined in [[scala.reflect.api.Types#TypeApi]].
* Such scopes support the `sorted` method, which sorts members in declaration order.
*
* @group ReflectionAPI
@@ -27,23 +27,18 @@ trait Scopes { self: Universe =>
* @template
* @group Scopes
*/
- type Scope >: Null <: ScopeApi
+ type Scope >: Null <: AnyRef with ScopeApi
/** The API that all scopes support
* @group API
*/
trait ScopeApi extends Iterable[Symbol]
- /** Create a new scope with the given initial elements.
- * @group Scopes
- */
- def newScopeWith(elems: Symbol*): Scope
-
/** The type of member scopes, as in class definitions, for example.
* @template
* @group Scopes
*/
- type MemberScope >: Null <: Scope with MemberScopeApi
+ type MemberScope >: Null <: AnyRef with MemberScopeApi with Scope
/** The API that all member scopes support
* @group API
diff --git a/src/reflect/scala/reflect/api/StandardDefinitions.scala b/src/reflect/scala/reflect/api/StandardDefinitions.scala
index 1a8885e6b5..524b7ea14b 100644
--- a/src/reflect/scala/reflect/api/StandardDefinitions.scala
+++ b/src/reflect/scala/reflect/api/StandardDefinitions.scala
@@ -131,10 +131,10 @@ trait StandardDefinitions {
* scala> val m = typeOf[C].member(newTermName("m")).asMethod
* m: reflect.runtime.universe.MethodSymbol = method m
*
- * scala> m.params(0)(0).typeSignature
+ * scala> m.params(0)(0).info
* res1: reflect.runtime.universe.Type = => scala.Int
*
- * scala> showRaw(m.params(0)(0).typeSignature)
+ * scala> showRaw(m.params(0)(0).info)
* res2: String = TypeRef(
* ThisType(scala),
* scala.<byname>, // <-- ByNameParamClass
@@ -159,10 +159,10 @@ trait StandardDefinitions {
* scala> val m = typeOf[C].member(newTermName("m")).asMethod
* m: reflect.runtime.universe.MethodSymbol = method m
*
- * scala> m.params(0)(0).typeSignature
+ * scala> m.params(0)(0).info
* res1: reflect.runtime.universe.Type = <repeated...>[Object]
*
- * scala> showRaw(m.params(0)(0).typeSignature)
+ * scala> showRaw(m.params(0)(0).info)
* res2: String = TypeRef(
* ThisType(scala),
* scala.<repeated...>, // <-- JavaRepeatedParamClass
@@ -184,10 +184,10 @@ trait StandardDefinitions {
* scala> val m = typeOf[C].member(newTermName("m")).asMethod
* m: reflect.runtime.universe.MethodSymbol = method m
*
- * scala> m.params(0)(0).typeSignature
+ * scala> m.params(0)(0).info
* res1: reflect.runtime.universe.Type = scala.Int*
*
- * scala> showRaw(m.params(0)(0).typeSignature)
+ * scala> showRaw(m.params(0)(0).info)
* res2: String = TypeRef(
* ThisType(scala),
* scala.<repeated>, // <-- RepeatedParamClass
diff --git a/src/reflect/scala/reflect/api/StandardLiftables.scala b/src/reflect/scala/reflect/api/StandardLiftables.scala
index f89630a938..af11de46ce 100644
--- a/src/reflect/scala/reflect/api/StandardLiftables.scala
+++ b/src/reflect/scala/reflect/api/StandardLiftables.scala
@@ -2,13 +2,14 @@ package scala.reflect
package api
trait StandardLiftables { self: Universe =>
- import build.{SyntacticTuple, ScalaDot}
+ import internal._
+ import reificationSupport.{SyntacticTuple, ScalaDot}
trait StandardLiftableInstances {
private def lift[T: Liftable](value: T): Tree = implicitly[Liftable[T]].apply(value)
private def selectScala(names: Name*) = names.tail.foldLeft(ScalaDot(names.head)) { Select(_, _) }
private def callScala(names: Name*)(args: List[Tree]) = Apply(selectScala(names: _*), args)
- private def callCollection(name: Name)(args: List[Tree]) = callScala(nme.collection, nme.immutable, name)(args)
+ private def callCollection(name: Name)(args: List[Tree]) = callScala(stdnme.collection, stdnme.immutable, name)(args)
private def liftAsLiteral[T]: Liftable[T] = Liftable { v => Literal(Constant(v)) }
implicit def liftByte[T <: Byte]: Liftable[T] = liftAsLiteral[T]
@@ -23,7 +24,7 @@ trait StandardLiftables { self: Universe =>
implicit def liftString[T <: String]: Liftable[T] = liftAsLiteral[T]
implicit def liftScalaSymbol: Liftable[scala.Symbol] = Liftable { v =>
- callScala(nme.Symbol)(Literal(Constant(v.name)) :: Nil)
+ callScala(stdnme.Symbol)(Literal(Constant(v.name)) :: Nil)
}
implicit def liftName[T <: Name]: Liftable[T] = Liftable { name => Ident(name) }
@@ -32,22 +33,22 @@ trait StandardLiftables { self: Universe =>
implicit def liftTypeTag[T <: WeakTypeTag[_]]: Liftable[T] = Liftable { ttag => TypeTree(ttag.tpe) }
implicit def liftConstant[T <: Constant]: Liftable[T] = Liftable { const => Literal(const) }
- implicit def liftArray[T: Liftable]: Liftable[Array[T]] = Liftable { arr => callScala(nme.Array)(arr.map(lift(_)).toList) }
- implicit def liftVector[T: Liftable]: Liftable[Vector[T]] = Liftable { vect => callCollection(nme.Vector)(vect.map(lift(_)).toList) }
- implicit def liftList[T: Liftable]: Liftable[List[T]] = Liftable { lst => callCollection(nme.List)(lst.map(lift(_))) }
- implicit def liftNil: Liftable[Nil.type] = Liftable { _ => selectScala(nme.collection, nme.immutable, nme.Nil) }
- implicit def liftMap[K: Liftable, V: Liftable]: Liftable[Map[K, V]] = Liftable { m => callCollection(nme.Map)(m.toList.map(lift(_))) }
- implicit def liftSet[T: Liftable]: Liftable[Set[T]] = Liftable { s => callCollection(nme.Set)(s.toList.map(lift(_))) }
+ implicit def liftArray[T: Liftable]: Liftable[Array[T]] = Liftable { arr => callScala(stdnme.Array)(arr.map(lift(_)).toList) }
+ implicit def liftVector[T: Liftable]: Liftable[Vector[T]] = Liftable { vect => callCollection(stdnme.Vector)(vect.map(lift(_)).toList) }
+ implicit def liftList[T: Liftable]: Liftable[List[T]] = Liftable { lst => callCollection(stdnme.List)(lst.map(lift(_))) }
+ implicit def liftNil: Liftable[Nil.type] = Liftable { _ => selectScala(stdnme.collection, stdnme.immutable, stdnme.Nil) }
+ implicit def liftMap[K: Liftable, V: Liftable]: Liftable[Map[K, V]] = Liftable { m => callCollection(stdnme.Map)(m.toList.map(lift(_))) }
+ implicit def liftSet[T: Liftable]: Liftable[Set[T]] = Liftable { s => callCollection(stdnme.Set)(s.toList.map(lift(_))) }
- implicit def liftSome[T: Liftable]: Liftable[Some[T]] = Liftable { case Some(v) => callScala(nme.Some)(lift(v) :: Nil) }
- implicit def liftNone: Liftable[None.type] = Liftable { _ => selectScala(nme.None) }
+ implicit def liftSome[T: Liftable]: Liftable[Some[T]] = Liftable { case Some(v) => callScala(stdnme.Some)(lift(v) :: Nil) }
+ implicit def liftNone: Liftable[None.type] = Liftable { _ => selectScala(stdnme.None) }
implicit def liftOption[T: Liftable]: Liftable[Option[T]] = Liftable {
case some: Some[T] => lift(some)
case none: None.type => lift(none)
}
- implicit def liftLeft[L: Liftable, R]: Liftable[Left[L, R]] = Liftable { case Left(v) => callScala(nme.util, nme.Left)(lift(v) :: Nil) }
- implicit def liftRight[L, R: Liftable]: Liftable[Right[L, R]] = Liftable { case Right(v) => callScala(nme.util, nme.Right)(lift(v) :: Nil) }
+ implicit def liftLeft[L: Liftable, R]: Liftable[Left[L, R]] = Liftable { case Left(v) => callScala(stdnme.util, stdnme.Left)(lift(v) :: Nil) }
+ implicit def liftRight[L, R: Liftable]: Liftable[Right[L, R]] = Liftable { case Right(v) => callScala(stdnme.util, stdnme.Right)(lift(v) :: Nil) }
implicit def liftEither[L: Liftable, R: Liftable]: Liftable[Either[L, R]] = Liftable {
case left: Left[L, R] => lift(left)
case right: Right[L, R] => lift(right)
@@ -137,10 +138,10 @@ trait StandardLiftables { self: Universe =>
implicit def unliftString: Unliftable[String] = Unliftable { case Literal(Constant(s: String)) => s }
implicit def unliftScalaSymbol: Unliftable[scala.Symbol] = Unliftable {
- case Apply(ScalaDot(symbol), List(Literal(Constant(name: String)))) if symbol == nme.Symbol => scala.Symbol(name)
+ case Apply(ScalaDot(stdnme.Symbol), List(Literal(Constant(name: String)))) => scala.Symbol(name)
}
- implicit def unliftName[T <: Name : ClassTag]: Unliftable[T] = Unliftable[T] { case Ident(name: T) => name; case Bind(name: T, Ident(nme.WILDCARD)) => name }
+ implicit def unliftName[T <: Name : ClassTag]: Unliftable[T] = Unliftable[T] { case Ident(name: T) => name; case Bind(name: T, Ident(stdnme.WILDCARD)) => name }
implicit def unliftType: Unliftable[Type] = Unliftable[Type] { case tt: TypeTree if tt.tpe != null => tt.tpe }
implicit def unliftConstant: Unliftable[Constant] = Unliftable[Constant] { case Literal(const) => const }
@@ -210,9 +211,10 @@ trait StandardLiftables { self: Universe =>
}
// names used internally by implementations of standard liftables and unliftables
- import scala.language.implicitConversions
- private implicit def cachedNames(nme: self.nme.type): CachedNames.type = CachedNames
- private object CachedNames {
+ // can't be `private object nme` because of https://groups.google.com/forum/#!topic/scala-internals/b-Full9WZeE
+ // can't be `private[this] object nme` because then STARR has problems prioritizing this.nme over self.nme
+ // therefore I'm essentially forced to give this object a non-standard name
+ private object stdnme {
val Array = TermName("Array")
val collection = TermName("collection")
val immutable = TermName("immutable")
@@ -225,7 +227,8 @@ trait StandardLiftables { self: Universe =>
val Set = TermName("Set")
val Some = TermName("Some")
val Symbol = TermName("Symbol")
- val Vector = TermName("Vector")
val util = TermName("util")
+ val Vector = TermName("Vector")
+ val WILDCARD = self.nme.WILDCARD
}
}
diff --git a/src/reflect/scala/reflect/api/StandardNames.scala b/src/reflect/scala/reflect/api/StandardNames.scala
index aec5f19fa0..19bdfcae59 100644
--- a/src/reflect/scala/reflect/api/StandardNames.scala
+++ b/src/reflect/scala/reflect/api/StandardNames.scala
@@ -28,15 +28,23 @@ package api
trait StandardNames {
self: Universe =>
+ /** @see [[termNames]] */
+ @deprecated("Use `termNames` instead", "2.11.0")
+ val nme: TermNamesApi
+
/** A value containing all [[TermNamesApi standard term names]].
* @group StandardNames
*/
- val nme: TermNamesApi
+ val termNames: TermNamesApi
+
+ /** @see [[typeNames]] */
+ @deprecated("Use `typeNames` instead", "2.11.0")
+ val tpnme: TypeNamesApi
/** A value containing all [[TypeNamesApi standard type names]].
* @group StandardNames
*/
- val tpnme: TypeNamesApi
+ val typeNames: TypeNamesApi
/** Defines standard names, common for term and type names: These can be accessed via the [[nme]] and [[tpnme]] members.
* @group API
diff --git a/src/reflect/scala/reflect/api/Symbols.scala b/src/reflect/scala/reflect/api/Symbols.scala
index 1250545497..a5a50f1088 100644
--- a/src/reflect/scala/reflect/api/Symbols.scala
+++ b/src/reflect/scala/reflect/api/Symbols.scala
@@ -30,7 +30,7 @@ package api
* scala> val test = typeOf[C[Int]].member(newTermName("test")).asMethod
* test: reflect.runtime.universe.MethodSymbol = method test
*
- * scala> test.typeSignature
+ * scala> test.info
* res0: reflect.runtime.universe.Type = [U](x: T)(y: U)scala.Int
* }}}
*
@@ -60,51 +60,39 @@ trait Symbols { self: Universe =>
* @group Symbols
* @template
*/
- type Symbol >: Null <: SymbolApi
+ type Symbol >: Null <: AnyRef with SymbolApi
/** The type of type symbols representing type, class, and trait declarations,
* as well as type parameters.
* @group Symbols
* @template
*/
- type TypeSymbol >: Null <: Symbol with TypeSymbolApi
+ type TypeSymbol >: Null <: TypeSymbolApi with Symbol
/** The type of term symbols representing val, var, def, and object declarations as
* well as packages and value parameters.
* @group Symbols
* @template
*/
- type TermSymbol >: Null <: Symbol with TermSymbolApi
+ type TermSymbol >: Null <: TermSymbolApi with Symbol
/** The type of method symbols representing def declarations.
* @group Symbols
* @template
*/
- type MethodSymbol >: Null <: TermSymbol with MethodSymbolApi
+ type MethodSymbol >: Null <: MethodSymbolApi with TermSymbol
/** The type of module symbols representing object declarations.
* @group Symbols
* @template
*/
- type ModuleSymbol >: Null <: TermSymbol with ModuleSymbolApi
+ type ModuleSymbol >: Null <: ModuleSymbolApi with TermSymbol
/** The type of class symbols representing class and trait definitions.
* @group Symbols
* @template
*/
- type ClassSymbol >: Null <: TypeSymbol with ClassSymbolApi
-
- /** The type of free terms introduced by reification.
- * @group Symbols
- * @template
- */
- type FreeTermSymbol >: Null <: TermSymbol with FreeTermSymbolApi
-
- /** The type of free types introduced by reification.
- * @group Symbols
- * @template
- */
- type FreeTypeSymbol >: Null <: TypeSymbol with FreeTypeSymbolApi
+ type ClassSymbol >: Null <: ClassSymbolApi with TypeSymbol
/** A special "missing" symbol. Commonly used in the API to denote a default or empty value.
* @group Symbols
@@ -131,12 +119,8 @@ trait Symbols { self: Universe =>
* @groupdesc Helpers These methods enable collections-like operations on symbols.
* @groupname Type TypeSymbol Members
* @groupprio Type -1
- * @groupname FreeType FreeType Symbol Members
- * @groupprio FreeType -2
* @groupname Term TermSymbol Members
* @groupprio Term -1
- * @groupname FreeTerm FreeTerm Symbol Members
- * @groupprio FreeTerm -2
* @groupname Class Class Symbol Members
* @groupprio Class -2
* @groupname Method Method Symbol Members
@@ -171,7 +155,7 @@ trait Symbols { self: Universe =>
/** The name of the symbol as a member of the `Name` type.
* @group Basics
*/
- def name: Name
+ def name: NameType
/** The encoded full path name of this symbol, where outer names and inner names
* are separated by periods.
@@ -179,6 +163,9 @@ trait Symbols { self: Universe =>
*/
def fullName: String
+ /** Position of the tree. */
+ def pos: Position
+
/** Does this symbol represent the definition of a type?
* Note that every symbol is either a term or a type.
* So for every symbol `sym` (except for `NoSymbol`),
@@ -218,6 +205,15 @@ trait Symbols { self: Universe =>
*/
def isMethod: Boolean = false
+ /** Does this method represent a constructor?
+ *
+ * If `owner` is a class, then this is a vanilla JVM constructor.
+ * If `owner` is a trait, then this is a mixin constructor.
+ *
+ * @group Method
+ */
+ def isConstructor: Boolean
+
/** This symbol cast to a MethodSymbol.
* @throws ScalaReflectionException if `isMethod` is false.
*
@@ -275,45 +271,6 @@ trait Symbols { self: Universe =>
*/
def asClass: ClassSymbol = throw new ScalaReflectionException(s"$this is not a class")
- /** Does this symbol represent a free term captured by reification?
- * If yes, `isTerm` is also guaranteed to be true.
- *
- * @group Tests
- */
- def isFreeTerm: Boolean = false
-
- /** This symbol cast to a free term symbol.
- * @throws ScalaReflectionException if `isFreeTerm` is false.
- *
- * @group Conversions
- */
- def asFreeTerm: FreeTermSymbol = throw new ScalaReflectionException(s"$this is not a free term")
-
- /** Does this symbol represent a free type captured by reification?
- * If yes, `isType` is also guaranteed to be true.
- *
- * @group Tests
- */
- def isFreeType: Boolean = false
-
- /** This symbol cast to a free type symbol.
- * @throws ScalaReflectionException if `isFreeType` is false.
- *
- * @group Conversions
- */
- def asFreeType: FreeTypeSymbol = throw new ScalaReflectionException(s"$this is not a free type")
-
- /** @group Constructors */
- def newTermSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TermSymbol
- /** @group Constructors */
- def newModuleAndClassSymbol(name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol)
- /** @group Constructors */
- def newMethodSymbol(name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): MethodSymbol
- /** @group Constructors */
- def newTypeSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TypeSymbol
- /** @group Constructors */
- def newClassSymbol(name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): ClassSymbol
-
/** 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.
*
@@ -323,6 +280,7 @@ trait Symbols { self: Universe =>
*
* @group Basics
*/
+ @deprecated("Use `pos.source.file` instead", "2.11.0")
def associatedFile: scala.reflect.io.AbstractFile
/** A list of annotations attached to this Symbol.
@@ -335,15 +293,32 @@ trait Symbols { self: Universe =>
* For a module: the class with the same name in the same package.
* For all others: NoSymbol
*
+ * This API may return unexpected results for module classes, packages and package classes.
+ * Use `companion` instead in order to get predictable results.
+ *
* @group Basics
*/
+ @deprecated("Use `companion` instead, but beware of possible changes in behavior", "2.11.0")
def companionSymbol: Symbol
+ /** For a class: its companion object if exists.
+ * For a module or a module class: companion class of the module if exists.
+ * For a package or a package class: NoSymbol.
+ * For all others: NoSymbol.
+ */
+ def companion: Symbol
+
+ /** @see [[infoIn]] */
+ def typeSignatureIn(site: Type): Type
+
/** The type signature of this symbol seen as a member of given type `site`.
*
* @group Basics
*/
- def typeSignatureIn(site: Type): Type
+ def infoIn(site: Type): Type
+
+ /** @see [[info]] */
+ def typeSignature: Type
/** The type signature of this symbol.
*
@@ -351,17 +326,27 @@ trait Symbols { self: Universe =>
* instantiation of a generic type. For example, signature
* of the method `def map[B](f: (A) ⇒ B): List[B]`, which refers to the type parameter `A` of the declaring class `List[A]`,
* will always feature `A`, regardless of whether `map` is loaded from the `List[_]` or from `List[Int]`. To get a signature
- * with type parameters appropriately instantiated, one should use `typeSignatureIn`.
+ * with type parameters appropriately instantiated, one should use `infoIn`.
*
* @group Basics
*/
- def typeSignature: Type
+ def info: Type
+
+ /** @see [[overrides]] */
+ @deprecated("Use `overrides` instead", "2.11.0")
+ def allOverriddenSymbols: List[Symbol]
/** Returns all symbols overriden by this symbol.
*
* @group Basics
*/
- def allOverriddenSymbols: List[Symbol]
+ def overrides: List[Symbol]
+
+ /** The overloaded alternatives of this symbol
+ *
+ * @group Basics
+ */
+ def alternatives: List[Symbol]
/******************* tests *******************/
@@ -380,16 +365,13 @@ trait Symbols { self: Universe =>
*/
def isImplementationArtifact: Boolean
- /** Does this symbol represent a local declaration or definition?
- *
- * If yes, either `isPrivate` or `isProtected` are guaranteed to be true.
- * Local symbols can only be accessed from the same object instance.
- *
- * If yes, `privateWithin` might tell more about this symbol's visibility scope.
+ /** Does this symbol represent a declaration or definition written in a source file as `private[this]`
+ * or generated in tree/symbol form with the combination of flags LOCAL and PRIVATE?
+ * If yes, `isPrivate` is guaranteed to be true,
*
* @group Tests
*/
- def isLocal: Boolean
+ def isPrivateThis: Boolean
/** Does this symbol represent a private declaration or definition?
* If yes, `privateWithin` might tell more about this symbol's visibility scope.
@@ -398,6 +380,14 @@ trait Symbols { self: Universe =>
*/
def isPrivate: Boolean
+ /** Does this symbol represent a declaration or definition written in a source file as `protected[this]`
+ * or generated in tree/symbol form with the combination of flags LOCAL and PROTECTED?
+ * If yes, `isProtected` is guaranteed to be true,
+ *
+ * @group Tests
+ */
+ def isProtectedThis: Boolean
+
/** Does this symbol represent a protected declaration or definition?
* If yes, `privateWithin` might tell more about this symbol's visibility scope.
*
@@ -412,7 +402,7 @@ trait Symbols { self: Universe =>
def isPublic: Boolean
/**
- * Set when symbol has a modifier of the form private[X], NoSymbol otherwise.
+ * Set when symbol has a modifier of the form private[X] or protected[X], NoSymbol otherwise.
*
* Access level encoding: there are three scala flags (PRIVATE, PROTECTED,
* and LOCAL) which combine with value privateWithin (the "foo" in private[foo])
@@ -441,7 +431,7 @@ trait Symbols { self: Universe =>
def privateWithin: Symbol
/** Does this symbol represent the definition of a package?
- * If yes, `isTerm` is also guaranteed to be true.
+ * Known issues: [[https://issues.scala-lang.org/browse/SI-6732]].
*
* @group Tests
*/
@@ -454,12 +444,6 @@ trait Symbols { self: Universe =>
*/
def isPackageClass: Boolean
- /** Does this symbol or its underlying type represent a typechecking error?
- *
- * @group Tests
- */
- def isErroneous : Boolean
-
/** Is this symbol static (i.e. with no outer instance)?
* Q: When exactly is a sym marked as STATIC?
* A: If it's a member of a toplevel object, or of an object contained in a toplevel object, or any number of levels deep.
@@ -475,11 +459,11 @@ trait Symbols { self: Universe =>
*/
def isFinal: Boolean
- /** Is this symbol overriding something?
+ /** Is this symbol abstract (i.e. an abstract class, an abstract method, value or type member)?
*
* @group Tests
*/
- def isOverride: Boolean
+ def isAbstract: Boolean
/** Is this symbol labelled as "abstract override"?
*
@@ -613,12 +597,6 @@ trait Symbols { self: Universe =>
*/
def isLazy: Boolean
- /** The overloaded alternatives of this symbol
- *
- * @group Term
- */
- def alternatives: List[Symbol]
-
/** Used to provide a better error message for `asMethod` */
override protected def isOverloadedMethod = alternatives exists (_.isMethod)
@@ -704,7 +682,7 @@ trait Symbols { self: Universe =>
* Example: Given a class declaration `class C[T] { ... } `, that generates a symbol
* `C`. Then `C.toType` is the type `C[T]`.
*
- * By contrast, `C.typeSignature` would be a type signature of form
+ * By contrast, `C.info` would be a type signature of form
* `PolyType(ClassInfoType(...))` that describes type parameters, value
* parameters, parent types, and members of `C`.
*
@@ -727,13 +705,6 @@ trait Symbols { self: Universe =>
*/
def isCovariant : Boolean
- /** Does this symbol represent the definition of a skolem?
- * Skolems are used during typechecking to represent type parameters viewed from inside their scopes.
- *
- * @group Type
- */
- def isSkolem : Boolean
-
/** Does this symbol represent the definition of a type alias?
*
* @group Type
@@ -744,6 +715,7 @@ trait Symbols { self: Universe =>
*
* @group Type
*/
+ @deprecated("Use isAbstract instead", "2.11.0")
def isAbstractType : Boolean
/** Does this symbol represent an existentially bound type?
@@ -769,15 +741,6 @@ trait Symbols { self: Universe =>
final override def isMethod = true
final override def asMethod = this
- /** Does this method represent a constructor?
- *
- * If `owner` is a class, then this is a vanilla JVM constructor.
- * If `owner` is a trait, then this is a mixin constructor.
- *
- * @group Method
- */
- def isConstructor: Boolean
-
/** Does this symbol denote the primary constructor of its enclosing class?
*
* @group Method
@@ -790,6 +753,10 @@ trait Symbols { self: Universe =>
*/
def typeParams: List[Symbol]
+ /** @see [[paramLists]] */
+ @deprecated("Use `paramLists` instead", "2.11.0")
+ def paramss: List[List[Symbol]]
+
/** All parameter lists of the method.
* The name ending with "ss" indicates that the result type is a list of lists.
*
@@ -799,7 +766,7 @@ trait Symbols { self: Universe =>
*
* @group Method
*/
- def paramss: List[List[Symbol]]
+ def paramLists: List[List[Symbol]]
/** Does this method support variable length argument lists?
*
@@ -812,6 +779,14 @@ trait Symbols { self: Universe =>
* @group Method
*/
def returnType: Type
+
+ /** Exceptions that this method is known to throw.
+ * For Scala methods, the list is calculated from [[throws]] annotations present on a method.
+ * For Java methods, the list is calculated from `throws` clauses attached to the method and stored in bytecode.
+ *
+ * @group Method
+ */
+ def exceptions: List[Symbol]
}
/** The API of module symbols.
@@ -877,6 +852,7 @@ trait Symbols { self: Universe =>
*
* @group Class
*/
+ @deprecated("Use isAbstract instead", "2.11.0")
def isAbstractClass: Boolean
/** Does this symbol represent a case class?
@@ -926,50 +902,29 @@ trait Symbols { self: Universe =>
*/
def thisPrefix: Type
- /** For a polymorphic class/trait, its type parameters, the empty list for all other classes/trait
+ /** The type `C.super[M]`, where `C` is the current class and `M` is supertpe.
*
* @group Class
*/
- def typeParams: List[Symbol]
- }
-
- /** The API of free term symbols.
- * The main source of information about symbols is the [[Symbols]] page.
- *
- * $SYMACCESSORS
- * @group API
- */
- trait FreeTermSymbolApi extends TermSymbolApi { this: FreeTermSymbol =>
- final override def isFreeTerm = true
- final override def asFreeTerm = this
+ def superPrefix(supertpe: Type): Type
- /** The place where this symbol has been spawned
- *
- * @group FreeTerm
- */
- def origin: String
-
- /** The valus this symbol refers to
+ /** For a polymorphic class/trait, its type parameters, the empty list for all other classes/trait
*
- * @group FreeTerm
+ * @group Class
*/
- def value: Any
- }
-
- /** The API of free type symbols.
- * The main source of information about symbols is the [[Symbols]] page.
- *
- * $SYMACCESSORS
- * @group API
- */
- trait FreeTypeSymbolApi extends TypeSymbolApi { this: FreeTypeSymbol =>
- final override def isFreeType = true
- final override def asFreeType = this
+ def typeParams: List[Symbol]
- /** The place where this symbol has been spawned
+ /** For a Scala class or module class, the primary constructor of the class.
+ * For a Scala trait, its mixin constructor.
+ * For a Scala package class, NoSymbol.
+ * For a Java class, NoSymbol.
*
- * @group FreeType
+ * @group Class
*/
- def origin: String
+ // TODO: SI-8193 I think we should only return a non-empty symbol if called for Scala classes
+ // returning something for traits and module classes is outright confusing
+ // This, however, will require some refactoring in the compiler, so I'll leave it for later
+ // as at the moment we don't have time or risk tolerance for that
+ def primaryConstructor: Symbol
}
}
diff --git a/src/reflect/scala/reflect/api/TagInterop.scala b/src/reflect/scala/reflect/api/TagInterop.scala
deleted file mode 100644
index 51b7c519c5..0000000000
--- a/src/reflect/scala/reflect/api/TagInterop.scala
+++ /dev/null
@@ -1,44 +0,0 @@
-package scala
-package reflect
-package api
-
-/**
- * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
- *
- * This trait provides type tag <-> manifest interoperability.
- * @group ReflectionAPI
- *
- * @groupname TagInterop TypeTag and Manifest Interoperability
- */
-trait TagInterop { self: Universe =>
- // TODO `mirror` parameters are now of type `Any`, because I can't make these path-dependent types work
- // if you're brave enough, replace `Any` with `Mirror`, recompile and run interop_typetags_are_manifests.scala
-
- /**
- * Convert a [[scala.reflect.api.TypeTags#TypeTag]] to a [[scala.reflect.Manifest]].
- *
- * Compiler usually generates these conversions automatically, when a type tag for a type `T` is in scope,
- * and an implicit of type `Manifest[T]` is requested, but this method can also be called manually.
- * For example:
- * {{{
- * typeTagToManifest(scala.reflect.runtime.currentMirror, implicitly[TypeTag[String]])
- * }}}
- * @group TagInterop
- */
- def typeTagToManifest[T: ClassTag](mirror: Any, tag: Universe#TypeTag[T]): Manifest[T] =
- throw new UnsupportedOperationException("This universe does not support tag -> manifest conversions. Use a JavaUniverse, e.g. the scala.reflect.runtime.universe.")
-
- /**
- * Convert a [[scala.reflect.Manifest]] to a [[scala.reflect.api.TypeTags#TypeTag]].
- *
- * Compiler usually generates these conversions automatically, when a manifest for a type `T` is in scope,
- * and an implicit of type `TypeTag[T]` is requested, but this method can also be called manually.
- * For example:
- * {{{
- * manifestToTypeTag(scala.reflect.runtime.currentMirror, implicitly[Manifest[String]])
- * }}}
- * @group TagInterop
- */
- def manifestToTypeTag[T](mirror: Any, manifest: Manifest[T]): Universe#TypeTag[T] =
- throw new UnsupportedOperationException("This universe does not support manifest -> tag conversions. Use a JavaUniverse, e.g. the scala.reflect.runtime.universe.")
-}
diff --git a/src/reflect/scala/reflect/api/Trees.scala b/src/reflect/scala/reflect/api/Trees.scala
index 60e00ca5fd..ff8926651b 100644
--- a/src/reflect/scala/reflect/api/Trees.scala
+++ b/src/reflect/scala/reflect/api/Trees.scala
@@ -59,7 +59,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Tree >: Null <: TreeApi
+ type Tree >: Null <: AnyRef with TreeApi
/** The API that all trees support.
* The main source of information about trees is the [[scala.reflect.api.Trees]] page.
@@ -168,29 +168,6 @@ trait Trees { self: Universe =>
*/
def children: List[Tree]
- /** Extracts free term symbols from a tree that is reified or contains reified subtrees.
- */
- def freeTerms: List[FreeTermSymbol]
-
- /** Extracts free type symbols from a tree that is reified or contains reified subtrees.
- */
- def freeTypes: List[FreeTypeSymbol]
-
- /** Substitute symbols in `to` for corresponding occurrences of references to
- * symbols `from` in this type.
- */
- def substituteSymbols(from: List[Symbol], to: List[Symbol]): Tree
-
- /** Substitute types in `to` for corresponding occurrences of references to
- * symbols `from` in this tree.
- */
- def substituteTypes(from: List[Symbol], to: List[Type]): Tree
-
- /** Substitute given tree `to` for occurrences of nodes that represent
- * `C.this`, where `C` referes to the given class `clazz`.
- */
- def substituteThis(clazz: Symbol, to: Tree): Tree
-
/** Make a copy of this tree, keeping all attributes,
* except that all positions are focused (so nothing
* in this tree will be found when searching by position).
@@ -216,7 +193,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type TermTree >: Null <: AnyRef with Tree with TermTreeApi
+ type TermTree >: Null <: TermTreeApi with Tree
/** The API that all term trees support
* @group API
@@ -229,7 +206,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type TypTree >: Null <: AnyRef with Tree with TypTreeApi
+ type TypTree >: Null <: TypTreeApi with Tree
/** The API that all typ trees support
* @group API
@@ -237,11 +214,14 @@ trait Trees { self: Universe =>
trait TypTreeApi extends TreeApi { this: TypTree =>
}
- /** A tree with a mutable symbol field, initialized to NoSymbol.
+ /** A tree that carries a symbol, e.g. by defining it (`DefTree`) or by referring to it (`RefTree`).
+ * Such trees start their life naked, returning `NoSymbol`, but after being typechecked without errors
+ * they hold non-empty symbols.
+ *
* @group Trees
* @template
*/
- type SymTree >: Null <: AnyRef with Tree with SymTreeApi
+ type SymTree >: Null <: SymTreeApi with Tree
/** The API that all sym trees support
* @group API
@@ -251,18 +231,18 @@ trait Trees { self: Universe =>
def symbol: Symbol
}
- /** A tree with a name - effectively, a DefTree or RefTree.
+ /** A tree that carries a name, e.g. by defining it (`DefTree`) or by referring to it (`RefTree`).
* @group Trees
* @template
*/
- type NameTree >: Null <: AnyRef with Tree with NameTreeApi
+ type NameTree >: Null <: NameTreeApi with Tree
/** The API that all name trees support
* @group API
*/
trait NameTreeApi extends TreeApi { this: NameTree =>
/** The underlying name.
- * For example, the `<List>` part of `Ident("List": TermName)`.
+ * For example, the `List` part of `Ident(TermName("List"))`.
*/
def name: Name
}
@@ -273,14 +253,14 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type RefTree >: Null <: SymTree with NameTree with RefTreeApi
+ type RefTree >: Null <: RefTreeApi with SymTree with NameTree
/** The API that all ref trees support
* @group API
*/
trait RefTreeApi extends SymTreeApi with NameTreeApi { this: RefTree =>
/** The qualifier of the reference.
- * For example, the `<scala>` part of `Select("scala": TermName, "List": TermName)`.
+ * For example, the `Ident(TermName("scala"))` part of `Select(Ident(TermName("scala")), TermName("List"))`.
* `EmptyTree` for `Ident` instances.
*/
def qualifier: Tree
@@ -303,11 +283,14 @@ trait Trees { self: Universe =>
def unapply(refTree: RefTree): Option[(Tree, Name)]
}
- /** A tree which defines a symbol-carrying entity.
+ /** A tree representing a symbol-defining entity:
+ * 1) A declaration or a definition (type, class, object, package, val, var, or def)
+ * 2) `Bind` that is used to represent binding occurrences in pattern matches
+ * 3) `LabelDef` that is used internally to represent while loops
* @group Trees
* @template
*/
- type DefTree >: Null <: SymTree with NameTree with DefTreeApi
+ type DefTree >: Null <: DefTreeApi with SymTree with NameTree
/** The API that all def trees support
* @group API
@@ -322,7 +305,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type MemberDef >: Null <: DefTree with MemberDefApi
+ type MemberDef >: Null <: MemberDefApi with DefTree
/** The API that all member defs support
* @group API
@@ -336,7 +319,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type PackageDef >: Null <: MemberDef with PackageDefApi
+ type PackageDef >: Null <: PackageDefApi with MemberDef
/** The constructor/extractor for `PackageDef` instances.
* @group Extractors
@@ -369,7 +352,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type ImplDef >: Null <: MemberDef with ImplDefApi
+ type ImplDef >: Null <: ImplDefApi with MemberDef
/** The API that all impl defs support
* @group API
@@ -383,7 +366,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type ClassDef >: Null <: ImplDef with ClassDefApi
+ type ClassDef >: Null <: ClassDefApi with ImplDef
/** The constructor/extractor for `ClassDef` instances.
* @group Extractors
@@ -403,6 +386,10 @@ trait Trees { self: Universe =>
abstract class ClassDefExtractor {
def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template): ClassDef
def unapply(classDef: ClassDef): Option[(Modifiers, TypeName, List[TypeDef], Template)]
+
+ /** @see [[InternalApi.classDef]] */
+ @deprecated("Use `internal.classDef` instead", "2.11.0")
+ def apply(sym: Symbol, impl: Template)(implicit token: CompatToken): ClassDef = internal.classDef(sym, impl)
}
/** The API that all class defs support
@@ -428,7 +415,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type ModuleDef >: Null <: ImplDef with ModuleDefApi
+ type ModuleDef >: Null <: ModuleDefApi with ImplDef
/** The constructor/extractor for `ModuleDef` instances.
* @group Extractors
@@ -448,6 +435,10 @@ trait Trees { self: Universe =>
abstract class ModuleDefExtractor {
def apply(mods: Modifiers, name: TermName, impl: Template): ModuleDef
def unapply(moduleDef: ModuleDef): Option[(Modifiers, TermName, Template)]
+
+ /** @see [[InternalApi.moduleDef]] */
+ @deprecated("Use `internal.moduleDef` instead", "2.11.0")
+ def apply(sym: Symbol, impl: Template)(implicit token: CompatToken): ModuleDef = internal.moduleDef(sym, impl)
}
/** The API that all module defs support
@@ -468,14 +459,14 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type ValOrDefDef >: Null <: MemberDef with ValOrDefDefApi
+ type ValOrDefDef >: Null <: ValOrDefDefApi with MemberDef
/** The API that all val defs and def defs support
* @group API
*/
trait ValOrDefDefApi extends MemberDefApi { this: ValOrDefDef =>
/** @inheritdoc */
- def name: Name // can't be a TermName because macros can be type names.
+ def name: TermName
/** The type ascribed to the definition.
* An empty `TypeTree` if the type hasn't been specified explicitly
@@ -499,7 +490,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type ValDef >: Null <: ValOrDefDef with ValDefApi
+ type ValDef >: Null <: ValDefApi with ValOrDefDef
/** The constructor/extractor for `ValDef` instances.
* @group Extractors
@@ -524,6 +515,14 @@ trait Trees { self: Universe =>
abstract class ValDefExtractor {
def apply(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree): ValDef
def unapply(valDef: ValDef): Option[(Modifiers, TermName, Tree, Tree)]
+
+ /** @see [[InternalApi.valDef]] */
+ @deprecated("Use `internal.valDef` instead", "2.11.0")
+ def apply(sym: Symbol, rhs: Tree)(implicit token: CompatToken): ValDef = internal.valDef(sym, rhs)
+
+ /** @see [[InternalApi.valDef]] */
+ @deprecated("Use `internal.valDef` instead", "2.11.0")
+ def apply(sym: Symbol)(implicit token: CompatToken): ValDef = internal.valDef(sym)
}
/** The API that all val defs support
@@ -548,7 +547,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type DefDef >: Null <: ValOrDefDef with DefDefApi
+ type DefDef >: Null <: DefDefApi with ValOrDefDef
/** The constructor/extractor for `DefDef` instances.
* @group Extractors
@@ -567,6 +566,26 @@ trait Trees { self: Universe =>
abstract class DefDefExtractor {
def apply(mods: Modifiers, name: TermName, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef
def unapply(defDef: DefDef): Option[(Modifiers, TermName, List[TypeDef], List[List[ValDef]], Tree, Tree)]
+
+ /** @see [[InternalApi.defDef]] */
+ @deprecated("Use `internal.defDef` instead", "2.11.0")
+ def apply(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree)(implicit token: CompatToken): DefDef = internal.defDef(sym, mods, vparamss, rhs)
+
+ /** @see [[InternalApi.defDef]] */
+ @deprecated("Use `internal.defDef` instead", "2.11.0")
+ def apply(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree)(implicit token: CompatToken): DefDef = internal.defDef(sym, vparamss, rhs)
+
+ /** @see [[InternalApi.defDef]] */
+ @deprecated("Use `internal.defDef` instead", "2.11.0")
+ def apply(sym: Symbol, mods: Modifiers, rhs: Tree)(implicit token: CompatToken): DefDef = internal.defDef(sym, mods, rhs)
+
+ /** @see [[InternalApi.defDef]] */
+ @deprecated("Use `internal.defDef` instead", "2.11.0")
+ def apply(sym: Symbol, rhs: Tree)(implicit token: CompatToken): DefDef = internal.defDef(sym, rhs)
+
+ /** @see [[InternalApi.defDef]] */
+ @deprecated("Use `internal.defDef` instead", "2.11.0")
+ def apply(sym: Symbol, rhs: List[List[Symbol]] => Tree)(implicit token: CompatToken): DefDef = internal.defDef(sym, rhs)
}
/** The API that all def defs support
@@ -597,7 +616,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type TypeDef >: Null <: MemberDef with TypeDefApi
+ type TypeDef >: Null <: TypeDefApi with MemberDef
/** The constructor/extractor for `TypeDef` instances.
* @group Extractors
@@ -619,6 +638,14 @@ trait Trees { self: Universe =>
abstract class TypeDefExtractor {
def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree): TypeDef
def unapply(typeDef: TypeDef): Option[(Modifiers, TypeName, List[TypeDef], Tree)]
+
+ /** @see [[InternalApi.typeDef]] */
+ @deprecated("Use `internal.typeDef` instead", "2.11.0")
+ def apply(sym: Symbol, rhs: Tree)(implicit token: CompatToken): TypeDef = internal.typeDef(sym, rhs)
+
+ /** @see [[InternalApi.typeDef]] */
+ @deprecated("Use `internal.typeDef` instead", "2.11.0")
+ def apply(sym: Symbol)(implicit token: CompatToken): TypeDef = internal.typeDef(sym)
}
/** The API that all type defs support
@@ -656,7 +683,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type LabelDef >: Null <: DefTree with TermTree with LabelDefApi
+ type LabelDef >: Null <: LabelDefApi with DefTree with TermTree
/** The constructor/extractor for `LabelDef` instances.
* @group Extractors
@@ -679,6 +706,10 @@ trait Trees { self: Universe =>
abstract class LabelDefExtractor {
def apply(name: TermName, params: List[Ident], rhs: Tree): LabelDef
def unapply(labelDef: LabelDef): Option[(TermName, List[Ident], Tree)]
+
+ /** @see [[InternalApi.labelDef]] */
+ @deprecated("Use `internal.labelDef` instead", "2.11.0")
+ def apply(sym: Symbol, params: List[Symbol], rhs: Tree)(implicit token: CompatToken): LabelDef = internal.labelDef(sym, params, rhs)
}
/** The API that all label defs support
@@ -699,7 +730,7 @@ trait Trees { self: Universe =>
def rhs: Tree
}
- /** Import selector
+ /** Import selector (not a tree, but a component of the `Import` tree)
*
* Representation of an imported name its optional rename and their optional positions
*
@@ -758,7 +789,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Import >: Null <: SymTree with ImportApi
+ type Import >: Null <: ImportApi with SymTree
/** The constructor/extractor for `Import` instances.
* @group Extractors
@@ -810,7 +841,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Template >: Null <: SymTree with TemplateApi
+ type Template >: Null <: TemplateApi with SymTree
/** The constructor/extractor for `Template` instances.
* @group Extractors
@@ -862,7 +893,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Block >: Null <: TermTree with BlockApi
+ type Block >: Null <: BlockApi with TermTree
/** The constructor/extractor for `Block` instances.
* @group Extractors
@@ -901,7 +932,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type CaseDef >: Null <: AnyRef with Tree with CaseDefApi
+ type CaseDef >: Null <: CaseDefApi with Tree
/** The constructor/extractor for `CaseDef` instances.
* @group Extractors
@@ -948,7 +979,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Alternative >: Null <: TermTree with AlternativeApi
+ type Alternative >: Null <: AlternativeApi with TermTree
/** The constructor/extractor for `Alternative` instances.
* @group Extractors
@@ -980,7 +1011,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Star >: Null <: TermTree with StarApi
+ type Star >: Null <: StarApi with TermTree
/** The constructor/extractor for `Star` instances.
* @group Extractors
@@ -1015,7 +1046,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Bind >: Null <: DefTree with BindApi
+ type Bind >: Null <: BindApi with DefTree
/** The constructor/extractor for `Bind` instances.
* @group Extractors
@@ -1078,7 +1109,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type UnApply >: Null <: TermTree with UnApplyApi
+ type UnApply >: Null <: UnApplyApi with TermTree
/** The constructor/extractor for `UnApply` instances.
* @group Extractors
@@ -1114,7 +1145,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Function >: Null <: TermTree with SymTree with FunctionApi
+ type Function >: Null <: FunctionApi with TermTree with SymTree
/** The constructor/extractor for `Function` instances.
* @group Extractors
@@ -1152,7 +1183,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Assign >: Null <: TermTree with AssignApi
+ type Assign >: Null <: AssignApi with TermTree
/** The constructor/extractor for `Assign` instances.
* @group Extractors
@@ -1188,7 +1219,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type AssignOrNamedArg >: Null <: TermTree with AssignOrNamedArgApi
+ type AssignOrNamedArg >: Null <: AssignOrNamedArgApi with TermTree
/** The constructor/extractor for `AssignOrNamedArg` instances.
* @group Extractors
@@ -1229,7 +1260,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type If >: Null <: TermTree with IfApi
+ type If >: Null <: IfApi with TermTree
/** The constructor/extractor for `If` instances.
* @group Extractors
@@ -1280,7 +1311,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Match >: Null <: TermTree with MatchApi
+ type Match >: Null <: MatchApi with TermTree
/** The constructor/extractor for `Match` instances.
* @group Extractors
@@ -1315,7 +1346,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Return >: Null <: TermTree with SymTree with ReturnApi
+ type Return >: Null <: ReturnApi with SymTree with TermTree
/** The constructor/extractor for `Return` instances.
* @group Extractors
@@ -1347,7 +1378,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Try >: Null <: TermTree with TryApi
+ type Try >: Null <: TryApi with TermTree
/** The constructor/extractor for `Try` instances.
* @group Extractors
@@ -1385,7 +1416,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Throw >: Null <: TermTree with ThrowApi
+ type Throw >: Null <: ThrowApi with TermTree
/** The constructor/extractor for `Throw` instances.
* @group Extractors
@@ -1415,7 +1446,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type New >: Null <: TermTree with NewApi
+ type New >: Null <: NewApi with TermTree
/** The constructor/extractor for `New` instances.
* @group Extractors
@@ -1465,7 +1496,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Typed >: Null <: TermTree with TypedApi
+ type Typed >: Null <: TypedApi with TermTree
/** The constructor/extractor for `Typed` instances.
* @group Extractors
@@ -1498,7 +1529,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type GenericApply >: Null <: TermTree with GenericApplyApi
+ type GenericApply >: Null <: GenericApplyApi with TermTree
/** The API that all applies support
* @group API
@@ -1519,7 +1550,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type TypeApply >: Null <: GenericApply with TypeApplyApi
+ type TypeApply >: Null <: TypeApplyApi with GenericApply
/** The constructor/extractor for `TypeApply` instances.
* @group Extractors
@@ -1557,7 +1588,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Apply >: Null <: GenericApply with ApplyApi
+ type Apply >: Null <: ApplyApi with GenericApply
/** The constructor/extractor for `Apply` instances.
* @group Extractors
@@ -1594,7 +1625,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Super >: Null <: TermTree with SuperApi
+ type Super >: Null <: SuperApi with TermTree
/** The constructor/extractor for `Super` instances.
* @group Extractors
@@ -1640,7 +1671,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type This >: Null <: TermTree with SymTree with ThisApi
+ type This >: Null <: ThisApi with TermTree with SymTree
/** The constructor/extractor for `This` instances.
* @group Extractors
@@ -1675,7 +1706,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Select >: Null <: RefTree with SelectApi
+ type Select >: Null <: SelectApi with RefTree
/** The constructor/extractor for `Select` instances.
* @group Extractors
@@ -1714,7 +1745,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Ident >: Null <: RefTree with IdentApi
+ type Ident >: Null <: IdentApi with RefTree
/** The constructor/extractor for `Ident` instances.
* @group Extractors
@@ -1739,65 +1770,18 @@ trait Trees { self: Universe =>
* @group API
*/
trait IdentApi extends RefTreeApi { this: Ident =>
+ /** Was this ident created from a backquoted identifier? */
+ def isBackquoted: Boolean
+
/** @inheritdoc */
def name: Name
}
- /** Marks underlying reference to id as boxed.
- *
- * <b>Precondition:<\b> id must refer to a captured variable
- * A reference such marked will refer to the boxed entity, no dereferencing
- * with `.elem` is done on it.
- * This tree node can be emitted by macros such as reify that call referenceCapturedVariable.
- * It is eliminated in LambdaLift, where the boxing conversion takes place.
- * @group Trees
- * @template
- */
- type ReferenceToBoxed >: Null <: TermTree with ReferenceToBoxedApi
-
- /** The constructor/extractor for `ReferenceToBoxed` instances.
- * @group Extractors
- */
- val ReferenceToBoxed: ReferenceToBoxedExtractor
-
- /** An extractor class to create and pattern match with syntax `ReferenceToBoxed(ident)`.
- * This AST node does not have direct correspondence to Scala code,
- * and is emitted by macros to reference capture vars directly without going through `elem`.
- *
- * For example:
- *
- * var x = ...
- * fun { x }
- *
- * Will emit:
- *
- * Ident(x)
- *
- * Which gets transformed to:
- *
- * Select(Ident(x), "elem")
- *
- * If `ReferenceToBoxed` were used instead of Ident, no transformation would be performed.
- * @group Extractors
- */
- abstract class ReferenceToBoxedExtractor {
- def apply(ident: Ident): ReferenceToBoxed
- def unapply(referenceToBoxed: ReferenceToBoxed): Option[Ident]
- }
-
- /** The API that all references support
- * @group API
- */
- trait ReferenceToBoxedApi extends TermTreeApi { this: ReferenceToBoxed =>
- /** The underlying reference. */
- def ident: Tree
- }
-
/** Literal
* @group Trees
* @template
*/
- type Literal >: Null <: TermTree with LiteralApi
+ type Literal >: Null <: LiteralApi with TermTree
/** The constructor/extractor for `Literal` instances.
* @group Extractors
@@ -1830,7 +1814,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type Annotated >: Null <: AnyRef with Tree with AnnotatedApi
+ type Annotated >: Null <: AnnotatedApi with Tree
/** The constructor/extractor for `Annotated` instances.
* @group Extractors
@@ -1864,7 +1848,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type SingletonTypeTree >: Null <: TypTree with SingletonTypeTreeApi
+ type SingletonTypeTree >: Null <: SingletonTypeTreeApi with TypTree
/** The constructor/extractor for `SingletonTypeTree` instances.
* @group Extractors
@@ -1894,7 +1878,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type SelectFromTypeTree >: Null <: TypTree with RefTree with SelectFromTypeTreeApi
+ type SelectFromTypeTree >: Null <: SelectFromTypeTreeApi with TypTree with RefTree
/** The constructor/extractor for `SelectFromTypeTree` instances.
* @group Extractors
@@ -1935,7 +1919,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type CompoundTypeTree >: Null <: TypTree with CompoundTypeTreeApi
+ type CompoundTypeTree >: Null <: CompoundTypeTreeApi with TypTree
/** The constructor/extractor for `CompoundTypeTree` instances.
* @group Extractors
@@ -1965,7 +1949,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type AppliedTypeTree >: Null <: TypTree with AppliedTypeTreeApi
+ type AppliedTypeTree >: Null <: AppliedTypeTreeApi with TypTree
/** The constructor/extractor for `AppliedTypeTree` instances.
* @group Extractors
@@ -2007,7 +1991,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type TypeBoundsTree >: Null <: TypTree with TypeBoundsTreeApi
+ type TypeBoundsTree >: Null <: TypeBoundsTreeApi with TypTree
/** The constructor/extractor for `TypeBoundsTree` instances.
* @group Extractors
@@ -2044,7 +2028,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type ExistentialTypeTree >: Null <: TypTree with ExistentialTypeTreeApi
+ type ExistentialTypeTree >: Null <: ExistentialTypeTreeApi with TypTree
/** The constructor/extractor for `ExistentialTypeTree` instances.
* @group Extractors
@@ -2085,7 +2069,7 @@ trait Trees { self: Universe =>
* @group Trees
* @template
*/
- type TypeTree >: Null <: TypTree with TypeTreeApi
+ type TypeTree >: Null <: TypeTreeApi with TypTree
/** The constructor/extractor for `TypeTree` instances.
* @group Extractors
@@ -2134,78 +2118,6 @@ trait Trees { self: Universe =>
// ---------------------- factories ----------------------------------------------
- /** A factory method for `ClassDef` nodes.
- * @group Factories
- */
- @deprecated("Use the canonical ClassDef constructor to create a class and then initialize its position and symbol manually", "2.10.1")
- def ClassDef(sym: Symbol, impl: Template): ClassDef
-
- /** A factory method for `ModuleDef` nodes.
- * @group Factories
- */
- @deprecated("Use the canonical ModuleDef constructor to create an object and then initialize its position and symbol manually", "2.10.1")
- def ModuleDef(sym: Symbol, impl: Template): ModuleDef
-
- /** A factory method for `ValDef` nodes.
- * @group Factories
- */
- @deprecated("Use the canonical ValDef constructor to create a val and then initialize its position and symbol manually", "2.10.1")
- def ValDef(sym: Symbol, rhs: Tree): ValDef
-
- /** A factory method for `ValDef` nodes.
- * @group Factories
- */
- @deprecated("Use the canonical ValDef constructor to create a val with an empty right-hand side and then initialize its position and symbol manually", "2.10.1")
- def ValDef(sym: Symbol): ValDef
-
- /** A factory method for `ValDef` nodes.
- * @group Factories
- */
- @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1")
- def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef
-
- /** A factory method for `ValDef` nodes.
- * @group Factories
- */
- @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1")
- def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef
-
- /** A factory method for `ValDef` nodes.
- * @group Factories
- */
- @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1")
- def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef
-
- /** A factory method for `ValDef` nodes.
- * @group Factories
- */
- @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1")
- def DefDef(sym: Symbol, rhs: Tree): DefDef
-
- /** A factory method for `ValDef` nodes.
- * @group Factories
- */
- @deprecated("Use the canonical DefDef constructor to create a method and then initialize its position and symbol manually", "2.10.1")
- def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef
-
- /** A factory method for `TypeDef` nodes.
- * @group Factories
- */
- @deprecated("Use the canonical TypeDef constructor to create a type alias and then initialize its position and symbol manually", "2.10.1")
- def TypeDef(sym: Symbol, rhs: Tree): TypeDef
-
- /** A factory method for `TypeDef` nodes.
- * @group Factories
- */
- @deprecated("Use the canonical TypeDef constructor to create an abstract type or type parameter and then initialize its position and symbol manually", "2.10.1")
- def TypeDef(sym: Symbol): TypeDef
-
- /** A factory method for `LabelDef` nodes.
- * @group Factories
- */
- @deprecated("Use the canonical LabelDef constructor to create a label and then initialize its position and symbol manually", "2.10.1")
- def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef
-
/** A factory method for `Block` nodes.
* Flattens directly nested blocks.
* @group Factories
@@ -2313,7 +2225,7 @@ trait Trees { self: Universe =>
* @template
* @group Copying
*/
- type TreeCopier <: TreeCopierOps
+ type TreeCopier >: Null <: AnyRef with TreeCopierOps
/** The standard (lazy) tree copier.
* @group Copying
@@ -2489,6 +2401,11 @@ trait Trees { self: Universe =>
*/
def Ident(tree: Tree, name: Name): Ident
+ /** Creates a `RefTree` node from the given components, having a given `tree` as a prototype.
+ * Having a tree as a prototype means that the tree's attachments, type and symbol will be copied into the result.
+ */
+ def RefTree(tree: Tree, qualifier: Tree, selector: Name): RefTree
+
/** Creates a `ReferenceToBoxed` node from the given components, having a given `tree` as a prototype.
* Having a tree as a prototype means that the tree's attachments, type and symbol will be copied into the result.
*/
@@ -2698,7 +2615,7 @@ trait Trees { self: Universe =>
*/
protected def xtransform(transformer: Transformer, tree: Tree): Tree = throw new MatchError(tree)
- /** The type of tree modifiers.
+ /** The type of tree modifiers (not a tree, but rather part of DefTrees).
* @group Traversal
*/
type Modifiers >: Null <: AnyRef with ModifiersApi
diff --git a/src/reflect/scala/reflect/api/TypeTags.scala b/src/reflect/scala/reflect/api/TypeTags.scala
index be76758224..1dfc84be69 100644
--- a/src/reflect/scala/reflect/api/TypeTags.scala
+++ b/src/reflect/scala/reflect/api/TypeTags.scala
@@ -333,6 +333,12 @@ trait TypeTags { self: Universe =>
* @group TypeTags
*/
def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe
+
+ /**
+ * Type symbol of `x` as derived from a type tag.
+ * @group TypeTags
+ */
+ def symbolOf[T: WeakTypeTag]: TypeSymbol
}
private[scala] class SerializedTypeTag(var tpec: TypeCreator, var concrete: Boolean) extends Serializable {
diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala
index 4892b46e16..f6995dd5de 100644
--- a/src/reflect/scala/reflect/api/Types.scala
+++ b/src/reflect/scala/reflect/api/Types.scala
@@ -59,7 +59,7 @@ trait Types {
* @template
* @group Types
*/
- type Type >: Null <: TypeApi
+ type Type >: Null <: AnyRef with TypeApi
/** This constant is used as a special value that indicates that no meaningful type exists.
* @group Types
@@ -76,6 +76,12 @@ trait Types {
/** The API of types.
* The main source of information about types is the [[scala.reflect.api.Types]] page.
* @group API
+ *
+ * @define dealiasWidenWarning Note that type aliases can hide beneath
+ * singleton types and singleton types can hide inside type aliases.
+ * Moreover, aliases might lurk in the upper bounds of abstract types.
+ * Therefore careful thought has to be applied to identify and carry out
+ * unwrapping logic specific to your use case.
*/
abstract class TypeApi {
/** The term symbol associated with the type, or `NoSymbol` for types
@@ -88,11 +94,19 @@ trait Types {
*/
def typeSymbol: Symbol
+ /** @see [[decl]] */
+ @deprecated("Use `decl` instead", "2.11.0")
+ def declaration(name: Name): Symbol
+
/** The defined or declared members with name `name` in this type;
* an OverloadedSymbol if several exist, NoSymbol if none exist.
* Alternatives of overloaded symbol appear in the order they are declared.
*/
- def declaration(name: Name): Symbol
+ def decl(name: Name): Symbol
+
+ /** @see [[decls]] */
+ @deprecated("Use `decls` instead", "2.11.0")
+ def declarations: MemberScope
/** A `Scope` containing directly declared members of this type.
* Unlike `members` this method doesn't returns inherited members.
@@ -100,7 +114,7 @@ trait Types {
* Members in the returned scope might appear in arbitrary order.
* Use `declarations.sorted` to get an ordered list of members.
*/
- def declarations: MemberScope
+ def decls: MemberScope
/** The member with given name, either directly declared or inherited,
* an OverloadedSymbol if several exist, NoSymbol if none exist.
@@ -115,6 +129,11 @@ trait Types {
*/
def members: MemberScope
+ /** Type signature of the companion of the underlying class symbol.
+ * NoType if the underlying symbol is not a class symbol, or if it doesn't have a companion.
+ */
+ def companion: Type
+
/** Is this type a type constructor that is missing its type arguments?
*/
def takesTypeArgs: Boolean
@@ -123,7 +142,7 @@ trait Types {
*/
def typeConstructor: Type
- /**
+ /** Reduce to beta eta-long normal form.
* Expands type aliases and converts higher-kinded TypeRefs to PolyTypes.
* Functions on types are also implemented as PolyTypes.
*
@@ -131,8 +150,18 @@ trait Types {
* TypeRef(pre, <List>, List()) is replaced by
* PolyType(X, TypeRef(pre, <List>, List(X)))
*/
+ @deprecated("Use `dealias` or `etaExpand` instead", "2.11.0")
def normalize: Type
+ /** Converts higher-kinded TypeRefs to PolyTypes.
+ * Functions on types are also implemented as PolyTypes.
+ *
+ * Example: (in the below, <List> is the type constructor of List)
+ * TypeRef(pre, <List>, List()) is replaced by
+ * PolyType(X, TypeRef(pre, <List>, List(X)))
+ */
+ def etaExpand: Type
+
/** Does this type conform to given type argument `that`? */
def <:< (that: Type): Boolean
@@ -205,9 +234,124 @@ trait Types {
* class Outer { class C ; val x: C }
* val o: Outer
* <o.x.type>.widen = o.C
+ *
+ * $dealiasWidenWarning
*/
def widen: Type
+ /** Expands type aliases arising from type members.
+ * $dealiasWidenWarning
+ */
+ def dealias: Type
+
+ /******* popular methods from subclasses *******/
+
+ /** List of type arguments ingrained in this type reference.
+ * Depending on your use case you might or might not want to call `dealias` first.
+ *
+ * {{{
+ * scala> type T = List[Int]
+ * defined type alias T
+ *
+ * scala> typeOf[T].typeArgs
+ * res0: List[reflect.runtime.universe.Type] = List()
+ *
+ * scala> typeOf[T].dealias.typeArgs
+ * res1: List[reflect.runtime.universe.Type] = List(scala.Int)
+ * }}}
+ */
+ def typeArgs: List[Type]
+
+ /** @see [[paramLists]] */
+ @deprecated("Use `paramLists` instead", "2.11.0")
+ def paramss: List[List[Symbol]]
+
+ /** For a method or poly type, a list of its value parameter sections,
+ * the empty list of lists for all other types.
+ */
+ def paramLists: List[List[Symbol]]
+
+ /** For a poly type, its type parameters,
+ * the empty list for all other types.
+ */
+ def typeParams: List[Symbol]
+
+ /** For a (nullary) method or poly type, its direct result type
+ * (can be a MethodType if the method has multiple argument lists),
+ * the type itself for all other types.
+ *
+ * {{{
+ * scala> class C { def foo[T](x: T)(y: T) = ??? }
+ * defined class C
+ *
+ * scala> typeOf[C].member(TermName("foo")).asMethod
+ * res0: reflect.runtime.universe.MethodSymbol = method foo
+ *
+ * scala> res0.info // PolyType wrapping a MethodType
+ * res1: reflect.runtime.universe.Type = [T](x: T)(y: T)scala.Nothing
+ *
+ * scala> res1.resultType // MethodType wrapping a MethodType
+ * res2: reflect.runtime.universe.Type = (x: T)(y: T)scala.Nothing
+ *
+ * scala> res1.resultType.resultType // vanilla MethodType
+ * res3: reflect.runtime.universe.Type = (y: T)scala.Nothing
+ *
+ * scala> res1.resultType.resultType.resultType
+ * res4: reflect.runtime.universe.Type = scala.Nothing
+ *
+ * scala> res1.finalResultType
+ * res5: reflect.runtime.universe.Type = scala.Nothing
+ * }}}
+ *
+ * @see finalResultType
+ */
+ def resultType: Type
+
+ /** For a curried/nullary method or poly type its non-method result type,
+ * the type itself for all other types.
+ *
+ * {{{
+ * scala> class C {
+ * | def foo[T](x: T)(y: T) = ???
+ * | def bar: Int = ???
+ * | }
+ * defined class C
+ *
+ * scala> typeOf[C].member(TermName("foo")).asMethod
+ * res0: reflect.runtime.universe.MethodSymbol = method foo
+ *
+ * scala> res0.info // PolyType wrapping a MethodType
+ * res1: reflect.runtime.universe.Type = [T](x: T)(y: T)scala.Nothing
+ *
+ * scala> res1.resultType // MethodType wrapping a MethodType
+ * res2: reflect.runtime.universe.Type = (x: T)(y: T)scala.Nothing
+ *
+ * scala> res1.resultType.resultType // vanilla MethodType
+ * res3: reflect.runtime.universe.Type = (y: T)scala.Nothing
+ *
+ * scala> res1.resultType.resultType.resultType
+ * res4: reflect.runtime.universe.Type = scala.Nothing
+ *
+ * scala> res1.finalResultType
+ * res5: reflect.runtime.universe.Type = scala.Nothing
+ *
+ * scala> typeOf[C].member(TermName("bar")).asMethod
+ * res6: reflect.runtime.universe.MethodSymbol = method bar
+ *
+ * scala> res6.info
+ * res7: reflect.runtime.universe.Type = => scala.Int
+ *
+ * scala> res6.info.resultType
+ * res8: reflect.runtime.universe.Type = scala.Int
+ *
+ * scala> res6.info.finalResultType
+ * res9: reflect.runtime.universe.Type = scala.Int
+ * }}}
+ *
+ * @see resultType
+ */
+ def finalResultType: Type
+
/******************* helpers *******************/
/** Provides an alternate if type is NoType.
@@ -256,7 +400,12 @@ trait Types {
* @template
* @group Types
*/
- type SingletonType >: Null <: Type
+ type SingletonType >: Null <: SingletonTypeApi with Type
+
+ /** Has no special methods. Is here to provides erased identity for `SingletonType`.
+ * @group API
+ */
+ trait SingletonTypeApi
/** A singleton type that describes types of the form on the left with the
* corresponding `ThisType` representation to the right:
@@ -266,7 +415,7 @@ trait Types {
* @template
* @group Types
*/
- type ThisType >: Null <: AnyRef with SingletonType with ThisTypeApi
+ type ThisType >: Null <: ThisTypeApi with SingletonType
/** The constructor/extractor for `ThisType` instances.
* @group Extractors
@@ -278,11 +427,11 @@ trait Types {
* @group Extractors
*/
abstract class ThisTypeExtractor {
- /**
- * Creates a ThisType from the given class symbol.
- */
- def apply(sym: Symbol): Type
def unapply(tpe: ThisType): Option[Symbol]
+
+ /** @see [[InternalApi.thisType]] */
+ @deprecated("Use `internal.thisType` instead", "2.11.0")
+ def apply(sym: Symbol)(implicit token: CompatToken): Type = internal.thisType(sym)
}
/** The API that all this types support.
@@ -304,7 +453,7 @@ trait Types {
* @template
* @group Types
*/
- type SingleType >: Null <: AnyRef with SingletonType with SingleTypeApi
+ type SingleType >: Null <: SingleTypeApi with SingletonType
/** The constructor/extractor for `SingleType` instances.
* @group Extractors
@@ -317,8 +466,11 @@ trait Types {
* @group Extractors
*/
abstract class SingleTypeExtractor {
- def apply(pre: Type, sym: Symbol): Type // not SingleTypebecause of implementation details
def unapply(tpe: SingleType): Option[(Type, Symbol)]
+
+ /** @see [[InternalApi.singleType]] */
+ @deprecated("Use `ClassSymbol.thisPrefix` or `internal.singleType` instead")
+ def apply(pre: Type, sym: Symbol)(implicit token: CompatToken): Type = internal.singleType(pre, sym)
}
/** The API that all single types support.
@@ -343,7 +495,7 @@ trait Types {
* @template
* @group Types
*/
- type SuperType >: Null <: AnyRef with SingletonType with SuperTypeApi
+ type SuperType >: Null <: SuperTypeApi with SingletonType
/** The constructor/extractor for `SuperType` instances.
* @group Extractors
@@ -354,8 +506,11 @@ trait Types {
* @group Extractors
*/
abstract class SuperTypeExtractor {
- def apply(thistpe: Type, supertpe: Type): Type // not SuperTypebecause of implementation details
def unapply(tpe: SuperType): Option[(Type, Type)]
+
+ /** @see [[InternalApi.superType]] */
+ @deprecated("Use `ClassSymbol.superPrefix` or `internal.superType` instead", "2.11.0")
+ def apply(thistpe: Type, supertpe: Type)(implicit token: CompatToken): Type = internal.superType(thistpe, supertpe)
}
/** The API that all super types support.
@@ -382,7 +537,7 @@ trait Types {
* @template
* @group Types
*/
- type ConstantType >: Null <: AnyRef with SingletonType with ConstantTypeApi
+ type ConstantType >: Null <: ConstantTypeApi with SingletonType
/** The constructor/extractor for `ConstantType` instances.
* @group Extractors
@@ -394,8 +549,11 @@ trait Types {
* @group Extractors
*/
abstract class ConstantTypeExtractor {
- def apply(value: Constant): ConstantType
def unapply(tpe: ConstantType): Option[Constant]
+
+ /** @see [[InternalApi.constantType]] */
+ @deprecated("Use `value.tpe` or `internal.constantType` instead", "2.11.0")
+ def apply(value: Constant)(implicit token: CompatToken): ConstantType = internal.constantType(value)
}
/** The API that all constant types support.
@@ -420,7 +578,7 @@ trait Types {
* @template
* @group Types
*/
- type TypeRef >: Null <: AnyRef with Type with TypeRefApi
+ type TypeRef >: Null <: TypeRefApi with Type
/** The constructor/extractor for `TypeRef` instances.
* @group Extractors
@@ -434,8 +592,11 @@ trait Types {
* @group Extractors
*/
abstract class TypeRefExtractor {
- def apply(pre: Type, sym: Symbol, args: List[Type]): Type // not TypeRefbecause of implementation details
def unapply(tpe: TypeRef): Option[(Type, Symbol, List[Type])]
+
+ /** @see [[InternalApi.typeRef]] */
+ @deprecated("Use `internal.typeRef` instead", "2.11.0")
+ def apply(pre: Type, sym: Symbol, args: List[Type])(implicit token: CompatToken): Type = internal.typeRef(pre, sym, args)
}
/** The API that all type refs support.
@@ -461,7 +622,12 @@ trait Types {
* @template
* @group Types
*/
- type CompoundType >: Null <: AnyRef with Type
+ type CompoundType >: Null <: CompoundTypeApi with Type
+
+ /** Has no special methods. Is here to provides erased identity for `CompoundType`.
+ * @group API
+ */
+ trait CompoundTypeApi
/** The `RefinedType` type defines types of any of the forms on the left,
* with their RefinedType representations to the right.
@@ -473,7 +639,7 @@ trait Types {
* @template
* @group Types
*/
- type RefinedType >: Null <: AnyRef with CompoundType with RefinedTypeApi
+ type RefinedType >: Null <: RefinedTypeApi with CompoundType
/** The constructor/extractor for `RefinedType` instances.
* @group Extractors
@@ -486,13 +652,15 @@ trait Types {
* @group Extractors
*/
abstract class RefinedTypeExtractor {
- def apply(parents: List[Type], decls: Scope): RefinedType
-
- /** An alternative constructor that passes in the synthetic classs symbol
- * that backs the refined type. (Normally, a fresh class symbol is created automatically).
- */
- def apply(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType
def unapply(tpe: RefinedType): Option[(List[Type], Scope)]
+
+ /** @see [[InternalApi.refinedType]] */
+ @deprecated("Use `internal.refinedType` instead", "2.11.0")
+ def apply(parents: List[Type], decls: Scope)(implicit token: CompatToken): RefinedType = internal.refinedType(parents, decls)
+
+ /** @see [[InternalApi.refinedType]] */
+ @deprecated("Use `internal.refinedType` instead", "2.11.0")
+ def apply(parents: List[Type], decls: Scope, clazz: Symbol)(implicit token: CompatToken): RefinedType = internal.refinedType(parents, decls, clazz)
}
/** The API that all refined types support.
@@ -504,7 +672,7 @@ trait Types {
def parents: List[Type]
/** The scope that holds the definitions comprising the type. */
- def decls: Scope
+ def decls: MemberScope
}
/** The `ClassInfo` type signature is used to define parents and declarations
@@ -519,7 +687,7 @@ trait Types {
* @template
* @group Types
*/
- type ClassInfoType >: Null <: AnyRef with CompoundType with ClassInfoTypeApi
+ type ClassInfoType >: Null <: ClassInfoTypeApi with CompoundType
/** The constructor/extractor for `ClassInfoType` instances.
* @group Extractors
@@ -533,8 +701,11 @@ trait Types {
* @group Extractors
*/
abstract class ClassInfoTypeExtractor {
- def apply(parents: List[Type], decls: Scope, typeSymbol: Symbol): ClassInfoType
def unapply(tpe: ClassInfoType): Option[(List[Type], Scope, Symbol)]
+
+ /** @see [[InternalApi.classInfoType]] */
+ @deprecated("Use `internal.classInfoType` instead", "2.11.0")
+ def apply(parents: List[Type], decls: Scope, typeSymbol: Symbol)(implicit token: CompatToken): ClassInfoType = internal.classInfoType(parents, decls, typeSymbol)
}
/** The API that all class info types support.
@@ -546,7 +717,7 @@ trait Types {
def parents: List[Type]
/** The scope that holds the definitions comprising the class type. */
- def decls: Scope
+ def decls: MemberScope
/** The symbol underlying the class type. */
def typeSymbol: Symbol
@@ -556,7 +727,7 @@ trait Types {
* @template
* @group Types
*/
- type MethodType >: Null <: AnyRef with Type with MethodTypeApi
+ type MethodType >: Null <: MethodTypeApi with Type
/** The constructor/extractor for `MethodType` instances.
* @group Extractors
@@ -579,8 +750,11 @@ trait Types {
* @group Extractors
*/
abstract class MethodTypeExtractor {
- def apply(params: List[Symbol], resultType: Type): MethodType
def unapply(tpe: MethodType): Option[(List[Symbol], Type)]
+
+ /** @see [[InternalApi.methodType]] */
+ @deprecated("Use `internal.methodType` instead", "2.11.0")
+ def apply(params: List[Symbol], resultType: Type)(implicit token: CompatToken): MethodType = internal.methodType(params, resultType)
}
/** The API that all method types support.
@@ -600,7 +774,7 @@ trait Types {
* @template
* @group Types
*/
- type NullaryMethodType >: Null <: AnyRef with Type with NullaryMethodTypeApi
+ type NullaryMethodType >: Null <: NullaryMethodTypeApi with Type
/** The constructor/extractor for `NullaryMethodType` instances.
* @group Extractors
@@ -612,8 +786,11 @@ trait Types {
* @group Extractors
*/
abstract class NullaryMethodTypeExtractor {
- def apply(resultType: Type): NullaryMethodType
def unapply(tpe: NullaryMethodType): Option[(Type)]
+
+ /** @see [[InternalApi.nullaryMethodType]] */
+ @deprecated("Use `internal.nullaryMethodType` instead", "2.11.0")
+ def apply(resultType: Type)(implicit token: CompatToken): NullaryMethodType = internal.nullaryMethodType(resultType)
}
/** The API that all nullary method types support.
@@ -630,7 +807,7 @@ trait Types {
* @template
* @group Types
*/
- type PolyType >: Null <: AnyRef with Type with PolyTypeApi
+ type PolyType >: Null <: PolyTypeApi with Type
/** The constructor/extractor for `PolyType` instances.
* @group Extractors
@@ -643,8 +820,11 @@ trait Types {
* @group Extractors
*/
abstract class PolyTypeExtractor {
- def apply(typeParams: List[Symbol], resultType: Type): PolyType
def unapply(tpe: PolyType): Option[(List[Symbol], Type)]
+
+ /** @see [[InternalApi.polyType]] */
+ @deprecated("Use `internal.polyType` instead", "2.11.0")
+ def apply(typeParams: List[Symbol], resultType: Type)(implicit token: CompatToken): PolyType = internal.polyType(typeParams, resultType)
}
/** The API that all polymorphic types support.
@@ -664,7 +844,7 @@ trait Types {
* @template
* @group Types
*/
- type ExistentialType >: Null <: AnyRef with Type with ExistentialTypeApi
+ type ExistentialType >: Null <: ExistentialTypeApi with Type
/** The constructor/extractor for `ExistentialType` instances.
* @group Extractors
@@ -678,8 +858,11 @@ trait Types {
* @group Extractors
*/
abstract class ExistentialTypeExtractor {
- def apply(quantified: List[Symbol], underlying: Type): ExistentialType
def unapply(tpe: ExistentialType): Option[(List[Symbol], Type)]
+
+ /** @see [[InternalApi.existentialType]] */
+ @deprecated("Use `internal.existentialType` instead", "2.11.0")
+ def apply(quantified: List[Symbol], underlying: Type)(implicit token: CompatToken): ExistentialType = internal.existentialType(quantified, underlying)
}
/** The API that all existential types support.
@@ -699,7 +882,7 @@ trait Types {
* @template
* @group Types
*/
- type AnnotatedType >: Null <: AnyRef with Type with AnnotatedTypeApi
+ type AnnotatedType >: Null <: AnnotatedTypeApi with Type
/** The constructor/extractor for `AnnotatedType` instances.
* @group Extractors
@@ -713,8 +896,11 @@ trait Types {
* @group Extractors
*/
abstract class AnnotatedTypeExtractor {
- def apply(annotations: List[Annotation], underlying: Type): AnnotatedType
def unapply(tpe: AnnotatedType): Option[(List[Annotation], Type)]
+
+ /** @see [[InternalApi.annotatedType]] */
+ @deprecated("Use `internal.annotatedType` instead", "2.11.0")
+ def apply(annotations: List[Annotation], underlying: Type)(implicit token: CompatToken): AnnotatedType = internal.annotatedType(annotations, underlying)
}
/** The API that all annotated types support.
@@ -741,7 +927,7 @@ trait Types {
* @template
* @group Types
*/
- type TypeBounds >: Null <: AnyRef with Type with TypeBoundsApi
+ type TypeBounds >: Null <: TypeBoundsApi with Type
/** The constructor/extractor for `TypeBounds` instances.
* @group Extractors
@@ -754,8 +940,11 @@ trait Types {
* @group Extractors
*/
abstract class TypeBoundsExtractor {
- def apply(lo: Type, hi: Type): TypeBounds
def unapply(tpe: TypeBounds): Option[(Type, Type)]
+
+ /** @see [[InternalApi.typeBounds]] */
+ @deprecated("Use `internal.typeBounds` instead", "2.11.0")
+ def apply(lo: Type, hi: Type)(implicit token: CompatToken): TypeBounds = internal.typeBounds(lo, hi)
}
/** The API that all type bounds support.
@@ -792,7 +981,7 @@ trait Types {
* @template
* @group Types
*/
- type BoundedWildcardType >: Null <: AnyRef with Type with BoundedWildcardTypeApi
+ type BoundedWildcardType >: Null <: BoundedWildcardTypeApi with Type
/** The constructor/extractor for `BoundedWildcardType` instances.
* @group Extractors
@@ -804,8 +993,11 @@ trait Types {
* @group Extractors
*/
abstract class BoundedWildcardTypeExtractor {
- def apply(bounds: TypeBounds): BoundedWildcardType
def unapply(tpe: BoundedWildcardType): Option[TypeBounds]
+
+ /** @see [[InternalApi.boundedWildcardType]] */
+ @deprecated("Use `internal.boundedWildcardType` instead", "2.11.0")
+ def apply(bounds: TypeBounds)(implicit token: CompatToken): BoundedWildcardType = internal.boundedWildcardType(bounds)
}
/** The API that all this types support.
@@ -827,74 +1019,17 @@ trait Types {
*/
def glb(ts: List[Type]): Type
- // Creators ---------------------------------------------------------------
- // too useful and too non-trivial to be left out of public API
-
- /** The canonical creator for single-types
- * @group TypeCreators
- */
- def singleType(pre: Type, sym: Symbol): Type
-
- /** the canonical creator for a refined type with a given scope
- * @group TypeCreators
- */
- def refinedType(parents: List[Type], owner: Symbol, decls: Scope, pos: Position): Type
-
- /** The canonical creator for a refined type with an initially empty scope.
- * @group TypeCreators
- */
- def refinedType(parents: List[Type], owner: Symbol): Type
-
- /** The canonical creator for typerefs
- * @group TypeCreators
- */
- def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type
-
- /** A creator for intersection type where intersections of a single type are
- * replaced by the type itself.
- * @group TypeCreators
- */
- def intersectionType(tps: List[Type]): Type
-
- /** A creator for intersection type where intersections of a single type are
- * replaced by the type itself, and repeated parent classes are merged.
- *
- * !!! Repeated parent classes are not merged - is this a bug in the
- * comment or in the code?
- * @group TypeCreators
- */
- def intersectionType(tps: List[Type], owner: Symbol): Type
-
/** A creator for type applications
- * @group Types
+ * @group TypeOps
*/
def appliedType(tycon: Type, args: List[Type]): Type
- /** A creator for type parameterizations that strips empty type parameter lists.
- * Use this factory method to indicate the type has kind * (it's a polymorphic value)
- * until we start tracking explicit kinds equivalent to typeFun (except that the latter requires tparams nonEmpty).
- * @group Types
- */
- def polyType(tparams: List[Symbol], tpe: Type): Type
+ /** @see [[appliedType]] */
+ def appliedType(tycon: Type, args: Type*): Type
- /** A creator for existential types. This generates:
- *
- * {{{
- * tpe1 where { tparams }
- * }}}
- *
- * where `tpe1` is the result of extrapolating `tpe` with regard to `tparams`.
- * Extrapolating means that type variables in `tparams` occurring
- * in covariant positions are replaced by upper bounds, (minus any
- * SingletonClass markers), type variables in `tparams` occurring in
- * contravariant positions are replaced by upper bounds, provided the
- * resulting type is legal with regard to stability, and does not contain
- * any type variable in `tparams`.
- *
- * The abstraction drops all type parameters that are not directly or
- * indirectly referenced by type `tpe1`. If there are no remaining type
- * parameters, simply returns result type `tpe`.
- * @group TypeCreators
- */
- def existentialAbstraction(tparams: List[Symbol], tpe0: Type): Type
+ /** @see [[appliedType]] */
+ def appliedType(sym: Symbol, args: List[Type]): Type
+
+ /** @see [[appliedType]] */
+ def appliedType(sym: Symbol, args: Type*): Type
}
diff --git a/src/reflect/scala/reflect/api/Universe.scala b/src/reflect/scala/reflect/api/Universe.scala
index 85a8ee0185..a3d1d291eb 100644
--- a/src/reflect/scala/reflect/api/Universe.scala
+++ b/src/reflect/scala/reflect/api/Universe.scala
@@ -69,17 +69,15 @@ abstract class Universe extends Symbols
with Positions
with Exprs
with TypeTags
- with TagInterop
with ImplicitTags
with StandardDefinitions
with StandardNames
with StandardLiftables
- with BuildUtils
with Mirrors
with Printers
- with Importers
with Liftables
with Quasiquotes
+ with Internals
{
/** Use `reify` to produce the abstract syntax tree representing a given Scala expression.
*
diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
index d634034fe9..19e9eef851 100644
--- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
@@ -10,10 +10,12 @@ package internal
import pickling.ByteCodecs
import scala.annotation.tailrec
import scala.collection.immutable.ListMap
+import scala.language.postfixOps
/** AnnotationInfo and its helpers */
trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
- import definitions.{ ThrowsClass, ThrowableClass, StaticAnnotationClass, isMetaAnnotation }
+ import definitions._
+ import treeInfo._
// Common annotation code between Symbol and Type.
// For methods altering the annotation list, on Symbol it mutates
@@ -75,7 +77,7 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
* - arrays of constants
* - or nested classfile annotations
*/
- sealed abstract class ClassfileAnnotArg extends Product
+ sealed abstract class ClassfileAnnotArg extends Product with JavaArgumentApi
implicit val JavaArgumentTag = ClassTag[ClassfileAnnotArg](classOf[ClassfileAnnotArg])
case object UnmappableAnnotArg extends ClassfileAnnotArg
@@ -344,6 +346,63 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
}
implicit val AnnotationTag = ClassTag[AnnotationInfo](classOf[AnnotationInfo])
+ protected[scala] def annotationToTree(ann: Annotation): Tree = {
+ def reverseEngineerArgs(): List[Tree] = {
+ def reverseEngineerArg(jarg: ClassfileAnnotArg): Tree = jarg match {
+ case LiteralAnnotArg(const) =>
+ val tpe = if (const.tag == UnitTag) UnitTpe else ConstantType(const)
+ Literal(const) setType tpe
+ case ArrayAnnotArg(jargs) =>
+ val args = jargs map reverseEngineerArg
+ // TODO: I think it would be a good idea to typecheck Java annotations using a more traditional algorithm
+ // sure, we can't typecheck them as is using the `new jann(foo = bar)` syntax (because jann is going to be an @interface)
+ // however we can do better than `typedAnnotation` by desugaring the aforementioned expression to
+ // something like `new jann() { override def annotatedType() = ...; override def foo = bar }`
+ // and then using the results of that typecheck to produce a Java-compatible classfile entry
+ // in that case we're going to have correctly typed Array.apply calls, however that's 2.12 territory
+ // and for 2.11 exposing an untyped call to ArrayModule should suffice
+ Apply(Ident(ArrayModule), args.toList)
+ case NestedAnnotArg(ann: Annotation) =>
+ annotationToTree(ann)
+ case _ =>
+ EmptyTree
+ }
+ def reverseEngineerArgs(jargs: List[(Name, ClassfileAnnotArg)]): List[Tree] = jargs match {
+ case (name, jarg) :: rest => AssignOrNamedArg(Ident(name), reverseEngineerArg(jarg)) :: reverseEngineerArgs(rest)
+ case Nil => Nil
+ }
+ if (ann.javaArgs.isEmpty) ann.scalaArgs
+ else reverseEngineerArgs(ann.javaArgs.toList)
+ }
+
+ // TODO: at the moment, constructor selection is unattributed, because AnnotationInfos lack necessary information
+ // later on, in 2.12, for every annotation we could save an entire tree instead of just bits and pieces
+ // but for 2.11 the current situation will have to do
+ val ctorSelection = Select(New(TypeTree(ann.atp)), nme.CONSTRUCTOR)
+ Apply(ctorSelection, reverseEngineerArgs()) setType ann.atp
+ }
+
+ protected[scala] def treeToAnnotation(tree: Tree): Annotation = tree match {
+ case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) =>
+ def encodeJavaArg(arg: Tree): ClassfileAnnotArg = arg match {
+ case Literal(const) => LiteralAnnotArg(const)
+ case Apply(ArrayModule, args) => ArrayAnnotArg(args map encodeJavaArg toArray)
+ case Apply(Select(New(tpt), nme.CONSTRUCTOR), args) => NestedAnnotArg(treeToAnnotation(arg))
+ case _ => throw new Exception("unexpected java argument shape $arg: literals, arrays and nested annotations are supported")
+ }
+ def encodeJavaArgs(args: List[Tree]): List[(Name, ClassfileAnnotArg)] = args match {
+ case AssignOrNamedArg(Ident(name), arg) :: rest => (name, encodeJavaArg(arg)) :: encodeJavaArgs(rest)
+ case arg :: rest => throw new Exception("unexpected java argument shape $arg: only AssignOrNamedArg trees are supported")
+ case Nil => Nil
+ }
+ val atp = tpt.tpe
+ if (atp != null && (atp.typeSymbol isNonBottomSubClass StaticAnnotationClass)) AnnotationInfo(atp, args, Nil)
+ else if (atp != null && (atp.typeSymbol isNonBottomSubClass ClassfileAnnotationClass)) AnnotationInfo(atp, Nil, encodeJavaArgs(args))
+ else throw new Exception(s"unexpected annotation type $atp: only subclasses of StaticAnnotation and ClassfileAnnotation are supported")
+ case _ =>
+ throw new Exception("""unexpected tree shape: only q"new $annType(..$args)" is supported""")
+ }
+
object UnmappableAnnotation extends CompleteAnnotationInfo(NoType, Nil, Nil)
object ErroneousAnnotation extends CompleteAnnotationInfo(ErrorType, Nil, Nil)
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 645d6aa4ff..2567abe51d 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -461,6 +461,9 @@ trait Definitions extends api.StandardDefinitions {
def ReflectRuntimeUniverse = ReflectRuntimePackage.map(sym => getMemberValue(sym, nme.universe))
def ReflectRuntimeCurrentMirror = ReflectRuntimePackage.map(sym => getMemberMethod(sym, nme.currentMirror))
+ lazy val UniverseClass = getClassIfDefined("scala.reflect.api.Universe") // defined in scala-reflect.jar, so we need to be careful
+ def UniverseInternal = getMemberValue(UniverseClass, nme.internal)
+
lazy val PartialManifestModule = requiredModule[scala.reflect.ClassManifestFactory.type]
lazy val FullManifestClass = requiredClass[scala.reflect.Manifest[_]]
lazy val FullManifestModule = requiredModule[scala.reflect.ManifestFactory.type]
diff --git a/src/reflect/scala/reflect/internal/FlagSets.scala b/src/reflect/scala/reflect/internal/FlagSets.scala
index 799f85054a..ef9c77878f 100644
--- a/src/reflect/scala/reflect/internal/FlagSets.scala
+++ b/src/reflect/scala/reflect/internal/FlagSets.scala
@@ -42,7 +42,11 @@ trait FlagSets extends api.FlagSets { self: SymbolTable =>
val DEFAULTPARAM : FlagSet = Flags.DEFAULTPARAM
val PRESUPER : FlagSet = Flags.PRESUPER
val DEFAULTINIT : FlagSet = Flags.DEFAULTINIT
- val SYNTHETIC : FlagSet = Flags.SYNTHETIC
val ENUM : FlagSet = Flags.ENUM
+ val PARAMACCESSOR : FlagSet = Flags.PARAMACCESSOR
+ val CASEACCESSOR : FlagSet = Flags.CASEACCESSOR
+ val SYNTHETIC : FlagSet = Flags.SYNTHETIC
+ val ARTIFACT : FlagSet = Flags.ARTIFACT
+ val STABLE : FlagSet = Flags.STABLE
}
}
diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala
index e66ed9a3d4..1707061817 100644
--- a/src/reflect/scala/reflect/internal/Flags.scala
+++ b/src/reflect/scala/reflect/internal/Flags.scala
@@ -118,22 +118,10 @@ class ModifierFlags {
final val PRESUPER = 1L << 37 // value is evaluated before super call
final val DEFAULTINIT = 1L << 41 // symbol is initialized to the default value: used by -Xcheckinit
final val ARTIFACT = 1L << 46 // symbol should be ignored when typechecking; will be marked ACC_SYNTHETIC in bytecode
+ // to see which symbols are marked as ARTIFACT, see scaladocs for FlagValues.ARTIFACT
final val DEFAULTMETHOD = 1L << 47 // symbol is a java default method
final val ENUM = 1L << 48 // symbol is an enum
- /** Symbols which are marked ARTIFACT. (Expand this list?)
- *
- * - $outer fields and accessors
- * - super accessors
- * - protected accessors
- * - lazy local accessors
- * - bridge methods
- * - default argument getters
- * - evaluation-order preserving locals for right-associative and out-of-order named arguments
- * - catch-expression storing vals
- * - anything else which feels a setFlag(ARTIFACT)
- */
-
// Overridden.
def flagToString(flag: Long): String = ""
diff --git a/src/reflect/scala/reflect/internal/HasFlags.scala b/src/reflect/scala/reflect/internal/HasFlags.scala
index 1131c94da0..aa8f4c532e 100644
--- a/src/reflect/scala/reflect/internal/HasFlags.scala
+++ b/src/reflect/scala/reflect/internal/HasFlags.scala
@@ -83,7 +83,9 @@ trait HasFlags {
def hasAccessorFlag = hasFlag(ACCESSOR)
def hasDefault = hasFlag(DEFAULTPARAM) && hasFlag(METHOD | PARAM) // Second condition disambiguates with TRAIT
def hasEnumFlag = hasFlag(ENUM)
+ @deprecated("Use isLocalToThis instead", "2.11.0")
def hasLocalFlag = hasFlag(LOCAL)
+ def isLocalToThis = hasFlag(LOCAL)
def hasModuleFlag = hasFlag(MODULE)
def hasPackageFlag = hasFlag(PACKAGE)
def hasStableFlag = hasFlag(STABLE)
@@ -106,6 +108,7 @@ trait HasFlags {
def isOverride = hasFlag(OVERRIDE)
def isParamAccessor = hasFlag(PARAMACCESSOR)
def isPrivate = hasFlag(PRIVATE)
+ @deprecated ("Use `hasPackageFlag` instead", "2.11.0")
def isPackage = hasFlag(PACKAGE)
def isPrivateLocal = hasAllFlags(PrivateLocal)
def isProtected = hasFlag(PROTECTED)
diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala
index ff91b08ea1..dc4ad25ef2 100644
--- a/src/reflect/scala/reflect/internal/Importers.scala
+++ b/src/reflect/scala/reflect/internal/Importers.scala
@@ -7,19 +7,9 @@ import scala.ref.WeakReference
import scala.reflect.internal.Flags._
// SI-6241: move importers to a mirror
-trait Importers extends api.Importers { to: SymbolTable =>
+trait Importers { to: SymbolTable =>
- /** Attachment that knows how to import itself into another universe. */
- trait ImportableAttachment {
- def importAttachment(importer: Importer): this.type
- }
-
- /** Attachment that doesn't contain any reflection artificats and can be imported as-is. */
- trait PlainAttachment extends ImportableAttachment {
- def importAttachment(importer: Importer): this.type = this
- }
-
- def mkImporter(from0: api.Universe): Importer { val from: from0.type } = (
+ override def mkImporter(from0: api.Universe): Importer { val from: from0.type } = (
if (to eq from0) {
new Importer {
val from = from0
diff --git a/src/reflect/scala/reflect/internal/Internals.scala b/src/reflect/scala/reflect/internal/Internals.scala
new file mode 100644
index 0000000000..e9916cf7d1
--- /dev/null
+++ b/src/reflect/scala/reflect/internal/Internals.scala
@@ -0,0 +1,174 @@
+package scala
+package reflect
+package internal
+
+import scala.language.implicitConversions
+import scala.language.higherKinds
+import scala.collection.mutable.WeakHashMap
+import scala.ref.WeakReference
+import scala.reflect.api.Universe
+import scala.reflect.macros.Attachments
+import scala.reflect.internal.util.FreshNameCreator
+import scala.reflect.internal.Flags._
+import scala.reflect.internal.util.ListOfNil
+
+trait Internals extends api.Internals {
+ self: SymbolTable =>
+
+ type Internal = MacroInternalApi
+ lazy val internal: Internal = new SymbolTableInternal {}
+
+ type Compat = MacroCompatApi
+ lazy val compat: Compat = new Compat {}
+
+ trait SymbolTableInternal extends MacroInternalApi {
+ lazy val reificationSupport: ReificationSupportApi = self.build
+
+ def createImporter(from0: Universe): Importer { val from: from0.type } = self.mkImporter(from0)
+
+ def newScopeWith(elems: Symbol*): Scope = self.newScopeWith(elems: _*)
+ def enter(scope: Scope, sym: Symbol): scope.type = { scope.enter(sym); scope }
+ def unlink(scope: Scope, sym: Symbol): scope.type = { scope.unlink(sym); scope }
+
+ def freeTerms(tree: Tree): List[FreeTermSymbol] = tree.freeTerms
+ def freeTypes(tree: Tree): List[FreeTypeSymbol] = tree.freeTypes
+ def substituteSymbols(tree: Tree, from: List[Symbol], to: List[Symbol]): Tree = tree.substituteSymbols(from, to)
+ def substituteTypes(tree: Tree, from: List[Symbol], to: List[Type]): Tree = tree.substituteTypes(from, to)
+ def substituteThis(tree: Tree, clazz: Symbol, to: Tree): Tree = tree.substituteThis(clazz, to)
+ def attachments(tree: Tree): Attachments { type Pos = Position } = tree.attachments
+ def updateAttachment[T: ClassTag](tree: Tree, attachment: T): tree.type = tree.updateAttachment(attachment)
+ def removeAttachment[T: ClassTag](tree: Tree): tree.type = tree.removeAttachment[T]
+ def setPos(tree: Tree, newpos: Position): tree.type = tree.setPos(newpos)
+ def setType(tree: Tree, tp: Type): tree.type = tree.setType(tp)
+ def defineType(tree: Tree, tp: Type): tree.type = tree.defineType(tp)
+ def setSymbol(tree: Tree, sym: Symbol): tree.type = tree.setSymbol(sym)
+ def setOriginal(tt: TypeTree, tree: Tree): TypeTree = tt.setOriginal(tree)
+
+ def captureVariable(vble: Symbol): Unit = self.captureVariable(vble)
+ def referenceCapturedVariable(vble: Symbol): Tree = self.referenceCapturedVariable(vble)
+ def capturedVariableType(vble: Symbol): Type = self.capturedVariableType(vble)
+
+ def classDef(sym: Symbol, impl: Template): ClassDef = self.ClassDef(sym, impl)
+ def moduleDef(sym: Symbol, impl: Template): ModuleDef = self.ModuleDef(sym, impl)
+ def valDef(sym: Symbol, rhs: Tree): ValDef = self.ValDef(sym, rhs)
+ def valDef(sym: Symbol): ValDef = self.ValDef(sym)
+ def defDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef = self.DefDef(sym, mods, vparamss, rhs)
+ def defDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef = self.DefDef(sym, vparamss, rhs)
+ def defDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef = self.DefDef(sym, mods, rhs)
+ def defDef(sym: Symbol, rhs: Tree): DefDef = self.DefDef(sym, rhs)
+ def defDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef = self.DefDef(sym, rhs)
+ def typeDef(sym: Symbol, rhs: Tree): TypeDef = self.TypeDef(sym, rhs)
+ def typeDef(sym: Symbol): TypeDef = self.TypeDef(sym)
+ def labelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef = self.LabelDef(sym, params, rhs)
+
+ def changeOwner(tree: Tree, prev: Symbol, next: Symbol): tree.type = {
+ object changeOwnerAndModuleClassTraverser extends ChangeOwnerTraverser(prev, next) {
+ override def traverse(tree: Tree) {
+ tree match {
+ case _: DefTree => change(tree.symbol.moduleClass)
+ case _ => // do nothing
+ }
+ super.traverse(tree)
+ }
+ }
+ changeOwnerAndModuleClassTraverser.traverse(tree)
+ tree
+ }
+
+ lazy val gen = self.treeBuild
+
+ def isFreeTerm(symbol: Symbol): Boolean = symbol.isFreeTerm
+ def asFreeTerm(symbol: Symbol): FreeTermSymbol = symbol.asFreeTerm
+ def isFreeType(symbol: Symbol): Boolean = symbol.isFreeType
+ def asFreeType(symbol: Symbol): FreeTypeSymbol = symbol.asFreeType
+ def newTermSymbol(symbol: Symbol, name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TermSymbol = symbol.newTermSymbol(name, pos, flags)
+ def newModuleAndClassSymbol(symbol: Symbol, name: Name, pos: Position = NoPosition, flags: FlagSet = NoFlags): (ModuleSymbol, ClassSymbol) = symbol.newModuleAndClassSymbol(name, pos, flags)
+ def newMethodSymbol(symbol: Symbol, name: TermName, pos: Position = NoPosition, flags: FlagSet = NoFlags): MethodSymbol = symbol.newMethodSymbol(name, pos, flags)
+ def newTypeSymbol(symbol: Symbol, name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): TypeSymbol = symbol.newTypeSymbol(name, pos, flags)
+ def newClassSymbol(symbol: Symbol, name: TypeName, pos: Position = NoPosition, flags: FlagSet = NoFlags): ClassSymbol = symbol.newClassSymbol(name, pos, flags)
+ def newFreeTerm(name: String, value: => Any, flags: FlagSet = NoFlags, origin: String = null): FreeTermSymbol = reificationSupport.newFreeTerm(name, value, flags, origin)
+ def newFreeType(name: String, flags: FlagSet = NoFlags, origin: String = null): FreeTypeSymbol = reificationSupport.newFreeType(name, flags, origin)
+ def isErroneous(symbol: Symbol): Boolean = symbol.isErroneous
+ def isSkolem(symbol: Symbol): Boolean = symbol.isSkolem
+ def deSkolemize(symbol: Symbol): Symbol = symbol.deSkolemize
+ def initialize(symbol: Symbol): symbol.type = symbol.initialize
+ def fullyInitialize(symbol: Symbol): symbol.type = definitions.fullyInitializeSymbol(symbol).asInstanceOf[symbol.type]
+ def fullyInitialize(tp: Type): tp.type = definitions.fullyInitializeType(tp).asInstanceOf[tp.type]
+ def fullyInitialize(scope: Scope): scope.type = definitions.fullyInitializeScope(scope).asInstanceOf[scope.type]
+ def flags(symbol: Symbol): FlagSet = symbol.flags
+ def attachments(symbol: Symbol): Attachments { type Pos = Position } = symbol.attachments
+ def updateAttachment[T: ClassTag](symbol: Symbol, attachment: T): symbol.type = symbol.updateAttachment(attachment)
+ def removeAttachment[T: ClassTag](symbol: Symbol): symbol.type = symbol.removeAttachment[T]
+ def setOwner(symbol: Symbol, newowner: Symbol): symbol.type = { symbol.owner = newowner; symbol }
+ def setInfo(symbol: Symbol, tpe: Type): symbol.type = symbol.setInfo(tpe)
+ def setAnnotations(symbol: Symbol, annots: Annotation*): symbol.type = symbol.setAnnotations(annots: _*)
+ def setName(symbol: Symbol, name: Name): symbol.type = symbol.setName(name)
+ def setPrivateWithin(symbol: Symbol, sym: Symbol): symbol.type = symbol.setPrivateWithin(sym)
+ def setFlag(symbol: Symbol, flags: FlagSet): symbol.type = symbol.setFlag(flags)
+ def resetFlag(symbol: Symbol, flags: FlagSet): symbol.type = symbol.resetFlag(flags)
+
+ def thisType(sym: Symbol): Type = self.ThisType(sym)
+ def singleType(pre: Type, sym: Symbol): Type = self.SingleType(pre, sym)
+ def superType(thistpe: Type, supertpe: Type): Type = self.SuperType(thistpe, supertpe)
+ def constantType(value: Constant): ConstantType = self.ConstantType(value)
+ def typeRef(pre: Type, sym: Symbol, args: List[Type]): Type = self.TypeRef(pre, sym, args)
+ def refinedType(parents: List[Type], decls: Scope): RefinedType = self.RefinedType(parents, decls)
+ def refinedType(parents: List[Type], decls: Scope, clazz: Symbol): RefinedType = self.RefinedType(parents, decls, clazz)
+ def refinedType(parents: List[Type], owner: Symbol): Type = self.refinedType(parents, owner)
+ def refinedType(parents: List[Type], owner: Symbol, decls: Scope): Type = self.RefinedType(parents, decls, owner)
+ def refinedType(parents: List[Type], owner: Symbol, decls: Scope, pos: Position): Type = self.refinedType(parents, owner, decls, pos)
+ def intersectionType(tps: List[Type]): Type = self.intersectionType(tps)
+ def intersectionType(tps: List[Type], owner: Symbol): Type = self.intersectionType(tps, owner)
+ def classInfoType(parents: List[Type], decls: Scope, typeSymbol: Symbol): ClassInfoType = self.ClassInfoType(parents, decls, typeSymbol)
+ def methodType(params: List[Symbol], resultType: Type): MethodType = self.MethodType(params, resultType)
+ def nullaryMethodType(resultType: Type): NullaryMethodType = self.NullaryMethodType(resultType)
+ def polyType(typeParams: List[Symbol], resultType: Type): PolyType = self.PolyType(typeParams, resultType)
+ def existentialType(quantified: List[Symbol], underlying: Type): ExistentialType = self.ExistentialType(quantified, underlying)
+ def existentialAbstraction(tparams: List[Symbol], tpe0: Type): Type = self.existentialAbstraction(tparams, tpe0)
+ def annotatedType(annotations: List[Annotation], underlying: Type): AnnotatedType = self.AnnotatedType(annotations, underlying)
+ def typeBounds(lo: Type, hi: Type): TypeBounds = self.TypeBounds(lo, hi)
+ def boundedWildcardType(bounds: TypeBounds): BoundedWildcardType = self.BoundedWildcardType(bounds)
+
+ def subpatterns(tree: Tree): Option[List[Tree]] = tree.attachments.get[SubpatternsAttachment].map(_.patterns.map(_.duplicate))
+
+ type Decorators = MacroDecoratorApi
+ lazy val decorators: Decorators = new MacroDecoratorApi {
+ override type ScopeDecorator[T <: Scope] = MacroScopeDecoratorApi[T]
+ override implicit def scopeDecorator[T <: Scope](scope: T): ScopeDecorator[T] = new MacroScopeDecoratorApi[T](scope)
+ override type TreeDecorator[T <: Tree] = MacroTreeDecoratorApi[T]
+ override implicit def treeDecorator[T <: Tree](tree: T): TreeDecorator[T] = new MacroTreeDecoratorApi[T](tree)
+ override type TypeTreeDecorator[T <: TypeTree] = MacroTypeTreeDecoratorApi[T]
+ override implicit def typeTreeDecorator[T <: TypeTree](tt: T): TypeTreeDecorator[T] = new MacroTypeTreeDecoratorApi[T](tt)
+ override type SymbolDecorator[T <: Symbol] = MacroSymbolDecoratorApi[T]
+ override implicit def symbolDecorator[T <: Symbol](symbol: T): SymbolDecorator[T] = new MacroSymbolDecoratorApi[T](symbol)
+ override type TypeDecorator[T <: Type] = TypeDecoratorApi[T]
+ override implicit def typeDecorator[T <: Type](tp: T): TypeDecorator[T] = new TypeDecoratorApi[T](tp)
+ }
+ }
+
+ lazy val treeBuild = new self.TreeGen {
+ def mkAttributedQualifier(tpe: Type): Tree = self.gen.mkAttributedQualifier(tpe)
+ def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree = self.gen.mkAttributedQualifier(tpe, termSym)
+ def mkAttributedRef(pre: Type, sym: Symbol): RefTree = self.gen.mkAttributedRef(pre, sym)
+ def mkAttributedRef(sym: Symbol): RefTree = self.gen.mkAttributedRef(sym)
+ def stabilize(tree: Tree): Tree = self.gen.stabilize(tree)
+ def mkAttributedStableRef(pre: Type, sym: Symbol): Tree = self.gen.mkAttributedStableRef(pre, sym)
+ def mkAttributedStableRef(sym: Symbol): Tree = self.gen.mkAttributedStableRef(sym)
+ def mkUnattributedRef(sym: Symbol): RefTree = self.gen.mkUnattributedRef(sym)
+ def mkUnattributedRef(fullName: Name): RefTree = self.gen.mkUnattributedRef(fullName)
+ def mkAttributedThis(sym: Symbol): This = self.gen.mkAttributedThis(sym)
+ def mkAttributedIdent(sym: Symbol): RefTree = self.gen.mkAttributedIdent(sym)
+ def mkAttributedSelect(qual: Tree, sym: Symbol): RefTree = self.gen.mkAttributedSelect(qual, sym)
+ def mkMethodCall(receiver: Symbol, methodName: Name, targs: List[Type], args: List[Tree]): Tree = self.gen.mkMethodCall(receiver, methodName, targs, args)
+ def mkMethodCall(method: Symbol, targs: List[Type], args: List[Tree]): Tree = self.gen.mkMethodCall(method, targs, args)
+ def mkMethodCall(method: Symbol, args: List[Tree]): Tree = self.gen.mkMethodCall(method, args)
+ def mkMethodCall(target: Tree, args: List[Tree]): Tree = self.gen.mkMethodCall(target, args)
+ def mkMethodCall(receiver: Symbol, methodName: Name, args: List[Tree]): Tree = self.gen.mkMethodCall(receiver, methodName, args)
+ def mkMethodCall(receiver: Tree, method: Symbol, targs: List[Type], args: List[Tree]): Tree = self.gen.mkMethodCall(receiver, method, targs, args)
+ def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree = self.gen.mkMethodCall(target, targs, args)
+ def mkNullaryCall(method: Symbol, targs: List[Type]): Tree = self.gen.mkNullaryCall(method, targs)
+ def mkRuntimeUniverseRef: Tree = self.gen.mkRuntimeUniverseRef
+ def mkZero(tp: Type): Tree = self.gen.mkZero(tp)
+ def mkCast(tree: Tree, pt: Type): Tree = self.gen.mkCast(tree, pt)
+ }
+} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala
index 6cf4944d18..7065a8cd6d 100644
--- a/src/reflect/scala/reflect/internal/Mirrors.scala
+++ b/src/reflect/scala/reflect/internal/Mirrors.scala
@@ -117,14 +117,15 @@ trait Mirrors extends api.Mirrors {
* Compiler might ignore them, but they should be loadable with macros.
*/
override def staticClass(fullname: String): ClassSymbol =
- ensureClassSymbol(fullname, staticModuleOrClass(newTypeNameCached(fullname)))
+ try ensureClassSymbol(fullname, staticModuleOrClass(newTypeNameCached(fullname)))
+ catch { case mre: MissingRequirementError => throw new ScalaReflectionException(mre.msg) }
/************************ loaders of module symbols ************************/
private def ensureModuleSymbol(fullname: String, sym: Symbol, allowPackages: Boolean): ModuleSymbol =
sym match {
- case x: ModuleSymbol if allowPackages || !x.isPackage => x
- case _ => MissingRequirementError.notFound("object " + fullname)
+ case x: ModuleSymbol if allowPackages || !x.hasPackageFlag => x
+ case _ => MissingRequirementError.notFound("object " + fullname)
}
def getModuleByName(fullname: Name): ModuleSymbol =
@@ -155,14 +156,15 @@ trait Mirrors extends api.Mirrors {
* Compiler might ignore them, but they should be loadable with macros.
*/
override def staticModule(fullname: String): ModuleSymbol =
- ensureModuleSymbol(fullname, staticModuleOrClass(newTermNameCached(fullname)), allowPackages = false)
+ try ensureModuleSymbol(fullname, staticModuleOrClass(newTermNameCached(fullname)), allowPackages = false)
+ catch { case mre: MissingRequirementError => throw new ScalaReflectionException(mre.msg) }
/************************ loaders of package symbols ************************/
private def ensurePackageSymbol(fullname: String, sym: Symbol, allowModules: Boolean): ModuleSymbol =
sym match {
- case x: ModuleSymbol if allowModules || x.isPackage => x
- case _ => MissingRequirementError.notFound("package " + fullname)
+ case x: ModuleSymbol if allowModules || x.hasPackageFlag => x
+ case _ => MissingRequirementError.notFound("package " + fullname)
}
def getPackage(fullname: TermName): ModuleSymbol =
@@ -186,18 +188,19 @@ trait Mirrors extends api.Mirrors {
def getPackageObjectIfDefined(fullname: TermName): Symbol =
wrapMissing(getPackageObject(fullname))
-
+
final def getPackageObjectWithMember(pre: Type, sym: Symbol): Symbol = {
// The owner of a symbol which requires package qualification may be the
// package object iself, but it also could be any superclass of the package
// object. In the latter case, we must go through the qualifier's info
// to obtain the right symbol.
- if (sym.owner.isModuleClass) sym.owner.sourceModule // fast path, if the member is owned by a module class, that must be linked to the package object
+ if (sym.owner.isModuleClass) sym.owner.sourceModule // fast path, if the member is owned by a module class, that must be linked to the package object
else pre member nme.PACKAGE // otherwise we have to findMember
}
override def staticPackage(fullname: String): ModuleSymbol =
- ensurePackageSymbol(fullname.toString, getModuleOrClass(newTermNameCached(fullname)), allowModules = false)
+ try ensurePackageSymbol(fullname.toString, getModuleOrClass(newTermNameCached(fullname)), allowModules = false)
+ catch { case mre: MissingRequirementError => throw new ScalaReflectionException(mre.msg) }
/************************ helpers ************************/
diff --git a/src/reflect/scala/reflect/internal/Names.scala b/src/reflect/scala/reflect/internal/Names.scala
index 73ce59feb2..ae9f2da4e5 100644
--- a/src/reflect/scala/reflect/internal/Names.scala
+++ b/src/reflect/scala/reflect/internal/Names.scala
@@ -535,7 +535,7 @@ trait Names extends api.Names {
}
// SYNCNOTE: caller to constructor must synchronize if `synchronizeNames` is enabled
- sealed abstract class TermName(index0: Int, len0: Int, hash: Int) extends Name(index0, len0) {
+ sealed abstract class TermName(index0: Int, len0: Int, hash: Int) extends Name(index0, len0) with TermNameApi {
type ThisNameType = TermName
protected[this] def thisName: TermName = this
val next: TermName = termHashtable(hash)
@@ -572,7 +572,7 @@ trait Names extends api.Names {
def unapply(name: TermName): Option[String] = Some(name.toString)
}
- sealed abstract class TypeName(index0: Int, len0: Int, hash: Int) extends Name(index0, len0) {
+ sealed abstract class TypeName(index0: Int, len0: Int, hash: Int) extends Name(index0, len0) with TypeNameApi {
type ThisNameType = TypeName
protected[this] def thisName: TypeName = this
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index 6734a2bd5a..b1d76b6056 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -1214,17 +1214,17 @@ trait Printers extends api.Printers { self: SymbolTable =>
}
def show(name: Name): String = name match {
- case tpnme.WILDCARD => "tpnme.WILDCARD"
- case tpnme.EMPTY => "tpnme.EMPTY"
- case tpnme.ERROR => "tpnme.ERROR"
- case tpnme.PACKAGE => "tpnme.PACKAGE"
- case tpnme.WILDCARD_STAR => "tpnme.WILDCARD_STAR"
- case nme.WILDCARD => "nme.WILDCARD"
- case nme.EMPTY => "nme.EMPTY"
- case nme.ERROR => "tpnme.ERROR"
- case nme.PACKAGE => "nme.PACKAGE"
- case nme.CONSTRUCTOR => "nme.CONSTRUCTOR"
- case nme.ROOTPKG => "nme.ROOTPKG"
+ case tpnme.WILDCARD => "typeNames.WILDCARD"
+ case tpnme.EMPTY => "typeNames.EMPTY"
+ case tpnme.ERROR => "typeNames.ERROR"
+ case tpnme.PACKAGE => "typeNames.PACKAGE"
+ case tpnme.WILDCARD_STAR => "typeNames.WILDCARD_STAR"
+ case nme.WILDCARD => "termNames.WILDCARD"
+ case nme.EMPTY => "termNames.EMPTY"
+ case nme.ERROR => "termNames.ERROR"
+ case nme.PACKAGE => "termNames.PACKAGE"
+ case nme.CONSTRUCTOR => "termNames.CONSTRUCTOR"
+ case nme.ROOTPKG => "termNames.ROOTPKG"
case _ =>
val prefix = if (name.isTermName) "TermName(\"" else "TypeName(\""
prefix + name.toString + "\")"
@@ -1240,4 +1240,13 @@ trait Printers extends api.Printers { self: SymbolTable =>
s_flags mkString " | "
}
}
+
+ def show(position: Position): String = {
+ position.show
+ }
+
+ def showDecl(sym: Symbol): String = {
+ if (!isCompilerUniverse) definitions.fullyInitializeSymbol(sym)
+ sym.defString
+ }
}
diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/ReificationSupport.scala
index 0c7930f673..087d4186be 100644
--- a/src/reflect/scala/reflect/internal/BuildUtils.scala
+++ b/src/reflect/scala/reflect/internal/ReificationSupport.scala
@@ -5,10 +5,11 @@ package internal
import Flags._
import util._
-trait BuildUtils { self: SymbolTable =>
+trait ReificationSupport { self: SymbolTable =>
import definitions.{TupleClass, FunctionClass, ScalaPackage, UnitClass}
+ import internal._
- class BuildImpl extends BuildApi {
+ class ReificationSupportImpl extends ReificationSupportApi {
def selectType(owner: Symbol, name: String): TypeSymbol =
select(owner, newTypeName(name)).asType
@@ -22,14 +23,15 @@ trait BuildUtils { self: SymbolTable =>
val result = owner.info decl name
if (result ne NoSymbol) result
else
- mirrorThatLoaded(owner).missingHook(owner, name) orElse
- MissingRequirementError.notFound("%s %s in %s".format(if (name.isTermName) "term" else "type", name, owner.fullName))
+ mirrorThatLoaded(owner).missingHook(owner, name) orElse {
+ throw new ScalaReflectionException("%s %s in %s not found".format(if (name.isTermName) "term" else "type", name, owner.fullName))
+ }
}
def selectOverloadedMethod(owner: Symbol, name: String, index: Int): MethodSymbol = {
val result = owner.info.decl(newTermName(name)).alternatives(index)
if (result ne NoSymbol) result.asMethod
- else MissingRequirementError.notFound("overloaded method %s #%d in %s".format(name, index, owner.fullName))
+ else throw new ScalaReflectionException("overloaded method %s #%d in %s not found".format(name, index, owner.fullName))
}
def newFreeTerm(name: String, value: => Any, flags: Long = 0L, origin: String = null): FreeTermSymbol =
@@ -41,19 +43,50 @@ trait BuildUtils { self: SymbolTable =>
def newNestedSymbol(owner: Symbol, name: Name, pos: Position, flags: Long, isClass: Boolean): Symbol =
owner.newNestedSymbol(name, pos, flags, isClass).markFlagsCompleted(mask = AllFlags)
+ def newScopeWith(elems: Symbol*): Scope =
+ self.newScopeWith(elems: _*)
+
def setAnnotations[S <: Symbol](sym: S, annots: List[AnnotationInfo]): S =
sym.setAnnotations(annots)
- def setTypeSignature[S <: Symbol](sym: S, tpe: Type): S =
- sym.setTypeSignature(tpe).markAllCompleted()
+ def setInfo[S <: Symbol](sym: S, tpe: Type): S =
+ sym.setInfo(tpe).markAllCompleted()
+
+ def mkThis(sym: Symbol): Tree = self.This(sym)
+
+ def mkSelect(qualifier: Tree, sym: Symbol): Select = self.Select(qualifier, sym)
+
+ def mkIdent(sym: Symbol): Ident = self.Ident(sym)
+
+ def mkTypeTree(tp: Type): TypeTree = self.TypeTree(tp)
+
+ def ThisType(sym: Symbol): Type = self.ThisType(sym)
+
+ def SingleType(pre: Type, sym: Symbol): Type = self.SingleType(pre, sym)
+
+ def SuperType(thistpe: Type, supertpe: Type): Type = self.SuperType(thistpe, supertpe)
+
+ def ConstantType(value: Constant): ConstantType = self.ConstantType(value)
+
+ def TypeRef(pre: Type, sym: Symbol, args: List[Type]): Type = self.TypeRef(pre, sym, args)
+
+ def RefinedType(parents: List[Type], decls: Scope, typeSymbol: Symbol): RefinedType = self.RefinedType(parents, decls, typeSymbol)
+
+ def ClassInfoType(parents: List[Type], decls: Scope, typeSymbol: Symbol): ClassInfoType = self.ClassInfoType(parents, decls, typeSymbol)
+
+ def MethodType(params: List[Symbol], resultType: Type): MethodType = self.MethodType(params, resultType)
+
+ def NullaryMethodType(resultType: Type): NullaryMethodType = self.NullaryMethodType(resultType)
+
+ def PolyType(typeParams: List[Symbol], resultType: Type): PolyType = self.PolyType(typeParams, resultType)
- def This(sym: Symbol): Tree = self.This(sym)
+ def ExistentialType(quantified: List[Symbol], underlying: Type): ExistentialType = self.ExistentialType(quantified, underlying)
- def Select(qualifier: Tree, sym: Symbol): Select = self.Select(qualifier, sym)
+ def AnnotatedType(annotations: List[Annotation], underlying: Type): AnnotatedType = self.AnnotatedType(annotations, underlying)
- def Ident(sym: Symbol): Ident = self.Ident(sym)
+ def TypeBounds(lo: Type, hi: Type): TypeBounds = self.TypeBounds(lo, hi)
- def TypeTree(tp: Type): TypeTree = self.TypeTree(tp)
+ def BoundedWildcardType(bounds: TypeBounds): BoundedWildcardType = self.BoundedWildcardType(bounds)
def thisPrefix(sym: Symbol): Type = sym.thisPrefix
@@ -141,7 +174,7 @@ trait BuildUtils { self: SymbolTable =>
def mkEarlyDef(defns: List[Tree]): List[Tree] = defns.map(mkEarlyDef)
- def RefTree(qual: Tree, sym: Symbol) = self.RefTree(qual, sym.name) setSymbol sym
+ def mkRefTree(qual: Tree, sym: Symbol) = self.RefTree(qual, sym.name) setSymbol sym
def freshTermName(prefix: String = nme.FRESH_TERM_NAME_PREFIX): TermName = self.freshTermName(prefix)
@@ -953,5 +986,5 @@ trait BuildUtils { self: SymbolTable =>
}
}
- val build: BuildImpl = new BuildImpl
+ val build = new ReificationSupportImpl
}
diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala
index 139a79ffe1..614e71b597 100644
--- a/src/reflect/scala/reflect/internal/StdAttachments.scala
+++ b/src/reflect/scala/reflect/internal/StdAttachments.scala
@@ -22,6 +22,16 @@ trait StdAttachments {
def setPos(newpos: Position): this.type = { pos = newpos; this }
}
+ /** Attachment that knows how to import itself into another universe. */
+ trait ImportableAttachment {
+ def importAttachment(importer: Importer): this.type
+ }
+
+ /** Attachment that doesn't contain any reflection artificats and can be imported as-is. */
+ trait PlainAttachment extends ImportableAttachment {
+ def importAttachment(importer: Importer): this.type = this
+ }
+
/** Stores the trees that give rise to a refined type to be used in reification.
* Unfortunately typed `CompoundTypeTree` is lacking essential info, and the reifier cannot use `CompoundTypeTree.tpe`.
* Therefore we need this hack (see `Reshape.toPreTyperTypeTree` for a detailed explanation).
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index aad5f32b5f..0c28c4fba4 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -319,7 +319,7 @@ trait StdNames {
val FAKE_LOCAL_THIS: NameType = "this$"
val LAZY_LOCAL: NameType = "$lzy"
val LAZY_SLOW_SUFFIX: NameType = "$lzycompute"
- val UNIVERSE_BUILD_PREFIX: NameType = "$u.build."
+ val UNIVERSE_BUILD_PREFIX: NameType = "$u.internal.reificationSupport."
val UNIVERSE_PREFIX: NameType = "$u."
val UNIVERSE_SHORT: NameType = "$u"
val MIRROR_PREFIX: NameType = "$m."
@@ -578,10 +578,13 @@ trait StdNames {
val Annotation: NameType = "Annotation"
val Any: NameType = "Any"
val AnyVal: NameType = "AnyVal"
+ val Apply: NameType = "Apply"
val ArrayAnnotArg: NameType = "ArrayAnnotArg"
+ val ClassInfoType: NameType = "ClassInfoType"
val ConstantType: NameType = "ConstantType"
val EmptyPackage: NameType = "EmptyPackage"
val EmptyPackageClass: NameType = "EmptyPackageClass"
+ val ExistentialType: NameType = "ExistentialType"
val Flag : NameType = "Flag"
val FlagsRepr: NameType = "FlagsRepr"
val Ident: NameType = "Ident"
@@ -589,18 +592,25 @@ trait StdNames {
val Import: NameType = "Import"
val Literal: NameType = "Literal"
val LiteralAnnotArg: NameType = "LiteralAnnotArg"
+ val MethodType: NameType = "MethodType"
val Modifiers: NameType = "Modifiers"
val NestedAnnotArg: NameType = "NestedAnnotArg"
+ val New: NameType = "New"
val NoFlags: NameType = "NoFlags"
val NoSymbol: NameType = "NoSymbol"
val NoMods: NameType = "NoMods"
val Nothing: NameType = "Nothing"
val Null: NameType = "Null"
+ val NullaryMethodType: NameType = "NullaryMethodType"
val Object: NameType = "Object"
+ val PolyType: NameType = "PolyType"
+ val RefinedType: NameType = "RefinedType"
val RootPackage: NameType = "RootPackage"
val RootClass: NameType = "RootClass"
val Select: NameType = "Select"
val SelectFromTypeTree: NameType = "SelectFromTypeTree"
+ val SingleType: NameType = "SingleType"
+ val SuperType: NameType = "SuperType"
val SyntacticApplied: NameType = "SyntacticApplied"
val SyntacticAssign: NameType = "SyntacticAssign"
val SyntacticBlock: NameType = "SyntacticBlock"
@@ -632,6 +642,7 @@ trait StdNames {
val ThisType: NameType = "ThisType"
val Tuple2: NameType = "Tuple2"
val TYPE_ : NameType = "TYPE"
+ val TypeBounds: NameType = "TypeBounds"
val TypeRef: NameType = "TypeRef"
val TypeTree: NameType = "TypeTree"
val UNIT : NameType = "UNIT"
@@ -654,7 +665,6 @@ trait StdNames {
val asInstanceOf_ : NameType = "asInstanceOf"
val asInstanceOf_Ob : NameType = "$asInstanceOf"
val box: NameType = "box"
- val build : NameType = "build"
val bytes: NameType = "bytes"
val c: NameType = "c"
val canEqual_ : NameType = "canEqual"
@@ -696,6 +706,7 @@ trait StdNames {
val immutable: NameType = "immutable"
val implicitly: NameType = "implicitly"
val in: NameType = "in"
+ val internal: NameType = "internal"
val inlinedEquals: NameType = "inlinedEquals"
val isArray: NameType = "isArray"
val isDefinedAt: NameType = "isDefinedAt"
@@ -717,8 +728,13 @@ trait StdNames {
val moduleClass : NameType = "moduleClass"
val mkAnnotation: NameType = "mkAnnotation"
val mkEarlyDef: NameType = "mkEarlyDef"
+ val mkIdent: NameType = "mkIdent"
val mkPackageStat: NameType = "mkPackageStat"
val mkRefineStat: NameType = "mkRefineStat"
+ val mkRefTree: NameType = "mkRefTree"
+ val mkSelect: NameType = "mkSelect"
+ val mkThis: NameType = "mkThis"
+ val mkTypeTree: NameType = "mkTypeTree"
val ne: NameType = "ne"
val newArray: NameType = "newArray"
val newFreeTerm: NameType = "newFreeTerm"
@@ -736,11 +752,11 @@ trait StdNames {
val productPrefix: NameType = "productPrefix"
val readResolve: NameType = "readResolve"
val reify : NameType = "reify"
+ val reificationSupport : NameType = "reificationSupport"
val rootMirror : NameType = "rootMirror"
val runtime: NameType = "runtime"
val runtimeClass: NameType = "runtimeClass"
val runtimeMirror: NameType = "runtimeMirror"
- val RefTree: NameType = "RefTree"
val scala_ : NameType = "scala"
val selectDynamic: NameType = "selectDynamic"
val selectOverloadedMethod: NameType = "selectOverloadedMethod"
@@ -748,9 +764,9 @@ trait StdNames {
val selectType: NameType = "selectType"
val self: NameType = "self"
val setAnnotations: NameType = "setAnnotations"
+ val setInfo: NameType = "setInfo"
val setSymbol: NameType = "setSymbol"
val setType: NameType = "setType"
- val setTypeSignature: NameType = "setTypeSignature"
val splice: NameType = "splice"
val staticClass : NameType = "staticClass"
val staticModule : NameType = "staticModule"
@@ -989,6 +1005,8 @@ trait StdNames {
val BITMAP_CHECKINIT_TRANSIENT: NameType = BITMAP_PREFIX + "inittrans$" // initialization bitmap for transient checkinit values
}
+ lazy val typeNames: tpnme.type = tpnme
+
object tpnme extends TypeNames { }
/** For fully qualified type names.
@@ -1009,6 +1027,8 @@ trait StdNames {
val javanme = nme.javaKeywords
+ lazy val termNames: nme.type = nme
+
object nme extends TermNames {
def moduleVarName(name: TermName): TermName =
newTermNameCached("" + name + MODULE_VAR_SUFFIX)
diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala
index 802bd18a4e..e50c65c9ca 100644
--- a/src/reflect/scala/reflect/internal/SymbolTable.scala
+++ b/src/reflect/scala/reflect/internal/SymbolTable.scala
@@ -11,6 +11,7 @@ import scala.annotation.elidable
import scala.collection.{ mutable, immutable }
import util._
import java.util.concurrent.TimeUnit
+import scala.reflect.internal.{TreeGen => InternalTreeGen}
abstract class SymbolTable extends macros.Universe
with Collections
@@ -40,14 +41,14 @@ abstract class SymbolTable extends macros.Universe
with CapturedVariables
with StdAttachments
with StdCreators
- with BuildUtils
+ with ReificationSupport
with PrivateWithin
with pickling.Translations
with FreshNames
+ with Internals
{
- val gen = new TreeGen { val global: SymbolTable.this.type = SymbolTable.this }
- lazy val treeBuild = gen
+ val gen = new InternalTreeGen { val global: SymbolTable.this.type = SymbolTable.this }
def log(msg: => AnyRef): Unit
def warning(msg: String): Unit = Console.err.println(msg)
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 02616d1ba6..83c2e2acdb 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -77,9 +77,16 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
}
- abstract class SymbolContextApiImpl extends SymbolContextApi {
+ def symbolOf[T: WeakTypeTag]: TypeSymbol = weakTypeOf[T].typeSymbolDirect.asType
+
+ abstract class SymbolContextApiImpl extends SymbolApi {
this: Symbol =>
+ def isFreeTerm: Boolean = false
+ def asFreeTerm: FreeTermSymbol = throw new ScalaReflectionException(s"$this is not a free term")
+ def isFreeType: Boolean = false
+ def asFreeType: FreeTypeSymbol = throw new ScalaReflectionException(s"$this is not a free type")
+
def isExistential: Boolean = this.isExistentiallyBound
def isParamWithDefault: Boolean = this.hasDefault
// `isByNameParam` is only true for a call-by-name parameter of a *method*,
@@ -89,6 +96,9 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def isJava: Boolean = isJavaDefined
def isVal: Boolean = isTerm && !isModule && !isMethod && !isMutable
def isVar: Boolean = isTerm && !isModule && !isMethod && !isLazy && isMutable
+ def isAbstract: Boolean = isAbstractClass || isDeferred || isAbstractType
+ def isPrivateThis = (this hasFlag PRIVATE) && (this hasFlag LOCAL)
+ def isProtectedThis = (this hasFlag PROTECTED) && (this hasFlag LOCAL)
def newNestedSymbol(name: Name, pos: Position, newFlags: Long, isClass: Boolean): Symbol = name match {
case n: TermName => newTermSymbol(n, pos, newFlags)
@@ -110,24 +120,52 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def baseClasses = info.baseClasses
def module = sourceModule
def thisPrefix: Type = thisType
-
- // automatic full initialization on access to info from reflection API is a double-edged sword
- // on the one hand, it's convenient so that the users don't have to deal with initialization themselves before printing out stuff
- // (e.g. printing out a method's signature without fully initializing it would result in <_>'s for parameters
- // on the other hand, this strategy can potentially cause unexpected effects due to being inconsistent with compiler's behavior
- // so far I think user convenience outweighs the scariness, but we need to keep the tradeoff in mind
- // NOTE: if you end up removing the call to fullyInitializeSymbol, consider that it would affect both runtime reflection and macros
- def typeSignature: Type = { fullyInitializeSymbol(this); info }
- def typeSignatureIn(site: Type): Type = { fullyInitializeSymbol(this); site memberInfo this }
+ def superPrefix(supertpe: Type): Type = SuperType(thisType, supertpe)
+
+ // These two methods used to call fullyInitializeSymbol on `this`.
+ //
+ // The only positive effect of that is, to the best of my knowledge, convenient printing
+ // (if you print a signature of the symbol that's not fully initialized,
+ // you might end up with weird <?>'s in value/type params)
+ //
+ // Another effect is obviously full initialization of that symbol,
+ // but that one shouldn't be necessary from the public API standpoint,
+ // because everything that matters auto-initializes at runtime,
+ // and auto-initialization at compile-time is anyway dubious
+ // (I've had spurious cyclic refs caused by calling typeSignature
+ // that initialized parent, which was in the middle of initialization).
+ //
+ // Given that and also given the pressure of being uniform with info and infoIn,
+ // I've removed calls to fullyInitializeSymbol from typeSignature and typeSignatureIn,
+ // injected fullyInitializeSymbol in showDecl, and injected fullyInitializeType in runtime Type.toString
+ // (the latter will make things a bit harder to debug in runtime universe, because
+ // toString might now very rarely cause cyclic references, but we also have showRaw that doesn't do initialization).
+ //
+ // Auto-initialization in runtime Type.toString is one of the examples of why a cake-based design
+ // isn't a very good idea for reflection API. Sometimes we want to same pretty name for both a compiler-facing
+ // and a user-facing API that should have different behaviors (other examples here include isPackage, isCaseClass, etc).
+ // Within a cake it's fundamentally impossible to achieve that.
+ def typeSignature: Type = info
+ def typeSignatureIn(site: Type): Type = site memberInfo this
def toType: Type = tpe
def toTypeIn(site: Type): Type = site.memberType(this)
def toTypeConstructor: Type = typeConstructor
- def setTypeSignature(tpe: Type): this.type = { setInfo(tpe); this }
def setAnnotations(annots: AnnotationInfo*): this.type = { setAnnotations(annots.toList); this }
def getter: Symbol = getter(owner)
def setter: Symbol = setter(owner)
+
+ def companion: Symbol = {
+ if (isModule && !isPackage) companionSymbol
+ else if (isModuleClass && !isPackageClass) sourceModule.companionSymbol
+ else if (isClass && !isModuleClass && !isPackageClass) companionSymbol
+ else NoSymbol
+ }
+
+ def infoIn(site: Type): Type = typeSignatureIn(site)
+ def overrides: List[Symbol] = allOverriddenSymbols
+ def paramLists: List[List[Symbol]] = paramss
}
private[reflect] case class SymbolKind(accurate: String, sanitized: String, abbreviation: String)
@@ -633,7 +671,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* (i.e. the pickle not only contains info about directly nested classes/modules, but also about
* classes/modules nested into those and so on).
*
- * Unpickling is triggered automatically whenever typeSignature (info in compiler parlance) is called.
+ * Unpickling is triggered automatically whenever info (info in compiler parlance) is called.
* This happens because package symbols assign completer thunks to the dummies they create.
* Therefore metadata loading happens lazily and transparently.
*
@@ -643,7 +681,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* produces incorrect results.
*
* One might think that the solution is simple: automatically call the completer
- * whenever one needs flags, annotations and privateWithin - just like it's done for typeSignature.
+ * whenever one needs flags, annotations and privateWithin - just like it's done for info.
* Unfortunately, this leads to weird crashes in scalac, and currently we can't attempt
* to fix the core of the compiler risk stability a few weeks before the final release.
* upd. Haha, "a few weeks before the final release". This surely sounds familiar :)
@@ -904,7 +942,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
|| isModuleOrModuleClass && (isTopLevel || !settings.overrideObjects)
|| isTerm && (
isPrivate
- || isLocal
+ || isLocalToBlock
|| isNotOverridden
)
)
@@ -912,9 +950,13 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Is this symbol owned by a package? */
final def isTopLevel = owner.isPackageClass
- /** Is this symbol locally defined? I.e. not accessed from outside `this` instance */
+ /** Is this symbol defined in a block? */
+ @deprecated("Use isLocalToBlock instead", "2.11.0")
final def isLocal: Boolean = owner.isTerm
+ /** Is this symbol defined in a block? */
+ final def isLocalToBlock: Boolean = owner.isTerm
+
/** Is this symbol a constant? */
final def isConstant: Boolean = isStable && isConstantType(tpe.resultType)
@@ -1257,7 +1299,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* as public.
*/
def accessBoundary(base: Symbol): Symbol = {
- if (hasFlag(PRIVATE) || isLocal) owner
+ if (hasFlag(PRIVATE) || isLocalToBlock) owner
else if (hasAllFlags(PROTECTED | STATIC | JAVA)) enclosingRootClass
else if (hasAccessBoundary && !phase.erasedTypes) privateWithin
else if (hasFlag(PROTECTED)) base
@@ -1861,7 +1903,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** The next enclosing method. */
def enclMethod: Symbol = if (isSourceMethod) this else owner.enclMethod
- /** The primary constructor of a class. */
def primaryConstructor: Symbol = NoSymbol
/** The self symbol (a TermSymbol) of a class with explicit self type, or else the
@@ -2272,7 +2313,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
* seen from class `base`. This symbol is always concrete.
* pre: `this.owner` is in the base class sequence of `base`.
*/
- final def superSymbol(base: Symbol): Symbol = {
+ @deprecated("Use `superSymbolIn` instead", "2.11.0")
+ final def superSymbol(base: Symbol): Symbol = superSymbolIn(base)
+
+ final def superSymbolIn(base: Symbol): Symbol = {
var bcs = base.info.baseClasses dropWhile (owner != _) drop 1
var sym: Symbol = NoSymbol
while (!bcs.isEmpty && sym == NoSymbol) {
@@ -2286,7 +2330,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** The getter of this value or setter definition in class `base`, or NoSymbol if
* none exists.
*/
- final def getter(base: Symbol): Symbol =
+ @deprecated("Use `getterIn` instead", "2.11.0")
+ final def getter(base: Symbol): Symbol = getterIn(base)
+
+ final def getterIn(base: Symbol): Symbol =
base.info decl getterName filter (_.hasAccessorFlag)
def getterName: TermName = name.getterName
@@ -2409,7 +2456,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else if (isClass) "class"
else if (isType && !isParameter) "type"
else if (isVariable) "var"
- else if (isPackage) "package"
+ else if (hasPackageFlag) "package"
else if (isModule) "object"
else if (isSourceMethod) "def"
else if (isTerm && (!isParameter || isParamAccessor)) "val"
@@ -2420,8 +2467,8 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
if (isTermMacro) ("term macro", "macro method", "MACM")
else if (isInstanceOf[FreeTermSymbol]) ("free term", "free term", "FTE")
else if (isInstanceOf[FreeTypeSymbol]) ("free type", "free type", "FTY")
- else if (isPackage) ("package", "package", "PK")
else if (isPackageClass) ("package class", "package", "PKC")
+ else if (isPackage) ("package", "package", "PK")
else if (isPackageObject) ("package object", "package", "PKO")
else if (isPackageObjectClass) ("package object class", "package", "PKOC")
else if (isAnonymousClass) ("anonymous class", "anonymous class", "AC")
@@ -2649,7 +2696,6 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
(infos ne null) && infos.info.isInstanceOf[OverloadedType]
)
***/
- override def isPackage = this hasFlag PACKAGE
override def isValueParameter = this hasFlag PARAM
override def isSetterParameter = isValueParameter && owner.isSetter
@@ -2822,13 +2868,15 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
}
loop(info)
}
+
+ override def exceptions = annotations flatMap ThrownException.unapply
}
implicit val MethodSymbolTag = ClassTag[MethodSymbol](classOf[MethodSymbol])
class AliasTypeSymbol protected[Symbols] (initOwner: Symbol, initPos: Position, initName: TypeName)
extends TypeSymbol(initOwner, initPos, initName) {
type TypeOfClonedSymbol = TypeSymbol
- override def variance = if (hasLocalFlag) Bivariant else info.typeSymbol.variance
+ override def variance = if (isLocalToThis) Bivariant else info.typeSymbol.variance
override def isContravariant = variance.isContravariant
override def isCovariant = variance.isCovariant
final override def isAliasType = true
@@ -3114,7 +3162,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
*/
override def isLocalClass = (
isAnonOrRefinementClass
- || isLocal
+ || isLocalToBlock
|| !isTopLevel && owner.isLocalClass
)
@@ -3139,13 +3187,16 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
override def primaryConstructor = {
val c = info decl primaryConstructorName
- if (c.isOverloaded) c.alternatives.head else c
+ if (isJavaDefined) NoSymbol // need to force info before checking the flag
+ else if (c.isOverloaded) c.alternatives.head else c
}
override def associatedFile = (
if (!isTopLevel) super.associatedFile
- else if (_associatedFile eq null) NoAbstractFile // guarantee not null, but save cost of initializing the var
- else _associatedFile
+ else {
+ if (_associatedFile eq null) NoAbstractFile // guarantee not null, but save cost of initializing the var
+ else _associatedFile
+ }
)
override def associatedFile_=(f: AbstractFile) { _associatedFile = f }
@@ -3354,11 +3405,16 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def origin: String
}
class FreeTermSymbol(name0: TermName, value0: => Any, val origin: String) extends TermSymbol(NoSymbol, NoPosition, name0) with FreeSymbol with FreeTermSymbolApi {
+ final override def isFreeTerm = true
+ final override def asFreeTerm = this
def value = value0
}
implicit val FreeTermSymbolTag = ClassTag[FreeTermSymbol](classOf[FreeTermSymbol])
- class FreeTypeSymbol(name0: TypeName, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) with FreeSymbol with FreeTypeSymbolApi
+ class FreeTypeSymbol(name0: TypeName, val origin: String) extends TypeSkolem(NoSymbol, NoPosition, name0, NoSymbol) with FreeSymbol with FreeTypeSymbolApi {
+ final override def isFreeType = true
+ final override def asFreeType = this
+ }
implicit val FreeTypeSymbolTag = ClassTag[FreeTypeSymbol](classOf[FreeTypeSymbol])
/** An object representing a missing symbol */
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index e7675eb4bf..6011289baf 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -6,7 +6,7 @@ import Flags._
import util._
import scala.collection.mutable.ListBuffer
-abstract class TreeGen extends macros.TreeBuilder {
+abstract class TreeGen {
val global: SymbolTable
import global._
@@ -186,7 +186,7 @@ abstract class TreeGen extends macros.TreeBuilder {
)
val needsPackageQualifier = (
(sym ne null)
- && qualsym.isPackage
+ && qualsym.hasPackageFlag
&& !(sym.isDefinedInPackage || sym.moduleClass.isDefinedInPackage) // SI-7817 work around strangeness in post-flatten `Symbol#owner`
)
val pkgQualifier =
@@ -893,4 +893,7 @@ abstract class TreeGen extends macros.TreeBuilder {
def mkSyntheticParam(pname: TermName) =
ValDef(Modifiers(PARAM | SYNTHETIC), pname, TypeTree(), EmptyTree)
+
+ def mkCast(tree: Tree, pt: Type): Tree =
+ atPos(tree.pos)(mkAsInstanceOf(tree, pt, any = true, wrapInApply = false))
}
diff --git a/src/reflect/scala/reflect/internal/Trees.scala b/src/reflect/scala/reflect/internal/Trees.scala
index 91e80f8989..7a6862a770 100644
--- a/src/reflect/scala/reflect/internal/Trees.scala
+++ b/src/reflect/scala/reflect/internal/Trees.scala
@@ -99,7 +99,7 @@ trait Trees extends api.Trees {
(duplicator transform this).asInstanceOf[this.type]
}
- abstract class TreeContextApiImpl extends TreeContextApi { this: Tree =>
+ abstract class TreeContextApiImpl extends TreeApi { this: Tree =>
override def orElse(alt: => Tree) = if (!isEmpty) this else alt
@@ -158,8 +158,8 @@ trait Trees extends api.Trees {
productIterator.toList flatMap subtrees
}
- override def freeTerms: List[FreeTermSymbol] = freeSyms[FreeTermSymbol](_.isFreeTerm, _.termSymbol)
- override def freeTypes: List[FreeTypeSymbol] = freeSyms[FreeTypeSymbol](_.isFreeType, _.typeSymbol)
+ def freeTerms: List[FreeTermSymbol] = freeSyms[FreeTermSymbol](_.isFreeTerm, _.termSymbol)
+ def freeTypes: List[FreeTypeSymbol] = freeSyms[FreeTypeSymbol](_.isFreeType, _.typeSymbol)
private def freeSyms[S <: Symbol](isFree: Symbol => Boolean, symOfType: Type => Symbol): List[S] = {
val s = mutable.LinkedHashSet[S]()
@@ -175,13 +175,13 @@ trait Trees extends api.Trees {
s.toList
}
- override def substituteSymbols(from: List[Symbol], to: List[Symbol]): Tree =
+ def substituteSymbols(from: List[Symbol], to: List[Symbol]): Tree =
new TreeSymSubstituter(from, to)(this)
- override def substituteTypes(from: List[Symbol], to: List[Type]): Tree =
+ def substituteTypes(from: List[Symbol], to: List[Type]): Tree =
new TreeTypeSubstituter(from, to)(this)
- override def substituteThis(clazz: Symbol, to: Tree): Tree =
+ def substituteThis(clazz: Symbol, to: Tree): Tree =
new ThisSubstituter(clazz, to) transform this
def hasExistingSymbol = (symbol ne null) && (symbol ne NoSymbol)
@@ -235,7 +235,7 @@ trait Trees extends api.Trees {
trait TypTree extends Tree with TypTreeApi
- abstract class SymTree extends Tree with SymTreeContextApi {
+ abstract class SymTree extends Tree with SymTreeApi {
override def hasSymbolField = true
override var symbol: Symbol = NoSymbol
}
@@ -296,14 +296,42 @@ trait Trees extends api.Trees {
case class ClassDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], impl: Template)
extends ImplDef with ClassDefApi
- object ClassDef extends ClassDefExtractor
+ object ClassDef extends ClassDefExtractor {
+ /** @param sym the class symbol
+ * @param impl the implementation template
+ * @return the class definition
+ */
+ def apply(sym: Symbol, impl: Template): ClassDef =
+ atPos(sym.pos) {
+ ClassDef(Modifiers(sym.flags),
+ sym.name.toTypeName,
+ sym.typeParams map TypeDef.apply,
+ impl) setSymbol sym
+ }
+
+ /** @param sym the class symbol
+ * @param body trees that constitute the body of the class
+ * @return the class definition
+ */
+ def apply(sym: Symbol, body: List[Tree]): ClassDef =
+ ClassDef(sym, Template(sym, body))
+ }
case class ModuleDef(mods: Modifiers, name: TermName, impl: Template)
extends ImplDef with ModuleDefApi
- object ModuleDef extends ModuleDefExtractor
+ object ModuleDef extends ModuleDefExtractor {
+ /**
+ * @param sym the class symbol
+ * @param impl the implementation template
+ */
+ def apply(sym: Symbol, impl: Template): ModuleDef =
+ atPos(sym.pos) {
+ ModuleDef(Modifiers(sym.flags), sym.name.toTermName, impl) setSymbol sym
+ }
+ }
abstract class ValOrDefDef extends MemberDef with ValOrDefDefApi {
- def name: Name
+ def name: TermName
def tpt: Tree
def rhs: Tree
}
@@ -317,19 +345,37 @@ trait Trees extends api.Trees {
}
case class ValDef(mods: Modifiers, name: TermName, tpt: Tree, rhs: Tree) extends ValOrDefDef with ValDefApi
- object ValDef extends ValDefExtractor
+ object ValDef extends ValDefExtractor {
+ def apply(sym: Symbol): ValDef = newValDef(sym, EmptyTree)()
+ def apply(sym: Symbol, rhs: Tree): ValDef = newValDef(sym, rhs)()
+ }
case class DefDef(mods: Modifiers, name: TermName, tparams: List[TypeDef],
vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree) extends ValOrDefDef with DefDefApi
- object DefDef extends DefDefExtractor
+ object DefDef extends DefDefExtractor {
+ def apply(sym: Symbol, rhs: Tree): DefDef = newDefDef(sym, rhs)()
+ def apply(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef = newDefDef(sym, rhs)(vparamss = vparamss)
+ def apply(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef = newDefDef(sym, rhs)(mods = mods)
+ def apply(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef = newDefDef(sym, rhs)(mods = mods, vparamss = vparamss)
+ def apply(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef = newDefDef(sym, rhs(sym.info.paramss))()
+ }
case class TypeDef(mods: Modifiers, name: TypeName, tparams: List[TypeDef], rhs: Tree)
extends MemberDef with TypeDefApi
- object TypeDef extends TypeDefExtractor
+ object TypeDef extends TypeDefExtractor {
+ /** A TypeDef node which defines abstract type or type parameter for given `sym` */
+ def apply(sym: Symbol): TypeDef = newTypeDef(sym, TypeBoundsTree(sym))()
+ def apply(sym: Symbol, rhs: Tree): TypeDef = newTypeDef(sym, rhs)()
+ }
case class LabelDef(name: TermName, params: List[Ident], rhs: Tree)
extends DefTree with TermTree with LabelDefApi
- object LabelDef extends LabelDefExtractor
+ object LabelDef extends LabelDefExtractor {
+ def apply(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef =
+ atPos(sym.pos) {
+ LabelDef(sym.name.toTermName, params map Ident, rhs) setSymbol sym
+ }
+ }
case class ImportSelector(name: Name, namePos: Int, rename: Name, renamePos: Int) extends ImportSelectorApi
object ImportSelector extends ImportSelectorExtractor {
@@ -488,7 +534,7 @@ trait Trees extends api.Trees {
}
object Select extends SelectExtractor
- case class Ident(name: Name) extends RefTree with IdentContextApi {
+ case class Ident(name: Name) extends RefTree with IdentApi {
def qualifier: Tree = EmptyTree
def isBackquoted = this.hasAttachment[BackquotedIdentifierAttachment.type]
}
@@ -545,7 +591,7 @@ trait Trees extends api.Trees {
extends TypTree with ExistentialTypeTreeApi
object ExistentialTypeTree extends ExistentialTypeTreeExtractor
- case class TypeTree() extends TypTree with TypeTreeContextApi {
+ case class TypeTree() extends TypTree with TypeTreeApi {
private var orig: Tree = null
/** Was this type tree originally empty? That is, does it now contain
* an inferred type that must be forgotten in `resetAttrs` to
@@ -590,14 +636,14 @@ trait Trees extends api.Trees {
def TypeTree(tp: Type): TypeTree = TypeTree() setType tp
private def TypeTreeMemberType(sym: Symbol): TypeTree = {
// Needed for pos/t4970*.scala. See SI-7853
- val resType = (if (sym.isLocal) sym.tpe else (sym.owner.thisType memberType sym)).finalResultType
+ val resType = (if (sym.isLocalToBlock) sym.tpe else (sym.owner.thisType memberType sym)).finalResultType
atPos(sym.pos.focus)(TypeTree(resType))
}
def TypeBoundsTree(bounds: TypeBounds): TypeBoundsTree = TypeBoundsTree(TypeTree(bounds.lo), TypeTree(bounds.hi))
def TypeBoundsTree(sym: Symbol): TypeBoundsTree = atPos(sym.pos)(TypeBoundsTree(sym.info.bounds))
- override type TreeCopier <: InternalTreeCopierOps
+ override type TreeCopier >: Null <: InternalTreeCopierOps
abstract class InternalTreeCopierOps extends TreeCopierOps {
def ApplyDynamic(tree: Tree, qual: Tree, args: List[Tree]): ApplyDynamic
def ArrayValue(tree: Tree, elemtpt: Tree, trees: List[Tree]): ArrayValue
@@ -676,6 +722,8 @@ trait Trees extends api.Trees {
new Select(qualifier, selector).copyAttrs(tree)
def Ident(tree: Tree, name: Name) =
new Ident(name) copyAttrs tree
+ def RefTree(tree: Tree, qualifier: Tree, selector: Name) =
+ self.RefTree(qualifier, selector) copyAttrs tree
def ReferenceToBoxed(tree: Tree, idt: Ident) =
new ReferenceToBoxed(idt).copyAttrs(tree)
def Literal(tree: Tree, value: Constant) =
@@ -866,6 +914,11 @@ trait Trees extends api.Trees {
if name0 == name => t
case _ => treeCopy.Ident(tree, name)
}
+ def RefTree(tree: Tree, qualifier: Tree, selector: Name) = tree match {
+ case t @ Select(qualifier0, selector0)
+ if (qualifier0 == qualifier) && (selector0 == selector) => t
+ case _ => treeCopy.RefTree(tree, qualifier, selector)
+ }
def ReferenceToBoxed(tree: Tree, idt: Ident) = tree match {
case t @ ReferenceToBoxed(idt0)
if (idt0 == idt) => t
@@ -1000,25 +1053,6 @@ trait Trees extends api.Trees {
// ---- values and creators ---------------------------------------
- /** @param sym the class symbol
- * @param impl the implementation template
- * @return the class definition
- */
- def ClassDef(sym: Symbol, impl: Template): ClassDef =
- atPos(sym.pos) {
- ClassDef(Modifiers(sym.flags),
- sym.name.toTypeName,
- sym.typeParams map TypeDef,
- impl) setSymbol sym
- }
-
- /** @param sym the class symbol
- * @param body trees that constitute the body of the class
- * @return the class definition
- */
- def ClassDef(sym: Symbol, body: List[Tree]): ClassDef =
- ClassDef(sym, Template(sym, body))
-
/** @param sym the template's symbol
* @param body trees that constitute the body of the template
* @return the template
@@ -1031,15 +1065,6 @@ trait Trees extends api.Trees {
}
}
- /**
- * @param sym the class symbol
- * @param impl the implementation template
- */
- def ModuleDef(sym: Symbol, impl: Template): ModuleDef =
- atPos(sym.pos) {
- ModuleDef(Modifiers(sym.flags), sym.name.toTermName, impl) setSymbol sym
- }
-
trait CannotHaveAttrs extends Tree {
super.setPos(NoPosition)
super.setType(NoType)
@@ -1076,8 +1101,8 @@ trait Trees extends api.Trees {
def newDefDef(sym: Symbol, rhs: Tree)(
mods: Modifiers = Modifiers(sym.flags),
name: TermName = sym.name.toTermName,
- tparams: List[TypeDef] = sym.typeParams map TypeDef,
- vparamss: List[List[ValDef]] = mapParamss(sym)(ValDef),
+ tparams: List[TypeDef] = sym.typeParams map TypeDef.apply,
+ vparamss: List[List[ValDef]] = mapParamss(sym)(ValDef.apply),
tpt: Tree = TypeTreeMemberType(sym)
): DefDef = (
atPos(sym.pos)(DefDef(mods, name, tparams, vparamss, tpt, rhs)) setSymbol sym
@@ -1086,29 +1111,11 @@ trait Trees extends api.Trees {
def newTypeDef(sym: Symbol, rhs: Tree)(
mods: Modifiers = Modifiers(sym.flags),
name: TypeName = sym.name.toTypeName,
- tparams: List[TypeDef] = sym.typeParams map TypeDef
+ tparams: List[TypeDef] = sym.typeParams map TypeDef.apply
): TypeDef = (
atPos(sym.pos)(TypeDef(mods, name, tparams, rhs)) setSymbol sym
)
- def DefDef(sym: Symbol, rhs: Tree): DefDef = newDefDef(sym, rhs)()
- def DefDef(sym: Symbol, vparamss: List[List[ValDef]], rhs: Tree): DefDef = newDefDef(sym, rhs)(vparamss = vparamss)
- def DefDef(sym: Symbol, mods: Modifiers, rhs: Tree): DefDef = newDefDef(sym, rhs)(mods = mods)
- def DefDef(sym: Symbol, mods: Modifiers, vparamss: List[List[ValDef]], rhs: Tree): DefDef = newDefDef(sym, rhs)(mods = mods, vparamss = vparamss)
- def DefDef(sym: Symbol, rhs: List[List[Symbol]] => Tree): DefDef = newDefDef(sym, rhs(sym.info.paramss))()
-
- def ValDef(sym: Symbol): ValDef = newValDef(sym, EmptyTree)()
- def ValDef(sym: Symbol, rhs: Tree): ValDef = newValDef(sym, rhs)()
-
- /** A TypeDef node which defines abstract type or type parameter for given `sym` */
- def TypeDef(sym: Symbol): TypeDef = newTypeDef(sym, TypeBoundsTree(sym))()
- def TypeDef(sym: Symbol, rhs: Tree): TypeDef = newTypeDef(sym, rhs)()
-
- def LabelDef(sym: Symbol, params: List[Symbol], rhs: Tree): LabelDef =
- atPos(sym.pos) {
- LabelDef(sym.name.toTermName, params map Ident, rhs) setSymbol sym
- }
-
/** casedef shorthand */
def CaseDef(pat: Tree, body: Tree): CaseDef =
CaseDef(pat, EmptyTree, body)
@@ -1851,8 +1858,8 @@ trait Trees extends api.Trees {
implicit val NameTreeTag = ClassTag[NameTree](classOf[NameTree])
implicit val NewTag = ClassTag[New](classOf[New])
implicit val PackageDefTag = ClassTag[PackageDef](classOf[PackageDef])
- implicit val RefTreeTag = ClassTag[RefTree](classOf[RefTree])
implicit val ReferenceToBoxedTag = ClassTag[ReferenceToBoxed](classOf[ReferenceToBoxed])
+ implicit val RefTreeTag = ClassTag[RefTree](classOf[RefTree])
implicit val ReturnTag = ClassTag[Return](classOf[Return])
implicit val SelectFromTypeTreeTag = ClassTag[SelectFromTypeTree](classOf[SelectFromTypeTree])
implicit val SelectTag = ClassTag[Select](classOf[Select])
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index ac6c6f67c0..e9e5a89aa7 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -195,6 +195,7 @@ trait Types
override def instantiateTypeParams(formals: List[Symbol], actuals: List[Type]) = underlying.instantiateTypeParams(formals, actuals)
override def skolemizeExistential(owner: Symbol, origin: AnyRef) = underlying.skolemizeExistential(owner, origin)
override def normalize = maybeRewrap(underlying.normalize)
+ override def etaExpand = maybeRewrap(underlying.etaExpand)
override def dealias = maybeRewrap(underlying.dealias)
override def cloneInfo(owner: Symbol) = maybeRewrap(underlying.cloneInfo(owner))
override def atOwner(owner: Symbol) = maybeRewrap(underlying.atOwner(owner))
@@ -243,6 +244,16 @@ trait Types
def isSpliceable = {
this.isInstanceOf[TypeRef] && typeSymbol.isAbstractType && !typeSymbol.isExistential
}
+
+ def companion = {
+ val sym = typeSymbolDirect
+ if (sym.isModule && !sym.isPackage) sym.companionSymbol.tpe
+ else if (sym.isModuleClass && !sym.isPackageClass) sym.sourceModule.companionSymbol.tpe
+ else if (sym.isClass && !sym.isModuleClass && !sym.isPackageClass) sym.companionSymbol.info
+ else NoType
+ }
+
+ def paramLists: List[List[Symbol]] = paramss
}
/** The base class for all types */
@@ -499,6 +510,8 @@ trait Types
*/
def normalize = this // @MAT
+ def etaExpand = this
+
/** Expands type aliases. */
def dealias = this
@@ -908,7 +921,11 @@ trait Types
* after `maxTostringRecursions` recursion levels. Uses `safeToString`
* to produce a string on each level.
*/
- override final def toString: String = typeToString(this)
+ override final def toString: String = {
+ // see comments to internal#Symbol.typeSignature for an explanation why this initializes
+ if (!isCompilerUniverse) fullyInitializeType(this)
+ typeToString(this)
+ }
/** Method to be implemented in subclasses.
* Converts this type to a string in calling toString for its parts.
@@ -1056,7 +1073,7 @@ trait Types
/** A base class for types that represent a single value
* (single-types and this-types).
*/
- abstract class SingletonType extends SubType with SimpleTypeProxy {
+ abstract class SingletonType extends SubType with SimpleTypeProxy with SingletonTypeApi {
def supertype = underlying
override def isTrivial = false
override def widen: Type = underlying.widen
@@ -1324,7 +1341,7 @@ trait Types
/** A common base class for intersection types and class types
*/
- abstract class CompoundType extends Type {
+ abstract class CompoundType extends Type with CompoundTypeApi {
private[reflect] var baseTypeSeqCache: BaseTypeSeq = _
private[reflect] var baseTypeSeqPeriod = NoPeriod
@@ -1590,20 +1607,27 @@ trait Types
} else if (flattened != parents) {
refinedType(flattened, if (typeSymbol eq NoSymbol) NoSymbol else typeSymbol.owner, decls, NoPosition)
} else if (isHigherKinded) {
- // MO to AM: This is probably not correct
- // If they are several higher-kinded parents with different bounds we need
- // to take the intersection of their bounds
- typeFun(
- typeParams,
- RefinedType(
- parents map {
- case TypeRef(pre, sym, List()) => TypeRef(pre, sym, dummyArgs)
- case p => p
- },
- decls,
- typeSymbol))
+ etaExpand
} else super.normalize
}
+
+ final override def etaExpand: Type = {
+ // MO to AM: This is probably not correct
+ // If they are several higher-kinded parents with different bounds we need
+ // to take the intersection of their bounds
+ // !!! inconsistent with TypeRef.etaExpand that uses initializedTypeParams
+ if (!isHigherKinded) this
+ else typeFun(
+ typeParams,
+ RefinedType(
+ parents map {
+ case TypeRef(pre, sym, List()) => TypeRef(pre, sym, dummyArgs)
+ case p => p
+ },
+ decls,
+ typeSymbol))
+ }
+
override def kind = "RefinedType"
}
@@ -2153,7 +2177,7 @@ trait Types
|| pre.isGround && args.forall(_.isGround)
)
- def etaExpand: Type = {
+ final override def etaExpand: Type = {
// must initialise symbol, see test/files/pos/ticket0137.scala
val tpars = initializedTypeParams
if (tpars.isEmpty) this
@@ -3155,9 +3179,13 @@ trait Types
if (instValid) inst
// get here when checking higher-order subtyping of the typevar by itself
// TODO: check whether this ever happens?
- else if (isHigherKinded) logResult("Normalizing HK $this")(typeFun(params, applyArgs(params map (_.typeConstructor))))
+ else if (isHigherKinded) etaExpand
else super.normalize
)
+ override def etaExpand: Type = (
+ if (!isHigherKinded) this
+ else logResult("Normalizing HK $this")(typeFun(params, applyArgs(params map (_.typeConstructor))))
+ )
override def typeSymbol = origin.typeSymbol
private def tparamsOfSym(sym: Symbol) = sym.info match {
@@ -3532,6 +3560,12 @@ trait Types
}
}
+ def appliedType(tycon: Type, args: Type*): Type =
+ appliedType(tycon, args.toList)
+
+ def appliedType(tyconSym: Symbol, args: List[Type]): Type =
+ appliedType(tyconSym.typeConstructor, args)
+
/** Very convenient. */
def appliedType(tyconSym: Symbol, args: Type*): Type =
appliedType(tyconSym.typeConstructor, args.toList)
diff --git a/src/reflect/scala/reflect/internal/Variances.scala b/src/reflect/scala/reflect/internal/Variances.scala
index 659bfb5d01..3bcfed7d34 100644
--- a/src/reflect/scala/reflect/internal/Variances.scala
+++ b/src/reflect/scala/reflect/internal/Variances.scala
@@ -33,10 +33,10 @@ trait Variances {
/** Is every symbol in the owner chain between `site` and the owner of `sym`
* either a term symbol or private[this]? If not, add `sym` to the set of
* esacped locals.
- * @pre sym.hasLocalFlag
+ * @pre sym.isLocalToThis
*/
@tailrec final def checkForEscape(sym: Symbol, site: Symbol) {
- if (site == sym.owner || site == sym.owner.moduleClass || site.isPackage) () // done
+ if (site == sym.owner || site == sym.owner.moduleClass || site.hasPackageFlag) () // done
else if (site.isTerm || site.isPrivateLocal) checkForEscape(sym, site.owner) // ok - recurse to owner
else escapedLocals += sym
}
@@ -53,8 +53,8 @@ trait Variances {
// return Bivariant if `sym` is local to a term
// or is private[this] or protected[this]
def isLocalOnly(sym: Symbol) = !sym.owner.isClass || (
- sym.isTerm
- && (sym.hasLocalFlag || sym.isSuperAccessor) // super accessors are implicitly local #4345
+ sym.isTerm // ?? shouldn't this be sym.owner.isTerm according to the comments above?
+ && (sym.isLocalToThis || sym.isSuperAccessor) // super accessors are implicitly local #4345
&& !escapedLocals(sym)
)
@@ -144,7 +144,7 @@ trait Variances {
// Or constructors, or case class factory or extractor.
def skip = (
sym == NoSymbol
- || sym.hasLocalFlag
+ || sym.isLocalToThis
|| sym.owner.isConstructor
|| sym.owner.isCaseApplyOrUnapply
)
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
index 0cd0387670..f06420de96 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
@@ -1100,7 +1100,7 @@ private[internal] trait TypeMaps {
tp
}
case SingleType(pre, sym) =>
- if (sym.isPackage) tp
+ if (sym.hasPackageFlag) tp
else {
val pre1 = this(pre)
try {
diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala
index 786ff2210c..d5b5967145 100644
--- a/src/reflect/scala/reflect/internal/transform/Erasure.scala
+++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala
@@ -74,7 +74,7 @@ trait Erasure {
//
// This requires that cls.isClass.
protected def rebindInnerClass(pre: Type, cls: Symbol): Type =
- if (cls.isTopLevel || cls.isLocal) pre else cls.owner.tpe_*
+ if (cls.isTopLevel || cls.isLocalToBlock) pre else cls.owner.tpe_*
/** The type of the argument of a value class reference after erasure
* This method needs to be called at a phase no later than erasurephase
diff --git a/src/reflect/scala/reflect/internal/util/Position.scala b/src/reflect/scala/reflect/internal/util/Position.scala
index f3eedb88e7..0192d31806 100644
--- a/src/reflect/scala/reflect/internal/util/Position.scala
+++ b/src/reflect/scala/reflect/internal/util/Position.scala
@@ -8,43 +8,7 @@ package reflect
package internal
package util
-/** The Position class and its subclasses represent positions of ASTs and symbols.
- * Every subclass of DefinedPosition refers to a SourceFile and three character
- * offsets within it: start, end, and point. The point is where the ^ belongs when
- * issuing an error message, usually a Name. A range position can be designated
- * as transparent, which excuses it from maintaining the invariants to follow. If
- * a transparent position has opaque children, those are considered as if they were
- * the direct children of the transparent position's parent.
- *
- * Note: some of these invariants actually apply to the trees which carry
- * the positions, but they are phrased as if the positions themselves were
- * the parent/children for conciseness.
- *
- * Invariant 1: in a focused/offset position, start == point == end
- * Invariant 2: in a range position, start <= point < end
- * Invariant 3: an offset position never has a child with a range position
- * Invariant 4: every range position child of a range position parent is contained within its parent
- * Invariant 5: opaque range position siblings overlap at most at a single point
- *
- * The following tests are useful on positions:
- *
- * pos.isDefined true if position is not an UndefinedPosition (those being NoPosition and FakePos)
- * pos.isRange true if position is a range (opaque or transparent) which implies start < end
- * pos.isOpaqueRange true if position is an opaque range
- *
- * The following accessor methods are provided - an exception will be thrown if
- * point/start/end are attempted on an UndefinedPosition.
- *
- * pos.source The source file of the position, or NoSourceFile if unavailable
- * pos.point The offset of the point
- * pos.start The (inclusive) start offset, or the point of an offset position
- * pos.end The (exclusive) end offset, or the point of an offset position
- *
- * The following conversion methods are often used:
- *
- * pos.focus Converts a range position to an offset position focused on the point
- * pos.makeTransparent Convert an opaque range into a transparent range
- */
+/** @inheritdoc */
class Position extends scala.reflect.api.Position with InternalPositionImpl with DeprecatedPosition {
type Pos = Position
def pos: Position = this
diff --git a/src/reflect/scala/reflect/io/NoAbstractFile.scala b/src/reflect/scala/reflect/io/NoAbstractFile.scala
index a4e869ed41..18eca7698d 100644
--- a/src/reflect/scala/reflect/io/NoAbstractFile.scala
+++ b/src/reflect/scala/reflect/io/NoAbstractFile.scala
@@ -31,4 +31,5 @@ object NoAbstractFile extends AbstractFile {
def output: java.io.OutputStream = null
def path: String = ""
override def toByteArray = Array[Byte]()
+ override def toString = "<no file>"
}
diff --git a/src/reflect/scala/reflect/macros/Aliases.scala b/src/reflect/scala/reflect/macros/Aliases.scala
index d2b878d081..64819a8601 100644
--- a/src/reflect/scala/reflect/macros/Aliases.scala
+++ b/src/reflect/scala/reflect/macros/Aliases.scala
@@ -116,4 +116,9 @@ trait Aliases {
* Shortcut for `implicitly[TypeTag[T]].tpe`
*/
def typeOf[T](implicit ttag: TypeTag[T]): Type = ttag.tpe
+
+ /**
+ * Type symbol of `x` as derived from a type tag.
+ */
+ def symbolOf[T: WeakTypeTag]: universe.TypeSymbol = universe.symbolOf[T]
}
diff --git a/src/reflect/scala/reflect/macros/Enclosures.scala b/src/reflect/scala/reflect/macros/Enclosures.scala
index 1ced2e54c6..69ede42cc7 100644
--- a/src/reflect/scala/reflect/macros/Enclosures.scala
+++ b/src/reflect/scala/reflect/macros/Enclosures.scala
@@ -20,7 +20,8 @@ import scala.language.existentials // SI-6541
* This is somewhat aligned with the overall evolution of macros during the 2.11 development cycle, where we played with
* `c.introduceTopLevel` and `c.introduceMember`, but at the end of the day decided to reject them.
*
- * If you're relying on the now deprecated APIs, consider reformulating your macros in terms of completely local expansion
+ * If you're relying on the now deprecated APIs, consider using the new [[c.internal.enclosingOwner]] method that can be used to obtain
+ * the names of enclosing definitions. Alternatively try reformulating your macros in terms of completely local expansion
* and/or joining a discussion of a somewhat related potential language feature at [[https://groups.google.com/forum/#!topic/scala-debate/f4CLmYShX6Q]].
* We also welcome questions and suggestions on our mailing lists, where we would be happy to further discuss this matter.
*/
diff --git a/src/reflect/scala/reflect/macros/Internals.scala b/src/reflect/scala/reflect/macros/Internals.scala
new file mode 100644
index 0000000000..75164344da
--- /dev/null
+++ b/src/reflect/scala/reflect/macros/Internals.scala
@@ -0,0 +1,79 @@
+package scala
+package reflect
+package macros
+
+/**
+ * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
+ * @see [[scala.reflect.api.Internals]]
+ */
+trait Internals {
+ self: blackbox.Context =>
+
+ /** @see [[scala.reflect.api.Internals]] */
+ val internal: ContextInternalApi
+
+ /** @see [[scala.reflect.api.Internals]] */
+ trait ContextInternalApi extends universe.MacroInternalApi {
+ /** Symbol associated with the innermost enclosing lexical context.
+ * Walking the owner chain of this symbol will reveal information about more and more enclosing contexts.
+ */
+ def enclosingOwner: Symbol
+
+ /** Functions that are available during [[transform]].
+ * @see [[transform]]
+ */
+ trait TransformApi {
+ /** Calls the current transformer on the given tree.
+ * Current transformer = argument to the `transform` call.
+ */
+ def recur(tree: Tree): Tree
+
+ /** Calls the default transformer on the given tree.
+ * Default transformer = recur into tree's children and assemble the results.
+ */
+ def default(tree: Tree): Tree
+ }
+
+ /** Transforms a given tree using the provided function.
+ * @see [[TransformApi]]
+ */
+ // TODO: explore a more concise notation that Denys and I discussed today
+ // when transformer is PartialFunction[Tree, Tree]] and TransformApi is passed magically
+ // also cf. https://github.com/dsl-paradise/dsl-paradise
+ def transform(tree: Tree)(transformer: (Tree, TransformApi) => Tree): Tree
+
+ /** Functions that are available during [[typingTransform]].
+ * @see [[typingTransform]]
+ */
+ trait TypingTransformApi extends TransformApi {
+ /** Temporarily pushes the given symbol onto the owner stack, creating a new local typer,
+ * invoke the given operation and then rollback the changes to the owner stack.
+ */
+ def atOwner[T](owner: Symbol)(op: => T): T
+
+ /** Temporarily pushes the given tree onto the recursion stack, and then calls `atOwner(symbol)(trans)`.
+ */
+ def atOwner[T](tree: Tree, owner: Symbol)(op: => T): T
+
+ /** Returns the symbol currently on the top of the owner stack.
+ * If we're not inside any `atOwner` call, then macro application's context owner will be used.
+ */
+ def currentOwner: Symbol
+
+ /** Typechecks the given tree using the local typer currently on the top of the owner stack.
+ * If we're not inside any `atOwner` call, then macro application's callsite typer will be used.
+ */
+ def typecheck(tree: Tree): Tree
+ }
+
+ /** Transforms a given tree using the provided function.
+ * @see [[TypingTransformApi]]
+ */
+ def typingTransform(tree: Tree)(transformer: (Tree, TypingTransformApi) => Tree): Tree
+
+ /** Transforms a given tree at a given owner using the provided function.
+ * @see [[TypingTransformApi]]
+ */
+ def typingTransform(tree: Tree, owner: Symbol)(transformer: (Tree, TypingTransformApi) => Tree): Tree
+ }
+}
diff --git a/src/reflect/scala/reflect/macros/Reifiers.scala b/src/reflect/scala/reflect/macros/Reifiers.scala
index ff1f7a3b28..e35a5c8622 100644
--- a/src/reflect/scala/reflect/macros/Reifiers.scala
+++ b/src/reflect/scala/reflect/macros/Reifiers.scala
@@ -15,7 +15,7 @@ trait Reifiers {
* 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 `universe.treeBuild.mkRuntimeUniverseRef`.
+ * Possible values for `universe` include `universe.internal.gen.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.
diff --git a/src/reflect/scala/reflect/macros/TreeBuilder.scala b/src/reflect/scala/reflect/macros/TreeBuilder.scala
deleted file mode 100644
index 7f57274347..0000000000
--- a/src/reflect/scala/reflect/macros/TreeBuilder.scala
+++ /dev/null
@@ -1,97 +0,0 @@
-package scala
-package reflect
-package macros
-
-/**
- * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
- *
- * A helper available in [[scala.reflect.macros.Universe]] that defines shorthands for the
- * most common tree-creating functions.
- */
-@deprecated("Use quasiquotes instead", "2.11.0")
-abstract class TreeBuilder {
- val global: Universe
-
- import global._
-
- /** Builds a reference to value whose type is given stable prefix.
- * The type must be suitable for this. For example, it
- * must not be a TypeRef pointing to an abstract type variable.
- */
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkAttributedQualifier(tpe: Type): Tree
-
- /** Builds a reference to value whose type is given stable prefix.
- * If the type is unsuitable, e.g. it is a TypeRef for an
- * abstract type variable, then an Ident will be made using
- * termSym as the Ident's symbol. In that case, termSym must
- * not be NoSymbol.
- */
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree
-
- /** Builds a typed reference to given symbol with given stable prefix. */
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkAttributedRef(pre: Type, sym: Symbol): RefTree
-
- /** Builds a typed reference to given symbol. */
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkAttributedRef(sym: Symbol): RefTree
-
- /** Builds an untyped reference to given symbol. Requires the symbol to be static. */
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkUnattributedRef(sym: Symbol): RefTree
-
- /** Builds an untyped reference to symbol with given name. Requires the symbol to be static. */
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkUnattributedRef(fullName: Name): RefTree
-
- /** Builds a typed This reference to given symbol. */
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkAttributedThis(sym: Symbol): This
-
- /** Builds a typed Ident with an underlying symbol. */
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkAttributedIdent(sym: Symbol): RefTree
-
- /** Builds a typed Select with an underlying symbol. */
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkAttributedSelect(qual: Tree, sym: Symbol): RefTree
-
- /** A creator for method calls, e.g. fn[T1, T2, ...](v1, v2, ...)
- * There are a number of variations.
- *
- * @param receiver symbol of the method receiver
- * @param methodName name of the method to call
- * @param targs type arguments (if Nil, no TypeApply node will be generated)
- * @param args value arguments
- * @return the newly created trees.
- */
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkMethodCall(receiver: Symbol, methodName: Name, targs: List[Type], args: List[Tree]): Tree
-
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkMethodCall(method: Symbol, targs: List[Type], args: List[Tree]): Tree
-
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkMethodCall(method: Symbol, args: List[Tree]): Tree
-
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkMethodCall(target: Tree, args: List[Tree]): Tree
-
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkMethodCall(receiver: Symbol, methodName: Name, args: List[Tree]): Tree
-
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkMethodCall(receiver: Tree, method: Symbol, targs: List[Type], args: List[Tree]): Tree
-
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkMethodCall(target: Tree, targs: List[Type], args: List[Tree]): Tree
-
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkNullaryCall(method: Symbol, targs: List[Type]): Tree
-
- /** A tree that refers to the runtime reflexive universe, `scala.reflect.runtime.universe`. */
- @deprecated("Use quasiquotes instead", "2.11.0")
- def mkRuntimeUniverseRef: Tree
-}
diff --git a/src/reflect/scala/reflect/macros/Typers.scala b/src/reflect/scala/reflect/macros/Typers.scala
index 6c077de1d2..d0dccb469d 100644
--- a/src/reflect/scala/reflect/macros/Typers.scala
+++ b/src/reflect/scala/reflect/macros/Typers.scala
@@ -2,6 +2,8 @@ package scala
package reflect
package macros
+import scala.reflect.internal.{Mode => InternalMode}
+
/**
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
*
@@ -23,13 +25,43 @@ trait Typers {
*/
def openMacros: List[blackbox.Context]
+ /** Represents mode of operations of the typechecker underlying `c.typecheck` calls.
+ * Is necessary since the shape of the typechecked tree alone is not enough to guess how it should be typechecked.
+ * Can be EXPRmode (typecheck as a term), TYPEmode (typecheck as a type) or PATTERNmode (typecheck as a pattern).
+ */
+ // I'd very much like to make use of https://github.com/dsl-paradise/dsl-paradise here!
+ type TypecheckMode
+
+ /** Indicates that an argument to `c.typecheck` should be typechecked as a term.
+ * This is the default typechecking mode in Scala 2.11 and the only one supported in Scala 2.10.
+ */
+ val TERMmode: TypecheckMode
+
+ /** Indicates that an argument to `c.typecheck` should be typechecked as a type.
+ */
+ val TYPEmode: TypecheckMode
+
+ /** Indicates that an argument to `c.typecheck` should be typechecked as a pattern.
+ */
+ val PATTERNmode: TypecheckMode
+
+ /** @see `scala.reflect.macros.TypecheckException`
+ */
+ type TypecheckException = scala.reflect.macros.TypecheckException
+
+ /** @see `scala.reflect.macros.TypecheckException`
+ */
+ val TypecheckException = scala.reflect.macros.TypecheckException
+
/** @see `Typers.typecheck`
*/
@deprecated("Use `c.typecheck` instead", "2.11.0")
def typeCheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree =
- typecheck(tree, pt, silent, withImplicitViewsDisabled, withMacrosDisabled)
+ typecheck(tree, TERMmode, pt, silent, withImplicitViewsDisabled, withMacrosDisabled)
- /** Typechecks the provided tree against the expected type `pt` in the macro callsite context.
+ /** Typechecks the provided tree against the expected type `pt` in the macro callsite context
+ * under typechecking mode specified in `mode` with [[EXPRmode]] being default.
+ * This populates symbols and types of the tree and possibly transforms it to reflect certain desugarings.
*
* If `silent` is false, `TypecheckException` will be thrown in case of a typecheck error.
* If `silent` is true, the typecheck is silent and will return `EmptyTree` if an error occurs.
@@ -42,7 +74,7 @@ trait Typers {
*
* @throws [[scala.reflect.macros.TypecheckException]]
*/
- def typecheck(tree: Tree, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree
+ def typecheck(tree: Tree, mode: TypecheckMode = TERMmode, pt: Type = universe.WildcardType, silent: Boolean = false, withImplicitViewsDisabled: Boolean = false, withMacrosDisabled: Boolean = false): Tree
/** Infers an implicit value of the expected type `pt` in the macro callsite context.
* Optional `pos` parameter provides a position that will be associated with the implicit search.
diff --git a/src/reflect/scala/reflect/macros/Universe.scala b/src/reflect/scala/reflect/macros/Universe.scala
index bc5c8b2840..1eb67215bb 100644
--- a/src/reflect/scala/reflect/macros/Universe.scala
+++ b/src/reflect/scala/reflect/macros/Universe.scala
@@ -2,6 +2,9 @@ package scala
package reflect
package macros
+import scala.language.implicitConversions
+import scala.language.higherKinds
+
/**
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
*
@@ -17,109 +20,93 @@ package macros
*/
abstract class Universe extends scala.reflect.api.Universe {
- /** A factory that encapsulates common tree-building functions.
- * @group Macros
- */
- @deprecated("Use quasiquotes instead", "2.11.0")
- val treeBuild: TreeBuilder { val global: Universe.this.type }
+ /** @inheritdoc */
+ override type Internal <: MacroInternalApi
- /** The API of reflection artifacts that support [[scala.reflect.macros.Attachments]].
- * These artifacts are trees and symbols.
- * @group Macros
- */
- trait AttachableApi {
- /** The attachment of the reflection artifact. */
- def attachments: Attachments { type Pos = Position }
+ /** @inheritdoc */
+ trait MacroInternalApi extends InternalApi { internal =>
- /** Updates the attachment with the payload slot of T added/updated with the provided value.
- * Replaces an existing payload of the same type, if exists.
- * Returns the reflection artifact itself.
+ /** Adds a given symbol to the given scope.
*/
- def updateAttachment[T: ClassTag](attachment: T): AttachableApi.this.type
+ def enter(scope: Scope, sym: Symbol): scope.type
- /** Update the attachment with the payload of the given class type `T` removed.
- * Returns the reflection artifact itself.
+ /** Removes a given symbol to the given scope.
*/
- def removeAttachment[T: ClassTag]: AttachableApi.this.type
- }
+ def unlink(scope: Scope, sym: Symbol): scope.type
- // Symbol extensions ---------------------------------------------------------------
+ /** Collects all the symbols defined by subtrees of `tree` that are owned by `prev`,
+ * and then changes their owner to point to `next`.
+ *
+ * This is an essential tool to battle owner chain corruption when moving trees
+ * from one lexical context to another. Whenever you take an attributed tree that
+ * has been typechecked under the Context owned by some symbol (let's call it `x`)
+ * and splice it elsewhere, into the Context owned by another symbol (let's call it `y`),
+ * it is imperative that you either call `untypecheck` or do `changeOwner(tree, x, y)`.
+ *
+ * Since at the moment `untypecheck` has fundamental problem that can sometimes lead to tree corruption,
+ * `changeOwner` becomes an indispensible tool in building 100% robust macros.
+ * Future versions of the reflection API might obviate the need in taking care of
+ * these low-level details, but at the moment this is what we've got.
+ */
+ def changeOwner(tree: Tree, prev: Symbol, next: Symbol): tree.type
- /** The `Symbol` API is extended for macros: See [[SymbolContextApi]] for details.
- *
- * @group Macros
- */
- override type Symbol >: Null <: SymbolContextApi
+ /** Advanced tree factories */
+ val gen: TreeGen
- /** The extended API of symbols that's supported in macro context universes
- * @group API
- */
- trait SymbolContextApi extends SymbolApi with AttachableApi { self: Symbol =>
+ /** The attachment of the symbol. */
+ def attachments(symbol: Symbol): Attachments { type Pos = Position }
- /** If this symbol is a skolem, its corresponding type parameter, otherwise the symbol itself.
- *
- * [[https://groups.google.com/forum/#!msg/scala-internals/0j8laVNTQsI/kRXMF_c8bGsJ To quote Martin Odersky]],
- * skolems are synthetic type "constants" that are copies of existentially bound or universally
- * bound type variables. E.g. if one is inside the right-hand side of a method:
- *
- * {{{
- * def foo[T](x: T) = ... foo[List[T]]....
- * }}}
- *
- * the skolem named `T` refers to the unknown type instance of `T` when `foo` is called. It needs to be different
- * from the type parameter because in a recursive call as in the `foo[List[T]]` above the type parameter gets
- * substituted with `List[T]`, but the ''type skolem'' stays what it is.
- *
- * The other form of skolem is an ''existential skolem''. Say one has a function
- *
- * {{{
- * def bar(xs: List[T] forSome { type T }) = xs.head
- * }}}
- *
- * then each occurrence of `xs` on the right will have type `List[T']` where `T'` is a fresh copy of `T`.
+ /** Updates the attachment with the payload slot of T added/updated with the provided value.
+ * Replaces an existing payload of the same type, if exists.
+ * Returns the symbol itself.
*/
- def deSkolemize: Symbol
+ def updateAttachment[T: ClassTag](symbol: Symbol, attachment: T): symbol.type
- /** The position of this symbol. */
- def pos: Position
+ /** Update the attachment with the payload of the given class type `T` removed.
+ * Returns the symbol itself.
+ */
+ def removeAttachment[T: ClassTag](symbol: Symbol): symbol.type
+
+ /** Sets the `owner` of the symbol. */
+ def setOwner(symbol: Symbol, newowner: Symbol): symbol.type
- /** Sets the `typeSignature` of the symbol. */
- def setTypeSignature(tpe: Type): Symbol
+ /** Sets the `info` of the symbol. */
+ def setInfo(symbol: Symbol, tpe: Type): symbol.type
/** Sets the `annotations` of the symbol. */
- def setAnnotations(annots: Annotation*): Symbol
+ def setAnnotations(symbol: Symbol, annots: Annotation*): symbol.type
/** Sets the `name` of the symbol. */
- def setName(name: Name): Symbol
+ def setName(symbol: Symbol, name: Name): symbol.type
/** Sets the `privateWithin` of the symbol. */
- def setPrivateWithin(sym: Symbol): Symbol
- }
+ def setPrivateWithin(symbol: Symbol, sym: Symbol): symbol.type
- // Tree extensions ---------------------------------------------------------------
+ /** Enables `flags` on the symbol. */
+ def setFlag(symbol: Symbol, flags: FlagSet): symbol.type
- /** The `Tree` API is extended for macros: See [[TreeContextApi]] for details.
- *
- * @group Macros
- */
- override type Tree >: Null <: TreeContextApi
+ /** Disables `flags` on the symbol. */
+ def resetFlag(symbol: Symbol, flags: FlagSet): symbol.type
- /** The extended API of trees that's supported in macro context universes
- * @group API
- */
- trait TreeContextApi extends TreeApi with AttachableApi { self: Tree =>
+ /** The attachment of the tree. */
+ def attachments(tree: Tree): Attachments { type Pos = Position }
- /** Sets the `pos` of the tree. Returns `Unit`. */
- def pos_=(pos: Position): Unit
+ /** Updates the attachment with the payload slot of T added/updated with the provided value.
+ * Replaces an existing payload of the same type, if exists.
+ * Returns the tree itself.
+ */
+ def updateAttachment[T: ClassTag](tree: Tree, attachment: T): tree.type
- /** Sets the `pos` of the tree. Returns the tree itself. */
- def setPos(newpos: Position): Tree
+ /** Update the attachment with the payload of the given class type `T` removed.
+ * Returns the tree itself.
+ */
+ def removeAttachment[T: ClassTag](tree: Tree): tree.type
- /** Sets the `tpe` of the tree. Returns `Unit`. */
- @deprecated("Use setType", "2.11.0") def tpe_=(t: Type): Unit
+ /** Sets the `pos` of the tree. Returns the tree itself. */
+ def setPos(tree: Tree, newpos: Position): tree.type
/** Sets the `tpe` of the tree. Returns the tree itself. */
- def setType(tp: Type): Tree
+ def setType(tree: Tree, tp: Type): tree.type
/** Like `setType`, but if this is a previously empty TypeTree that
* fact is remembered so that `untypecheck` will snap back.
@@ -139,63 +126,315 @@ abstract class Universe extends scala.reflect.api.Universe {
* and therefore should be abandoned if the current line of type
* inquiry doesn't work out.
*/
- def defineType(tp: Type): Tree
-
- /** Sets the `symbol` of the tree. Returns `Unit`. */
- def symbol_=(sym: Symbol): Unit
+ def defineType(tree: Tree, tp: Type): tree.type
/** Sets the `symbol` of the tree. Returns the tree itself. */
- def setSymbol(sym: Symbol): Tree
- }
+ def setSymbol(tree: Tree, sym: Symbol): tree.type
- /** @inheritdoc */
- override type SymTree >: Null <: Tree with SymTreeContextApi
+ /** Sets the `original` field of the type tree. */
+ def setOriginal(tt: TypeTree, original: Tree): TypeTree
- /** The extended API of sym trees that's supported in macro context universes
- * @group API
- */
- trait SymTreeContextApi extends SymTreeApi { this: SymTree =>
- /** Sets the `symbol` field of the sym tree. */
- var symbol: Symbol
- }
+ /** Mark a variable as captured; i.e. force boxing in a *Ref type.
+ * @group Macros
+ */
+ def captureVariable(vble: Symbol): Unit
- /** @inheritdoc */
- override type TypeTree >: Null <: TypTree with TypeTreeContextApi
+ /** Mark given identifier as a reference to a captured variable itself
+ * suppressing dereferencing with the `elem` field.
+ * @group Macros
+ */
+ def referenceCapturedVariable(vble: Symbol): Tree
- /** The extended API of sym trees that's supported in macro context universes
- * @group API
- */
- trait TypeTreeContextApi extends TypeTreeApi { this: TypeTree =>
- /** Sets the `original` field of the type tree. */
- def setOriginal(tree: Tree): this.type
+ /** Convert type of a captured variable to *Ref type.
+ * @group Macros
+ */
+ def capturedVariableType(vble: Symbol): Type
+
+ /** Retrieves the untyped list of subpatterns attached to selector dummy of an UnApply node.
+ * Useful in writing quasiquoting macros that do pattern matching.
+ */
+ def subpatterns(tree: Tree): Option[List[Tree]]
+
+ /** @inheritdoc */
+ override type Decorators <: MacroDecoratorApi
+
+ /** @inheritdoc */
+ trait MacroDecoratorApi extends DecoratorApi {
+ /** Extension methods for scopes */
+ type ScopeDecorator[T <: Scope] <: MacroScopeDecoratorApi[T]
+
+ /** @see [[ScopeDecorator]] */
+ implicit def scopeDecorator[T <: Scope](tree: T): ScopeDecorator[T]
+
+ /** @see [[ScopeDecorator]] */
+ class MacroScopeDecoratorApi[T <: Scope](val scope: T) {
+ /** @see [[internal.enter]] */
+ def enter(sym: Symbol): T = internal.enter(scope, sym)
+
+ /** @see [[internal.unlink]] */
+ def unlink(sym: Symbol): T = internal.unlink(scope, sym)
+ }
+
+ /** @inheritdoc */
+ override type TreeDecorator[T <: Tree] <: MacroTreeDecoratorApi[T]
+
+ /** @see [[TreeDecorator]] */
+ class MacroTreeDecoratorApi[T <: Tree](override val tree: T) extends TreeDecoratorApi[T](tree) {
+ /** @see [[internal.changeOwner]] */
+ def changeOwner(prev: Symbol, next: Symbol): tree.type = internal.changeOwner(tree, prev, next)
+
+ /** @see [[internal.attachments]] */
+ def attachments: Attachments { type Pos = Position } = internal.attachments(tree)
+
+ /** @see [[internal.updateAttachment]] */
+ def updateAttachment[A: ClassTag](attachment: A): tree.type = internal.updateAttachment(tree, attachment)
+
+ /** @see [[internal.removeAttachment]] */
+ def removeAttachment[A: ClassTag]: T = internal.removeAttachment[A](tree)
+
+ /** @see [[internal.setPos]] */
+ def setPos(newpos: Position): T = internal.setPos(tree, newpos)
+
+ /** @see [[internal.setType]] */
+ def setType(tp: Type): T = internal.setType(tree, tp)
+
+ /** @see [[internal.defineType]] */
+ def defineType(tp: Type): T = internal.defineType(tree, tp)
+
+ /** @see [[internal.setSymbol]] */
+ def setSymbol(sym: Symbol): T = internal.setSymbol(tree, sym)
+ }
+
+ /** Extension methods for typetrees */
+ type TypeTreeDecorator[T <: TypeTree] <: MacroTypeTreeDecoratorApi[T]
+
+ /** @see [[TypeTreeDecorator]] */
+ implicit def typeTreeDecorator[T <: TypeTree](tt: T): TypeTreeDecorator[T]
+
+ /** @see [[TypeTreeDecorator]] */
+ class MacroTypeTreeDecoratorApi[T <: TypeTree](val tt: T) {
+ /** @see [[internal.setOriginal]] */
+ def setOriginal(tree: Tree): TypeTree = internal.setOriginal(tt, tree)
+ }
+
+ /** @inheritdoc */
+ override type SymbolDecorator[T <: Symbol] <: MacroSymbolDecoratorApi[T]
+
+ /** @see [[TreeDecorator]] */
+ class MacroSymbolDecoratorApi[T <: Symbol](override val symbol: T) extends SymbolDecoratorApi[T](symbol) {
+ /** @see [[internal.attachments]] */
+ def attachments: Attachments { type Pos = Position } = internal.attachments(symbol)
+
+ /** @see [[internal.updateAttachment]] */
+ def updateAttachment[A: ClassTag](attachment: A): T = internal.updateAttachment(symbol, attachment)
+
+ /** @see [[internal.removeAttachment]] */
+ def removeAttachment[A: ClassTag]: T = internal.removeAttachment[A](symbol)
+
+ /** @see [[internal.setOwner]] */
+ def setOwner(newowner: Symbol): T = internal.setOwner(symbol, newowner)
+
+ /** @see [[internal.setInfo]] */
+ def setInfo(tpe: Type): T = internal.setInfo(symbol, tpe)
+
+ /** @see [[internal.setAnnotations]] */
+ def setAnnotations(annots: Annotation*): T = internal.setAnnotations(symbol, annots: _*)
+
+ /** @see [[internal.setName]] */
+ def setName(name: Name): T = internal.setName(symbol, name)
+
+ /** @see [[internal.setPrivateWithin]] */
+ def setPrivateWithin(sym: Symbol): T = internal.setPrivateWithin(symbol, sym)
+
+ /** @see [[internal.setFlag]] */
+ def setFlag(flags: FlagSet): T = internal.setFlag(symbol, flags)
+
+ /** @see [[internal.setFlag]] */
+ def resetFlag(flags: FlagSet): T = internal.resetFlag(symbol, flags)
+ }
+ }
}
- /** @inheritdoc */
- override type Ident >: Null <: RefTree with IdentContextApi
+ /** @group Internal */
+ trait TreeGen {
+ /** Builds a reference to value whose type is given stable prefix.
+ * The type must be suitable for this. For example, it
+ * must not be a TypeRef pointing to an abstract type variable.
+ */
+ def mkAttributedQualifier(tpe: Type): Tree
- /** The extended API of idents that's supported in macro context universes
- * @group API
- */
- trait IdentContextApi extends IdentApi { this: Ident =>
- /** Was this ident created from a backquoted identifier? */
- def isBackquoted: Boolean
+ /** Builds a reference to value whose type is given stable prefix.
+ * If the type is unsuitable, e.g. it is a TypeRef for an
+ * abstract type variable, then an Ident will be made using
+ * termSym as the Ident's symbol. In that case, termSym must
+ * not be NoSymbol.
+ */
+ def mkAttributedQualifier(tpe: Type, termSym: Symbol): Tree
+
+ /** Builds a typed reference to given symbol with given stable prefix. */
+ def mkAttributedRef(pre: Type, sym: Symbol): RefTree
+
+ /** Builds a typed reference to given symbol. */
+ def mkAttributedRef(sym: Symbol): RefTree
+
+ def stabilize(tree: Tree): Tree
+
+ def mkAttributedStableRef(pre: Type, sym: Symbol): Tree
+
+ def mkAttributedStableRef(sym: Symbol): Tree
+
+ /** Builds an untyped reference to given symbol. Requires the symbol to be static. */
+ def mkUnattributedRef(sym: Symbol): RefTree
+
+ /** Builds an untyped reference to symbol with given name. Requires the symbol to be static. */
+ def mkUnattributedRef(fullName: Name): RefTree
+
+ /** Builds a typed This reference to given symbol. */
+ def mkAttributedThis(sym: Symbol): This
+
+ /** Builds a typed Ident with an underlying symbol. */
+ def mkAttributedIdent(sym: Symbol): RefTree
+
+ /** Builds a typed Select with an underlying symbol. */
+ def mkAttributedSelect(qual: Tree, sym: Symbol): RefTree
+
+ /** A creator for method calls, e.g. fn[T1, T2, ...](v1, v2, ...)
+ * There are a number of variations.
+ *
+ * @param receiver symbol of the method receiver
+ * @param methodName name of the method to call
+ * @param targs type arguments (if Nil, no TypeApply node will be generated)
+ * @param args value arguments
+ * @return the newly created trees.
+ */
+ def mkMethodCall(receiver: Symbol, methodName: Name, targs: List[Type], args: List[Tree]): Tree
+
+ def mkMethodCall(method: Symbol, targs: List[Type], args: List[Tree]): Tree
+
+ def mkMethodCall(method: Symbol, args: List[Tree]): Tree
+
+ def mkMethodCall(target: Tree, args: List[Tree]): Tree
+
+ def mkMethodCall(receiver: Symbol, methodName: Name, args: List[Tree]): Tree
+
+ 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
+
+ def mkZero(tp: Type): Tree
+
+ def mkCast(tree: Tree, pt: Type): Tree
}
- /** Mark a variable as captured; i.e. force boxing in a *Ref type.
- * @group Macros
- */
- def captureVariable(vble: Symbol): Unit
+ /** @see [[internal.gen]] */
+ @deprecated("Use `internal.gen` instead", "2.11.0")
+ val treeBuild: TreeGen
- /** Mark given identifier as a reference to a captured variable itself
- * suppressing dereferencing with the `elem` field.
- * @group Macros
- */
- def referenceCapturedVariable(vble: Symbol): Tree
+ /** @inheritdoc */
+ type Compat <: MacroCompatApi
- /** Convert type of a captured variable to *Ref type.
- * @group Macros
+ /** @see [[compat]]
+ * @group Internal
*/
- def capturedVariableType(vble: Symbol): Type
+ trait MacroCompatApi extends CompatApi {
+ /** Scala 2.10 compatibility enrichments for Symbol. */
+ implicit class MacroCompatibleSymbol(symbol: Symbol) {
+ /** @see [[InternalMacroApi.attachments]] */
+ @deprecated("Use `internal.attachments` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def attachments: Attachments { type Pos = Position } = internal.attachments(symbol)
+
+ /** @see [[InternalMacroApi.updateAttachment]] */
+ @deprecated("Use `internal.updateAttachment` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def updateAttachment[T: ClassTag](attachment: T): Symbol = internal.updateAttachment[T](symbol, attachment)
+
+ /** @see [[InternalMacroApi.removeAttachment]] */
+ @deprecated("Use `internal.removeAttachment` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def removeAttachment[T: ClassTag]: Symbol = internal.removeAttachment[T](symbol)
+
+ /** @see [[InternalMacroApi.setInfo]] */
+ @deprecated("Use `internal.setInfo` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def setTypeSignature(tpe: Type): Symbol = internal.setInfo(symbol, tpe)
+
+ /** @see [[InternalMacroApi.setAnnotations]] */
+ @deprecated("Use `internal.setAnnotations` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def setAnnotations(annots: Annotation*): Symbol = internal.setAnnotations(symbol, annots: _*)
+
+ /** @see [[InternalMacroApi.setName]] */
+ @deprecated("Use `internal.setName` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def setName(name: Name): Symbol = internal.setName(symbol, name)
+
+ /** @see [[InternalMacroApi.setPrivateWithin]] */
+ @deprecated("Use `internal.setPrivateWithin` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def setPrivateWithin(sym: Symbol): Symbol = internal.setPrivateWithin(symbol, sym)
+ }
+
+ /** Scala 2.10 compatibility enrichments for TypeTree. */
+ implicit class MacroCompatibleTree(tree: Tree) {
+ /** @see [[InternalMacroApi.attachments]] */
+ @deprecated("Use `internal.attachments` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def attachments: Attachments { type Pos = Position } = internal.attachments(tree)
+
+ /** @see [[InternalMacroApi.updateAttachment]] */
+ @deprecated("Use `internal.updateAttachment` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def updateAttachment[T: ClassTag](attachment: T): Tree = internal.updateAttachment[T](tree, attachment)
+
+ /** @see [[InternalMacroApi.removeAttachment]] */
+ @deprecated("Use `internal.removeAttachment` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def removeAttachment[T: ClassTag]: Tree = internal.removeAttachment[T](tree)
+
+ /** @see [[InternalMacroApi.setPos]] */
+ @deprecated("Use `internal.setPos` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def pos_=(pos: Position): Unit = internal.setPos(tree, pos)
+
+ /** @see [[InternalMacroApi.setPos]] */
+ @deprecated("Use `internal.setPos` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def setPos(newpos: Position): Tree = internal.setPos(tree, newpos)
+
+ /** @see [[InternalMacroApi.setType]] */
+ @deprecated("Use `internal.setType` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def tpe_=(t: Type): Unit = internal.setType(tree, t)
+
+ /** @see [[InternalMacroApi.setType]] */
+ @deprecated("Use `internal.setType` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def setType(tp: Type): Tree = internal.setType(tree, tp)
+
+ /** @see [[InternalMacroApi.defineType]] */
+ @deprecated("Use `internal.defineType` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def defineType(tp: Type): Tree = internal.defineType(tree, tp)
+
+ /** @see [[InternalMacroApi.setSymbol]] */
+ @deprecated("Use `internal.setSymbol` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def symbol_=(sym: Symbol): Unit = internal.setSymbol(tree, sym)
+
+ /** @see [[InternalMacroApi.setSymbol]] */
+ @deprecated("Use `internal.setSymbol` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def setSymbol(sym: Symbol): Tree = internal.setSymbol(tree, sym)
+ }
+
+ /** Scala 2.10 compatibility enrichments for TypeTree. */
+ implicit class CompatibleTypeTree(tt: TypeTree) {
+ /** @see [[InternalMacroApi.setOriginal]] */
+ @deprecated("Use `internal.setOriginal` instead or import `internal.decorators._` for infix syntax", "2.11.0")
+ def setOriginal(tree: Tree): TypeTree = internal.setOriginal(tt, tree)
+ }
+
+ /** @see [[InternalMacroApi.captureVariable]] */
+ @deprecated("Use `internal.captureVariable` instead", "2.11.0")
+ def captureVariable(vble: Symbol): Unit = internal.captureVariable(vble)
+
+ /** @see [[InternalMacroApi.captureVariable]] */
+ @deprecated("Use `internal.referenceCapturedVariable` instead", "2.11.0")
+ def referenceCapturedVariable(vble: Symbol): Tree = internal.referenceCapturedVariable(vble)
+
+ /** @see [[InternalMacroApi.captureVariable]] */
+ @deprecated("Use `internal.capturedVariableType` instead", "2.11.0")
+ def capturedVariableType(vble: Symbol): Type = internal.capturedVariableType(vble)
+ }
/** The type of compilation runs.
* @see [[scala.reflect.macros.Enclosures]]
diff --git a/src/reflect/scala/reflect/macros/blackbox/Context.scala b/src/reflect/scala/reflect/macros/blackbox/Context.scala
index 05d9595c3a..2f9c512efa 100644
--- a/src/reflect/scala/reflect/macros/blackbox/Context.scala
+++ b/src/reflect/scala/reflect/macros/blackbox/Context.scala
@@ -42,7 +42,8 @@ trait Context extends Aliases
with Typers
with Parsers
with Evals
- with ExprUtils {
+ with ExprUtils
+ with Internals {
/** The compile-time universe. */
val universe: Universe
diff --git a/src/reflect/scala/reflect/runtime/JavaMirrors.scala b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
index bc95b839b7..f5bddb1784 100644
--- a/src/reflect/scala/reflect/runtime/JavaMirrors.scala
+++ b/src/reflect/scala/reflect/runtime/JavaMirrors.scala
@@ -22,7 +22,7 @@ import ReflectionUtils._
import scala.language.existentials
import scala.runtime.{ScalaRunTime, BoxesRunTime}
-private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse with TwoWayCaches { thisUniverse: SymbolTable =>
+private[scala] trait JavaMirrors extends internal.SymbolTable with api.JavaUniverse with TwoWayCaches { thisUniverse: SymbolTable =>
private lazy val mirrors = new WeakHashMap[ClassLoader, WeakReference[JavaMirror]]()
@@ -33,9 +33,8 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
jm
}
- override type RuntimeClass = java.lang.Class[_]
-
override type Mirror = JavaMirror
+ implicit val MirrorTag: ClassTag[Mirror] = ClassTag[Mirror](classOf[JavaMirror])
override lazy val rootMirror: Mirror = createMirror(NoSymbol, rootClassLoader)
@@ -81,10 +80,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
// the same thing is done by the `missingHook` below
override def staticPackage(fullname: String): ModuleSymbol =
try super.staticPackage(fullname)
- catch {
- case _: MissingRequirementError =>
- makeScalaPackage(fullname)
- }
+ catch { case _: ScalaReflectionException => makeScalaPackage(fullname) }
// ----------- Caching ------------------------------------------------------------------
@@ -146,7 +142,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
object ConstantArg {
def enumToSymbol(enum: Enum[_]): Symbol = {
val staticPartOfEnum = classToScala(enum.getClass).companionSymbol
- staticPartOfEnum.typeSignature.declaration(enum.name: TermName)
+ staticPartOfEnum.info.declaration(enum.name: TermName)
}
def unapply(schemaAndValue: (jClass[_], Any)): Option[Any] = schemaAndValue match {
@@ -270,7 +266,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
val isDerivedValueClass = symbol.isDerivedValueClass
lazy val boxer = runtimeClass(symbol.toType).getDeclaredConstructors().head
lazy val unboxer = {
- val fields @ (field :: _) = symbol.toType.declarations.collect{ case ts: TermSymbol if ts.isParamAccessor && ts.isMethod => ts }.toList
+ val fields @ (field :: _) = symbol.toType.decls.collect{ case ts: TermSymbol if ts.isParamAccessor && ts.isMethod => ts }.toList
assert(fields.length == 1, s"$symbol: $fields")
runtimeClass(symbol.asClass).getDeclaredMethod(field.name.toString)
}
@@ -293,32 +289,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
jfield.set(receiver, if (isDerivedValueClass) unboxer.invoke(value) else value)
}
- override def toString = s"field mirror for ${symbol.fullName} (bound to $receiver)"
- }
-
- private def showMethodSig(symbol: MethodSymbol): String = {
- var sig = s"${symbol.fullName}"
- if (symbol.typeParams.nonEmpty) {
- def showTparam(tparam: Symbol) =
- tparam.typeSignature match {
- case tpe @ TypeBounds(_, _) => s"${tparam.name}$tpe"
- case _ => tparam.name
- }
- def showTparams(tparams: List[Symbol]) = "[" + (tparams map showTparam mkString ", ") + "]"
- sig += showTparams(symbol.typeParams)
- }
- if (symbol.paramss.nonEmpty) {
- def showParam(param: Symbol) = s"${param.name}: ${param.typeSignature}"
- def showParams(params: List[Symbol]) = {
- val s_mods = if (params.nonEmpty && params(0).hasFlag(IMPLICIT)) "implicit " else ""
- val s_params = params map showParam mkString ", "
- "(" + s_mods + s_params + ")"
- }
- def showParamss(paramss: List[List[Symbol]]) = paramss map showParams mkString ""
- sig += showParamss(symbol.paramss)
- }
- sig += s": ${symbol.returnType}"
- sig
+ override def toString = s"field mirror for ${showDecl(symbol)} (bound to $receiver)"
}
// the "symbol == Any_getClass || symbol == Object_getClass" test doesn't cut it
@@ -373,7 +344,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
override def toString = {
val what = if (symbol.isConstructor) "constructor mirror" else "method mirror"
- s"$what for ${showMethodSig(symbol)} (bound to $receiver)"
+ s"$what for ${showDecl(symbol)} (bound to $receiver)"
}
}
@@ -469,7 +440,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
private class BytecodelessMethodMirror[T: ClassTag](val receiver: T, val symbol: MethodSymbol)
extends MethodMirror {
def bind(newReceiver: Any) = new BytecodelessMethodMirror(newReceiver.asInstanceOf[T], symbol)
- override def toString = s"bytecodeless method mirror for ${showMethodSig(symbol)} (bound to $receiver)"
+ override def toString = s"bytecodeless method mirror for ${showDecl(symbol)} (bound to $receiver)"
def apply(args: Any*): Any = {
// checking type conformance is too much of a hassle, so we don't do it here
@@ -483,7 +454,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
if (!perfectMatch && !varargMatch) {
val n_arguments = if (isVarArgsList(params)) s"${params.length - 1} or more" else s"${params.length}"
val s_arguments = if (params.length == 1 && !isVarArgsList(params)) "argument" else "arguments"
- abort(s"${showMethodSig(symbol)} takes $n_arguments $s_arguments")
+ abort(s"${showDecl(symbol)} takes $n_arguments $s_arguments")
}
def objReceiver = receiver.asInstanceOf[AnyRef]
@@ -640,6 +611,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
info(s"unpickling Scala $clazz and $module, owner = ${clazz.owner}")
val bytes = ssig.getBytes
val len = ByteCodecs.decode(bytes)
+ assignAssociatedFile(clazz, module, jclazz)
unpickler.unpickle(bytes take len, 0, clazz, module, jclazz.getName)
markAllCompleted(clazz, module)
case None =>
@@ -649,6 +621,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
val encoded = slsig flatMap (_.getBytes)
val len = ByteCodecs.decode(encoded)
val decoded = encoded.take(len)
+ assignAssociatedFile(clazz, module, jclazz)
unpickler.unpickle(decoded, 0, clazz, module, jclazz.getName)
markAllCompleted(clazz, module)
case None =>
@@ -690,6 +663,12 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
}
}
+ private def assignAssociatedFile(clazz: Symbol, module: Symbol, jclazz: jClass[_]): Unit = {
+ val associatedFile = ReflectionUtils.associatedFile(jclazz)
+ clazz.associatedFile = associatedFile
+ if (module != NoSymbol) module.associatedFile = associatedFile
+ }
+
/**
* Copy all annotations of Java annotated element `jann` over to Scala symbol `sym`.
* Also creates `@throws` annotations if necessary.
@@ -745,6 +724,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
debugInfo("completing from Java " + sym + "/" + clazz.fullName)//debug
assert(sym == clazz || (module != NoSymbol && (sym == module || sym == module.moduleClass)), sym)
+ assignAssociatedFile(clazz, module, jclazz)
propagatePackageBoundary(jclazz, relatedSymbols: _*)
copyAnnotations(clazz, jclazz)
// to do: annotations to set also for module?
@@ -961,7 +941,7 @@ private[reflect] trait JavaMirrors extends internal.SymbolTable with api.JavaUni
val owner = ownerModule.moduleClass
val name = (fullname: TermName) drop split + 1
val opkg = owner.info decl name
- if (opkg.isPackage)
+ if (opkg.hasPackageFlag)
opkg.asModule
else if (opkg == NoSymbol) {
val pkg = owner.newPackage(name)
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverse.scala b/src/reflect/scala/reflect/runtime/JavaUniverse.scala
index f6556a442d..b5446694ed 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverse.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverse.scala
@@ -2,33 +2,66 @@ package scala
package reflect
package runtime
+import scala.reflect.internal.{TreeInfo, SomePhase}
+import scala.reflect.internal.{SymbolTable => InternalSymbolTable}
+import scala.reflect.runtime.{SymbolTable => RuntimeSymbolTable}
+import scala.reflect.api.{TreeCreator, TypeCreator, Universe}
+
/** An implementation of [[scala.reflect.api.Universe]] for runtime reflection using JVM classloaders.
*
* Should not be instantiated directly, use [[scala.reflect.runtime.universe]] instead.
*
* @contentDiagram hideNodes "*Api" "*Extractor"
*/
-class JavaUniverse extends internal.SymbolTable with JavaUniverseForce with ReflectSetup with runtime.SymbolTable { self =>
+class JavaUniverse extends InternalSymbolTable with JavaUniverseForce with ReflectSetup with RuntimeSymbolTable { self =>
override def inform(msg: String): Unit = log(msg)
- def picklerPhase = internal.SomePhase
- def erasurePhase = internal.SomePhase
-
+ def picklerPhase = SomePhase
+ def erasurePhase = SomePhase
lazy val settings = new Settings
private val isLogging = sys.props contains "scala.debug.reflect"
def log(msg: => AnyRef): Unit = if (isLogging) Console.err.println("[reflect] " + msg)
type TreeCopier = InternalTreeCopierOps
+ implicit val TreeCopierTag: ClassTag[TreeCopier] = ClassTag[TreeCopier](classOf[TreeCopier])
def newStrictTreeCopier: TreeCopier = new StrictTreeCopier
def newLazyTreeCopier: TreeCopier = new LazyTreeCopier
def currentFreshNameCreator = globalFreshNameCreator
+ override lazy val internal: Internal = new SymbolTableInternal {
+ override def typeTagToManifest[T: ClassTag](mirror0: Any, tag: Universe # TypeTag[T]): Manifest[T] = {
+ // SI-6239: make this conversion more precise
+ val mirror = mirror0.asInstanceOf[Mirror]
+ val runtimeClass = mirror.runtimeClass(tag.in(mirror).tpe)
+ Manifest.classType(runtimeClass).asInstanceOf[Manifest[T]]
+ }
+ 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: scala.reflect.api.Mirror[U]): U # Type = {
+ mirror.universe match {
+ case ju: JavaUniverse =>
+ val jm = mirror.asInstanceOf[ju.Mirror]
+ val sym = jm.classSymbol(manifest.runtimeClass)
+ val tpe =
+ if (manifest.typeArguments.isEmpty) sym.toType
+ else {
+ val tags = manifest.typeArguments map (targ => ju.internal.manifestToTypeTag(jm, targ))
+ ju.appliedType(sym.toTypeConstructor, tags map (_.in(jm).tpe))
+ }
+ tpe.asInstanceOf[U # Type]
+ case u =>
+ u.internal.manifestToTypeTag(mirror.asInstanceOf[u.Mirror], manifest).in(mirror).tpe
+ }
+ }
+ })
+ }
+
// can't put this in runtime.Trees since that's mixed with Global in ReflectGlobal, which has the definition from internal.Trees
object treeInfo extends {
val global: JavaUniverse.this.type = JavaUniverse.this
- } with internal.TreeInfo
+ } with TreeInfo
init()
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index 0fcf215580..dcd262c288 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -26,11 +26,13 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
TypeTag.Null.tpe
this.settings
+ this.internal
this.treeInfo
this.rootMirror
- this.treeBuild
this.traceSymbols
this.perRunCaches
+ this.compat
+ this.treeBuild
this.FreshNameExtractor
this.FixedMirrorTreeCreator
this.FixedMirrorTypeCreator
@@ -106,9 +108,11 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.UnmappableAnnotation
this.ErroneousAnnotation
this.ThrownException
+ this.typeNames
this.tpnme
this.fulltpnme
this.binarynme
+ this.termNames
this.nme
this.sn
this.Constant
@@ -279,6 +283,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.ReflectPackage
definitions.ReflectApiPackage
definitions.ReflectRuntimePackage
+ definitions.UniverseClass
definitions.PartialManifestModule
definitions.FullManifestClass
definitions.FullManifestModule
diff --git a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
index d642b25127..a4bd698068 100644
--- a/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
+++ b/src/reflect/scala/reflect/runtime/ReflectionUtils.scala
@@ -9,6 +9,8 @@ package reflect.runtime
import java.lang.{Class => jClass}
import java.lang.reflect.{ Method, InvocationTargetException, UndeclaredThrowableException }
import scala.reflect.internal.util.AbstractFileClassLoader
+import scala.reflect.io._
+import java.io.{File => JFile}
/** A few java-reflection oriented utility functions useful during reflection bootstrapping.
*/
@@ -97,5 +99,74 @@ object ReflectionUtils {
object EnclosedInConstructor extends EnclosedIn(_.getEnclosingConstructor)
object EnclosedInClass extends EnclosedIn(_.getEnclosingClass)
object EnclosedInPackage extends EnclosedIn(_.getPackage)
+
+ def associatedFile(clazz: Class[_]): AbstractFile = {
+ // TODO: I agree with Jason - this implementation isn't something that we'd like to support
+ // therefore I'm having it commented out and this function will now return NoAbstractFile
+ // I think we can keep the source code though, because it can be useful to the others
+ //
+ // def inferAssociatedFile(clazz: Class[_]): AbstractFile = {
+ // // http://stackoverflow.com/questions/227486/find-where-java-class-is-loaded-from
+ // try {
+ // var cl = clazz.getClassLoader()
+ // if (cl == null) {
+ // cl = ClassLoader.getSystemClassLoader()
+ // while (cl != null && cl.getParent != null) cl = cl.getParent
+ // }
+ // var result: AbstractFile = null
+ // if (cl != null) {
+ // val name = clazz.getCanonicalName()
+ // val resource = cl.getResource(name.replace(".", "/") + ".class")
+ // if (resource != null) {
+ // def fromFile(file: String) = AbstractFile.getFile(file)
+ // def fromJarEntry(jarfile: String, entrypath: String) = {
+ // val jar = fromFile(jarfile)
+ // new VirtualFile(clazz.getName, entrypath) {
+ // lazy val impl: AbstractFile = {
+ // def loop(root: AbstractFile, path: List[String]): AbstractFile = {
+ // def find(name: String) = root.iterator.find(_.name == name).getOrElse(NoAbstractFile)
+ // path match {
+ // case step :: Nil => find(step)
+ // case step :: rest => loop(find(step), rest)
+ // case Nil => NoAbstractFile
+ // }
+ // }
+ // loop(ZipArchive.fromFile(new JFile(jarfile)), entrypath.split("/").toList)
+ // }
+ // override def container = impl.container
+ // override def lastModified = impl.lastModified
+ // override def input = impl.input
+ // override def sizeOption = impl.sizeOption
+ // override def underlyingSource = Some(jar)
+ // override def toString = jarfile + "(" + entrypath + ")"
+ // }
+ // }
+ // def fallback() = new VirtualFile(clazz.getName, resource.toString)
+ // result = resource.getProtocol match {
+ // case "file" =>
+ // fromFile(resource.getFile)
+ // case "jar" =>
+ // val intrajarUrl = new java.net.URL(resource.getFile)
+ // intrajarUrl.getProtocol match {
+ // case "file" =>
+ // val file = intrajarUrl.getFile()
+ // val expectedSuffix = "!/" + name.replace(".", "/") + ".class"
+ // if (file.endsWith(expectedSuffix)) fromJarEntry(file.stripSuffix(expectedSuffix), expectedSuffix.substring(2))
+ // else fallback()
+ // case _ => fallback()
+ // }
+ // case _ =>
+ // fallback()
+ // }
+ // }
+ // }
+ // if (result != null) result else NoAbstractFile
+ // } catch {
+ // case _: Exception => NoAbstractFile
+ // }
+ // }
+ // inferAssociatedFile(clazz)
+ NoAbstractFile
+ }
}
diff --git a/src/repl/scala/tools/nsc/interpreter/IMain.scala b/src/repl/scala/tools/nsc/interpreter/IMain.scala
index d261fc5be9..8bb5757bbb 100644
--- a/src/repl/scala/tools/nsc/interpreter/IMain.scala
+++ b/src/repl/scala/tools/nsc/interpreter/IMain.scala
@@ -1031,7 +1031,7 @@ class IMain(@BeanProperty val factory: ScriptEngineFactory, initialSettings: Set
def lastWarnings = mostRecentWarnings
private lazy val importToGlobal = global mkImporter ru
- private lazy val importToRuntime = ru mkImporter global
+ private lazy val importToRuntime = ru.internal createImporter global
private lazy val javaMirror = ru.rootMirror match {
case x: ru.JavaMirror => x
case _ => null
diff --git a/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala b/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala
index 53c7c82e89..c1122d4223 100644
--- a/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala
+++ b/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala
@@ -48,7 +48,7 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
// compiler to crash for reasons not yet known.
def members = exitingTyper((effectiveTp.nonPrivateMembers.toList ++ anyMembers) filter (_.isPublic))
def methods = members.toList filter (_.isMethod)
- def packages = members.toList filter (_.isPackage)
+ def packages = members.toList filter (_.hasPackageFlag)
def aliases = members.toList filter (_.isAliasType)
def memberNames = members map tos
diff --git a/src/repl/scala/tools/nsc/interpreter/package.scala b/src/repl/scala/tools/nsc/interpreter/package.scala
index 5dc9b65436..079097d7a2 100644
--- a/src/repl/scala/tools/nsc/interpreter/package.scala
+++ b/src/repl/scala/tools/nsc/interpreter/package.scala
@@ -157,7 +157,7 @@ package object interpreter extends ReplConfig with ReplStrings {
def echoKind(tpe: Type, kind: Kind, verbose: Boolean) {
def typeString(tpe: Type): String = {
tpe match {
- case TypeRef(_, sym, _) => typeString(sym.typeSignature)
+ case TypeRef(_, sym, _) => typeString(sym.info)
case RefinedType(_, _) => tpe.toString
case _ => tpe.typeSymbol.fullName
}