summaryrefslogtreecommitdiff
path: root/src/reflect/scala/reflect
diff options
context:
space:
mode:
Diffstat (limited to 'src/reflect/scala/reflect')
-rw-r--r--src/reflect/scala/reflect/api/BuildUtils.scala8
-rw-r--r--src/reflect/scala/reflect/api/Exprs.scala2
-rw-r--r--src/reflect/scala/reflect/api/FlagSets.scala8
-rw-r--r--src/reflect/scala/reflect/api/Importers.scala2
-rw-r--r--src/reflect/scala/reflect/api/Mirrors.scala8
-rw-r--r--src/reflect/scala/reflect/api/Printers.scala19
-rw-r--r--src/reflect/scala/reflect/api/StandardLiftables.scala35
-rw-r--r--src/reflect/scala/reflect/api/Types.scala9
-rw-r--r--src/reflect/scala/reflect/api/Universe.scala6
-rw-r--r--src/reflect/scala/reflect/internal/AnnotationInfos.scala4
-rw-r--r--src/reflect/scala/reflect/internal/BaseTypeSeqs.scala5
-rw-r--r--src/reflect/scala/reflect/internal/BuildUtils.scala4
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala106
-rw-r--r--src/reflect/scala/reflect/internal/FlagSets.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Flags.scala11
-rw-r--r--src/reflect/scala/reflect/internal/HasFlags.scala1
-rw-r--r--src/reflect/scala/reflect/internal/Importers.scala4
-rw-r--r--src/reflect/scala/reflect/internal/Mirrors.scala9
-rw-r--r--src/reflect/scala/reflect/internal/Printers.scala797
-rw-r--r--src/reflect/scala/reflect/internal/Scopes.scala2
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala5
-rw-r--r--src/reflect/scala/reflect/internal/SymbolTable.scala20
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala15
-rw-r--r--src/reflect/scala/reflect/internal/TreeGen.scala8
-rw-r--r--src/reflect/scala/reflect/internal/TreeInfo.scala4
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala58
-rw-r--r--src/reflect/scala/reflect/internal/Variances.scala4
-rw-r--r--src/reflect/scala/reflect/internal/pickling/UnPickler.scala2
-rw-r--r--src/reflect/scala/reflect/internal/tpe/GlbLubs.scala2
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeComparers.scala47
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeMaps.scala8
-rw-r--r--src/reflect/scala/reflect/internal/tpe/TypeToStrings.scala30
-rw-r--r--src/reflect/scala/reflect/internal/transform/Erasure.scala2
-rw-r--r--src/reflect/scala/reflect/internal/util/Position.scala37
-rw-r--r--src/reflect/scala/reflect/internal/util/SourceFile.scala44
-rw-r--r--src/reflect/scala/reflect/macros/Aliases.scala14
-rw-r--r--src/reflect/scala/reflect/macros/BlackboxMacro.scala36
-rw-r--r--src/reflect/scala/reflect/macros/Enclosures.scala40
-rw-r--r--src/reflect/scala/reflect/macros/Evals.scala8
-rw-r--r--src/reflect/scala/reflect/macros/ExprUtils.scala4
-rw-r--r--src/reflect/scala/reflect/macros/FrontEnds.scala4
-rw-r--r--src/reflect/scala/reflect/macros/Infrastructure.scala4
-rw-r--r--src/reflect/scala/reflect/macros/Names.scala4
-rw-r--r--src/reflect/scala/reflect/macros/Parsers.scala4
-rw-r--r--src/reflect/scala/reflect/macros/Reifiers.scala4
-rw-r--r--src/reflect/scala/reflect/macros/Typers.scala6
-rw-r--r--src/reflect/scala/reflect/macros/Universe.scala12
-rw-r--r--src/reflect/scala/reflect/macros/WhiteboxMacro.scala36
-rw-r--r--src/reflect/scala/reflect/macros/blackbox/Context.scala (renamed from src/reflect/scala/reflect/macros/BlackboxContext.scala)29
-rw-r--r--src/reflect/scala/reflect/macros/package.scala8
-rw-r--r--src/reflect/scala/reflect/macros/whitebox/Context.scala (renamed from src/reflect/scala/reflect/macros/WhiteboxContext.scala)13
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala7
-rw-r--r--src/reflect/scala/reflect/runtime/SynchronizedTypes.scala9
-rw-r--r--src/reflect/scala/reflect/runtime/package.scala2
54 files changed, 1085 insertions, 486 deletions
diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala
index 6971175f88..10c2def72a 100644
--- a/src/reflect/scala/reflect/api/BuildUtils.scala
+++ b/src/reflect/scala/reflect/api/BuildUtils.scala
@@ -246,13 +246,13 @@ private[reflect] trait BuildUtils { self: Universe =>
def unapply(tree: Tree): Option[(List[Tree], Tree)]
}
- def UnliftHelper1[T](unliftable: Unliftable[T]): UnliftHelper1[T]
- trait UnliftHelper1[T] {
+ def UnliftListElementwise[T](unliftable: Unliftable[T]): UnliftListElementwise[T]
+ trait UnliftListElementwise[T] {
def unapply(lst: List[Tree]): Option[List[T]]
}
- def UnliftHelper2[T](unliftable: Unliftable[T]): UnliftHelper2[T]
- trait UnliftHelper2[T] {
+ def UnliftListOfListsElementwise[T](unliftable: Unliftable[T]): UnliftListOfListsElementwise[T]
+ trait UnliftListOfListsElementwise[T] {
def unapply(lst: List[List[Tree]]): Option[List[List[T]]]
}
diff --git a/src/reflect/scala/reflect/api/Exprs.scala b/src/reflect/scala/reflect/api/Exprs.scala
index 50c8aa8779..5b6ff2325c 100644
--- a/src/reflect/scala/reflect/api/Exprs.scala
+++ b/src/reflect/scala/reflect/api/Exprs.scala
@@ -106,7 +106,7 @@ trait Exprs { self: Universe =>
*
* The corresponding macro implementation should have the following signature (note how the return type denotes path-dependency on x):
* {{{
- * object Impls { def foo_impl(c: BlackboxContext)(x: c.Expr[X]): c.Expr[x.value.T] = ... }
+ * object Impls { def foo_impl(c: Context)(x: c.Expr[X]): c.Expr[x.value.T] = ... }
* }}}
*/
@compileTimeOnly("cannot use value except for signatures of macro implementations")
diff --git a/src/reflect/scala/reflect/api/FlagSets.scala b/src/reflect/scala/reflect/api/FlagSets.scala
index 3d5a213f2f..54b65166d8 100644
--- a/src/reflect/scala/reflect/api/FlagSets.scala
+++ b/src/reflect/scala/reflect/api/FlagSets.scala
@@ -169,6 +169,14 @@ trait FlagSets { self: Universe =>
/** Flag indicating that tree was generated by the compiler */
val SYNTHETIC: FlagSet
+
+ /** Flag indicating that tree represents an enum.
+ *
+ * It can only appear at
+ * - the enum's class
+ * - enum constants
+ **/
+ val ENUM: FlagSet
}
/** The empty set of flags
diff --git a/src/reflect/scala/reflect/api/Importers.scala b/src/reflect/scala/reflect/api/Importers.scala
index e239b86452..5667d93e29 100644
--- a/src/reflect/scala/reflect/api/Importers.scala
+++ b/src/reflect/scala/reflect/api/Importers.scala
@@ -34,7 +34,7 @@ package api
* {{{
* def staticEval[T](x: T) = macro staticEval[T]
*
- * def staticEval[T](c: scala.reflect.macros.BlackboxContext)(x: c.Expr[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)
diff --git a/src/reflect/scala/reflect/api/Mirrors.scala b/src/reflect/scala/reflect/api/Mirrors.scala
index a4cd531053..f11b9a5c55 100644
--- a/src/reflect/scala/reflect/api/Mirrors.scala
+++ b/src/reflect/scala/reflect/api/Mirrors.scala
@@ -29,19 +29,19 @@ package api
* Compile-time `Mirror`s make use of only classloader `Mirror`s to load `Symbol`s
* by name.
*
- * The entry point to classloader `Mirror`s is via [[scala.reflect.macros.BlackboxContext#mirror]] or [[scala.reflect.macros.WhiteboxContext#mirror]].
+ * The entry point to classloader `Mirror`s is via [[scala.reflect.macros.blackbox.Context#mirror]] or [[scala.reflect.macros.whitebox.Context#mirror]].
* Typical methods which use classloader `Mirror`s include [[scala.reflect.api.Mirror#staticClass]],
* [[scala.reflect.api.Mirror#staticModule]], and [[scala.reflect.api.Mirror#staticPackage]]. For
* example:
* {{{
- * import scala.reflect.macros.BlackboxContext
+ * import scala.reflect.macros.blackbox.Context
*
* case class Location(filename: String, line: Int, column: Int)
*
* object Macros {
* def currentLocation: Location = macro impl
*
- * def impl(c: BlackboxContext): c.Expr[Location] = {
+ * def impl(c: Context): c.Expr[Location] = {
* import c.universe._
* val pos = c.macroApplication.pos
* val clsLocation = c.mirror.staticModule("Location") // get symbol of "Location" object
@@ -153,7 +153,7 @@ package api
*
* '''[[scala.reflect.api.Mirrors#ClassMirror]]'''. Used for creating invoker mirrors for constructors.
* Entry points: for ''static classes'' `val cm1 = m.reflectClass(<class symbol>)`,
- * for ''inner classes'' `val mm2 = im.reflectClass(<module symbol>)`.
+ * for ''inner classes'' `val mm2 = im.reflectClass(<class symbol>)`.
* Example:
* {{{
* scala> case class C(x: Int)
diff --git a/src/reflect/scala/reflect/api/Printers.scala b/src/reflect/scala/reflect/api/Printers.scala
index 1e0854d171..5bc92d3893 100644
--- a/src/reflect/scala/reflect/api/Printers.scala
+++ b/src/reflect/scala/reflect/api/Printers.scala
@@ -201,6 +201,25 @@ trait Printers { self: Universe =>
*/
protected def newTreePrinter(out: PrintWriter): TreePrinter
+ /**
+ * Renders the code of the passed tree, so that:
+ * 1) it can be later compiled by scalac retaining the same meaning,
+ * 2) it looks pretty.
+ * At the moment we have handled #1 for unattributed trees and
+ * later on plan to account for typical idiosyncrasies of the typechecker.
+ * #2 is more or less okay indentation-wise, but at the moment there's a lot of desugaring
+ * left in place, and that's what we also plan to improve in the future.
+ *
+ * @group Printers
+ */
+ def showCode(tree: Tree) = render(tree, newCodePrinter)
+
+ /**
+ * Hook to define what `showCode(...)` means.
+ * @group Printers
+ */
+ protected def newCodePrinter(out: PrintWriter): TreePrinter
+
/** Renders internal structure of a reflection artifact as the
* visualization of a Scala syntax tree.
*
diff --git a/src/reflect/scala/reflect/api/StandardLiftables.scala b/src/reflect/scala/reflect/api/StandardLiftables.scala
index 6756d5e114..5a03996dd9 100644
--- a/src/reflect/scala/reflect/api/StandardLiftables.scala
+++ b/src/reflect/scala/reflect/api/StandardLiftables.scala
@@ -11,16 +11,16 @@ trait StandardLiftables { self: Universe =>
private def callCollection(name: Name)(args: List[Tree]) = callScala(nme.collection, nme.immutable, name)(args)
private def liftAsLiteral[T]: Liftable[T] = Liftable { v => Literal(Constant(v)) }
- implicit def liftByte[T <: Byte]: Liftable[T] = liftAsLiteral[T]
- implicit def liftShort[T <: Short]: Liftable[T] = liftAsLiteral[T]
- implicit def liftChar[T <: Char]: Liftable[T] = liftAsLiteral[T]
- implicit def liftInt[T <: Int]: Liftable[T] = liftAsLiteral[T]
- implicit def liftLong[T <: Long]: Liftable[T] = liftAsLiteral[T]
- implicit def liftFloat[T <: Float]: Liftable[T] = liftAsLiteral[T]
- implicit def liftDouble[T <: Double]: Liftable[T] = liftAsLiteral[T]
- implicit def liftBoolean: Liftable[Boolean] = liftAsLiteral[Boolean]
- implicit def liftUnit: Liftable[Unit] = liftAsLiteral[Unit]
- implicit def liftString: Liftable[String] = liftAsLiteral[String]
+ implicit def liftByte[T <: Byte]: Liftable[T] = liftAsLiteral[T]
+ implicit def liftShort[T <: Short]: Liftable[T] = liftAsLiteral[T]
+ implicit def liftChar[T <: Char]: Liftable[T] = liftAsLiteral[T]
+ implicit def liftInt[T <: Int]: Liftable[T] = liftAsLiteral[T]
+ implicit def liftLong[T <: Long]: Liftable[T] = liftAsLiteral[T]
+ implicit def liftFloat[T <: Float]: Liftable[T] = liftAsLiteral[T]
+ implicit def liftDouble[T <: Double]: Liftable[T] = liftAsLiteral[T]
+ implicit def liftBoolean[T <: Boolean]: Liftable[T] = liftAsLiteral[T]
+ implicit def liftUnit: Liftable[Unit] = liftAsLiteral[Unit]
+ 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)
@@ -35,16 +35,22 @@ trait StandardLiftables { self: Universe =>
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 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 liftOption[T: Liftable]: Liftable[Option[T]] = Liftable {
- case Some(v) => callScala(nme.Some)(lift(v) :: Nil)
- case None => selectScala(nme.None)
+ 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 liftEither[L: Liftable, R: Liftable]: Liftable[Either[L, R]] = Liftable {
- case Left(l) => callScala(nme.util, nme.Left)(lift(l) :: Nil)
- case Right(r) => callScala(nme.util, nme.Right)(lift(r) :: Nil)
+ case left: Left[L, R] => lift(left)
+ case right: Right[L, R] => lift(right)
}
implicit def liftTuple1[T1](implicit liftT1: Liftable[T1]): Liftable[Tuple1[T1]] = Liftable { t =>
@@ -220,6 +226,7 @@ trait StandardLiftables { self: Universe =>
val List = TermName("List")
val Map = TermName("Map")
val None = TermName("None")
+ val Nil = TermName("Nil")
val Right = TermName("Right")
val Set = TermName("Set")
val Some = TermName("Some")
diff --git a/src/reflect/scala/reflect/api/Types.scala b/src/reflect/scala/reflect/api/Types.scala
index 9d2d06da69..4892b46e16 100644
--- a/src/reflect/scala/reflect/api/Types.scala
+++ b/src/reflect/scala/reflect/api/Types.scala
@@ -707,14 +707,14 @@ trait Types {
val AnnotatedType: AnnotatedTypeExtractor
/** An extractor class to create and pattern match with syntax
- * `AnnotatedType(annotations, underlying, selfsym)`.
+ * `AnnotatedType(annotations, underlying)`.
* Here, `annotations` are the annotations decorating the underlying type `underlying`.
* `selfSym` is a symbol representing the annotated type itself.
* @group Extractors
*/
abstract class AnnotatedTypeExtractor {
- def apply(annotations: List[Annotation], underlying: Type, selfsym: Symbol): AnnotatedType
- def unapply(tpe: AnnotatedType): Option[(List[Annotation], Type, Symbol)]
+ def apply(annotations: List[Annotation], underlying: Type): AnnotatedType
+ def unapply(tpe: AnnotatedType): Option[(List[Annotation], Type)]
}
/** The API that all annotated types support.
@@ -727,9 +727,6 @@ trait Types {
/** The annotee. */
def underlying: Type
-
- /** A symbol that represents the annotated type itself. */
- def selfsym: Symbol
}
/** The `TypeBounds` type signature is used to indicate lower and upper type bounds
diff --git a/src/reflect/scala/reflect/api/Universe.scala b/src/reflect/scala/reflect/api/Universe.scala
index 1da2c24306..1c9b77581a 100644
--- a/src/reflect/scala/reflect/api/Universe.scala
+++ b/src/reflect/scala/reflect/api/Universe.scala
@@ -41,11 +41,11 @@ package api
* res1: reflect.runtime.universe.Type = scala.Either[String,Int]
* }}}
*
- * To obtain a `Universe` for use within a Scala macro, use [[scala.reflect.macros.BlackboxContext#universe]].
- * or [[scala.reflect.macros.WhiteboxContext#universe]]. For example:
+ * To obtain a `Universe` for use within a Scala macro, use [[scala.reflect.macros.blackbox.Context#universe]].
+ * or [[scala.reflect.macros.whitebox.Context#universe]]. For example:
* {{{
* def printf(format: String, params: Any*): Unit = macro impl
- * def impl(c: BlackboxContext)(format: c.Expr[String], params: c.Expr[Any]*): c.Expr[Unit] = {
+ * def impl(c: Context)(format: c.Expr[String], params: c.Expr[Any]*): c.Expr[Unit] = {
* import c.universe._
* ...
* }
diff --git a/src/reflect/scala/reflect/internal/AnnotationInfos.scala b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
index f45fa40f89..4fde57ed02 100644
--- a/src/reflect/scala/reflect/internal/AnnotationInfos.scala
+++ b/src/reflect/scala/reflect/internal/AnnotationInfos.scala
@@ -290,8 +290,8 @@ trait AnnotationInfos extends api.Annotations { self: SymbolTable =>
* metaAnnotations = List(setter, field).
*/
def metaAnnotations: List[AnnotationInfo] = atp match {
- case AnnotatedType(metas, _, _) => metas
- case _ => Nil
+ case AnnotatedType(metas, _) => metas
+ case _ => Nil
}
/** The default kind of members to which this annotation is attached.
diff --git a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
index 19c67879f5..0ca8611719 100644
--- a/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
+++ b/src/reflect/scala/reflect/internal/BaseTypeSeqs.scala
@@ -166,9 +166,10 @@ trait BaseTypeSeqs {
val index = new Array[Int](nparents)
var i = 0
for (p <- parents) {
+ val parentBts = p.dealias.baseTypeSeq // dealias need for SI-8046.
pbtss(i) =
- if (p.baseTypeSeq eq undetBaseTypeSeq) AnyClass.info.baseTypeSeq
- else p.baseTypeSeq
+ if (parentBts eq undetBaseTypeSeq) AnyClass.info.baseTypeSeq
+ else parentBts
index(i) = 0
i += 1
}
diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala
index 0a81bfa2a5..9b19dc11cb 100644
--- a/src/reflect/scala/reflect/internal/BuildUtils.scala
+++ b/src/reflect/scala/reflect/internal/BuildUtils.scala
@@ -455,14 +455,14 @@ trait BuildUtils { self: SymbolTable =>
}
}
- def UnliftHelper1[T](unliftable: Unliftable[T]) = new UnliftHelper1[T] {
+ def UnliftListElementwise[T](unliftable: Unliftable[T]) = new UnliftListElementwise[T] {
def unapply(lst: List[Tree]): Option[List[T]] = {
val unlifted = lst.flatMap { unliftable.unapply(_) }
if (unlifted.length == lst.length) Some(unlifted) else None
}
}
- def UnliftHelper2[T](unliftable: Unliftable[T]) = new UnliftHelper2[T] {
+ def UnliftListOfListsElementwise[T](unliftable: Unliftable[T]) = new UnliftListOfListsElementwise[T] {
def unapply(lst: List[List[Tree]]): Option[List[List[T]]] = {
val unlifted = lst.map { l => l.flatMap { unliftable.unapply(_) } }
if (unlifted.flatten.length == lst.flatten.length) Some(unlifted) else None
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 38be6fcf56..c2939e69b5 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -363,6 +363,7 @@ trait Definitions extends api.StandardDefinitions {
lazy val ComparableClass = requiredClass[java.lang.Comparable[_]] modifyInfo fixupAsAnyTrait
lazy val JavaCloneableClass = requiredClass[java.lang.Cloneable]
lazy val JavaNumberClass = requiredClass[java.lang.Number]
+ lazy val JavaEnumClass = requiredClass[java.lang.Enum[_]]
lazy val RemoteInterfaceClass = requiredClass[java.rmi.Remote]
lazy val RemoteExceptionClass = requiredClass[java.rmi.RemoteException]
@@ -482,12 +483,8 @@ trait Definitions extends api.StandardDefinitions {
lazy val TypeCreatorClass = getClassIfDefined("scala.reflect.api.TypeCreator") // defined in scala-reflect.jar, so we need to be careful
lazy val TreeCreatorClass = getClassIfDefined("scala.reflect.api.TreeCreator") // defined in scala-reflect.jar, so we need to be careful
- lazy val BlackboxMacroClass = getClassIfDefined("scala.reflect.macros.BlackboxMacro") // defined in scala-reflect.jar, so we need to be careful
- def BlackboxMacroContextValue = BlackboxMacroClass.map(sym => getMemberValue(sym, nme.c))
- lazy val WhiteboxMacroClass = getClassIfDefined("scala.reflect.macros.WhiteboxMacro") // defined in scala-reflect.jar, so we need to be careful
- def WhiteboxMacroContextValue = WhiteboxMacroClass.map(sym => getMemberValue(sym, nme.c))
- lazy val BlackboxContextClass = getClassIfDefined("scala.reflect.macros.BlackboxContext") // defined in scala-reflect.jar, so we need to be careful
- lazy val WhiteboxContextClass = getClassIfDefined("scala.reflect.macros.WhiteboxContext") // defined in scala-reflect.jar, so we need to be careful
+ lazy val BlackboxContextClass = getClassIfDefined("scala.reflect.macros.blackbox.Context") // defined in scala-reflect.jar, so we need to be careful
+ lazy val WhiteboxContextClass = getClassIfDefined("scala.reflect.macros.whitebox.Context") // defined in scala-reflect.jar, so we need to be careful
def MacroContextPrefix = BlackboxContextClass.map(sym => getMemberMethod(sym, nme.prefix))
def MacroContextPrefixType = BlackboxContextClass.map(sym => getTypeMember(sym, tpnme.PrefixType))
def MacroContextUniverse = BlackboxContextClass.map(sym => getMemberMethod(sym, nme.universe))
@@ -603,32 +600,31 @@ trait Definitions extends api.StandardDefinitions {
def isWhiteboxContextType(tp: Type) =
isMacroContextType(tp) && (tp <:< WhiteboxContextClass.tpe)
- def mightBeMacroBundleType(tp: Type) =
- tp.baseClasses.contains(WhiteboxMacroClass) ||
- tp.baseClasses.contains(BlackboxMacroClass)
-
- def isMacroBundleType(tp: Type) = tp.baseClasses match {
- case _ :: proto :: _ if isMacroBundleProtoType(proto.tpe) => true
- case _ => false
+ private def macroBundleParamInfo(tp: Type) = {
+ val ctor = tp.erasure.typeSymbol.primaryConstructor
+ ctor.paramss match {
+ case List(List(c)) =>
+ val sym = c.info.typeSymbol
+ val isContextCompatible = sym.isNonBottomSubClass(BlackboxContextClass) || sym.isNonBottomSubClass(WhiteboxContextClass)
+ if (isContextCompatible) c.info else NoType
+ case _ =>
+ NoType
+ }
}
- def isBlackboxMacroBundleType(tp: Type) =
- isMacroBundleType(tp) && (tp <:< BlackboxMacroClass.tpe) && !(tp <:< WhiteboxMacroClass.tpe)
+ def looksLikeMacroBundleType(tp: Type) =
+ macroBundleParamInfo(tp) != NoType
- def isMacroBundleProtoType(tp: Type) = {
- val sym = tp.typeSymbol
- val isNonTrivial = tp != ErrorType && tp != NothingTpe && tp != NullTpe
- def subclasses(sym: Symbol) = sym != NoSymbol && tp.baseClasses.contains(sym)
- val isMacroCompatible = subclasses(BlackboxMacroClass) ^ subclasses(WhiteboxMacroClass)
- val isBundlePrototype = sym != BlackboxMacroClass && sym != WhiteboxMacroClass && sym.isTrait && {
- val c = sym.info.member(nme.c)
- def overrides(sym: Symbol) = c.overrideChain.contains(sym)
- val cIsOk = (overrides(BlackboxMacroContextValue) || overrides(WhiteboxMacroContextValue)) && c.isDeferred
- cIsOk && sym.isMonomorphicType
- }
- isNonTrivial && isMacroCompatible && isBundlePrototype
+ def isMacroBundleType(tp: Type) = {
+ val isContextCompatible = macroBundleParamInfo(tp) != NoType
+ val hasSingleConstructor = !tp.declaration(nme.CONSTRUCTOR).isOverloaded
+ val nonAbstract = !tp.erasure.typeSymbol.isAbstractClass
+ isContextCompatible && hasSingleConstructor && nonAbstract
}
+ def isBlackboxMacroBundleType(tp: Type) =
+ isMacroBundleType(tp) && (macroBundleParamInfo(tp) <:< BlackboxContextClass.tpe)
+
def isIterableType(tp: Type) = tp <:< classExistentialType(IterableClass)
// These "direct" calls perform no dealiasing. They are most needed when
@@ -692,7 +688,7 @@ trait Definitions extends api.StandardDefinitions {
case TypeRef(pre, sym, _) if sym.isModuleClass => isStable(pre)
case TypeRef(_, _, _) if tp ne tp.dealias => isStable(tp.dealias)
case TypeVar(origin, _) => isStable(origin)
- case AnnotatedType(_, atp, _) => isStable(atp) // Really?
+ case AnnotatedType(_, atp) => isStable(atp) // Really?
case _: SimpleTypeProxy => isStable(tp.underlying)
case _ => false
}
@@ -812,46 +808,32 @@ trait Definitions extends api.StandardDefinitions {
def byNameType(arg: Type) = appliedType(ByNameParamClass, arg)
def iteratorOfType(tp: Type) = appliedType(IteratorClass, tp)
def javaRepeatedType(arg: Type) = appliedType(JavaRepeatedParamClass, arg)
+ def optionType(tp: Type) = appliedType(OptionClass, tp)
def scalaRepeatedType(arg: Type) = appliedType(RepeatedParamClass, arg)
def seqType(arg: Type) = appliedType(SeqClass, arg)
// FYI the long clunky name is because it's really hard to put "get" into the
// name of a method without it sounding like the method "get"s something, whereas
// this method is about a type member which just happens to be named get.
- def typeOfMemberNamedGet(tp: Type) = resultOfMatchingMethod(tp, nme.get)()
- def typeOfMemberNamedHead(tp: Type) = resultOfMatchingMethod(tp, nme.head)()
- def typeOfMemberNamedApply(tp: Type) = resultOfMatchingMethod(tp, nme.apply)(IntTpe)
- def typeOfMemberNamedDrop(tp: Type) = resultOfMatchingMethod(tp, nme.drop)(IntTpe)
- def typeOfMemberNamedGetOrSelf(tp: Type) = typeOfMemberNamedGet(tp) orElse tp
- def typesOfSelectors(tp: Type) = getterMemberTypes(tp, productSelectors(tp))
- def typesOfCaseAccessors(tp: Type) = getterMemberTypes(tp, tp.typeSymbol.caseFieldAccessors)
-
- /** If this is a case class, the case field accessors (which may be an empty list.)
- * Otherwise, if there are any product selectors, that list.
- * Otherwise, a list containing only the type itself.
- */
- def typesOfSelectorsOrSelf(tp: Type): List[Type] = (
- if (tp.typeSymbol.isCase)
- typesOfCaseAccessors(tp)
- else typesOfSelectors(tp) match {
- case Nil => tp :: Nil
- case tps => tps
- }
- )
-
- /** If the given type has one or more product selectors, the type of the last one.
- * Otherwise, the type itself.
- */
- def typeOfLastSelectorOrSelf(tp: Type) = typesOfSelectorsOrSelf(tp).last
-
- def elementTypeOfLastSelectorOrSelf(tp: Type) = {
- val last = typeOfLastSelectorOrSelf(tp)
- ( typeOfMemberNamedHead(last)
- orElse typeOfMemberNamedApply(last)
- orElse elementType(ArrayClass, last)
- )
+ def typeOfMemberNamedGet(tp: Type) = typeArgOfBaseTypeOr(tp, OptionClass)(resultOfMatchingMethod(tp, nme.get)())
+ def typeOfMemberNamedHead(tp: Type) = typeArgOfBaseTypeOr(tp, SeqClass)(resultOfMatchingMethod(tp, nme.head)())
+ def typeOfMemberNamedApply(tp: Type) = typeArgOfBaseTypeOr(tp, SeqClass)(resultOfMatchingMethod(tp, nme.apply)(IntTpe))
+ def typeOfMemberNamedDrop(tp: Type) = typeArgOfBaseTypeOr(tp, SeqClass)(resultOfMatchingMethod(tp, nme.drop)(IntTpe))
+ def typesOfSelectors(tp: Type) = getterMemberTypes(tp, productSelectors(tp))
+ // SI-8128 Still using the type argument of the base type at Seq/Option if this is an old-style (2.10 compatible)
+ // extractor to limit exposure to regressions like the reported problem with existentials.
+ // TODO fix the existential problem in the general case, see test/pending/pos/t8128.scala
+ private def typeArgOfBaseTypeOr(tp: Type, baseClass: Symbol)(or: => Type): Type = (tp baseType baseClass).typeArgs match {
+ case x :: Nil => x
+ case _ => or
}
+ // Can't only check for _1 thanks to pos/t796.
+ def hasSelectors(tp: Type) = (
+ (tp.members containsName nme._1)
+ && (tp.members containsName nme._2)
+ )
+
/** Returns the method symbols for members _1, _2, ..., _N
* which exist in the given type.
*/
@@ -861,7 +843,9 @@ trait Definitions extends api.StandardDefinitions {
case m if m.paramss.nonEmpty => Nil
case m => m :: loop(n + 1)
}
- loop(1)
+ // Since ErrorType always returns a symbol from a call to member, we
+ // had better not start looking for _1, _2, etc. expecting it to run out.
+ if (tpe.isErroneous) Nil else loop(1)
}
/** If `tp` has a term member `name`, the first parameter list of which
diff --git a/src/reflect/scala/reflect/internal/FlagSets.scala b/src/reflect/scala/reflect/internal/FlagSets.scala
index 84825ff2da..799f85054a 100644
--- a/src/reflect/scala/reflect/internal/FlagSets.scala
+++ b/src/reflect/scala/reflect/internal/FlagSets.scala
@@ -43,5 +43,6 @@ trait FlagSets extends api.FlagSets { self: SymbolTable =>
val PRESUPER : FlagSet = Flags.PRESUPER
val DEFAULTINIT : FlagSet = Flags.DEFAULTINIT
val SYNTHETIC : FlagSet = Flags.SYNTHETIC
+ val ENUM : FlagSet = Flags.ENUM
}
}
diff --git a/src/reflect/scala/reflect/internal/Flags.scala b/src/reflect/scala/reflect/internal/Flags.scala
index dcdf6728ce..e66ed9a3d4 100644
--- a/src/reflect/scala/reflect/internal/Flags.scala
+++ b/src/reflect/scala/reflect/internal/Flags.scala
@@ -63,7 +63,7 @@ import scala.collection.{ mutable, immutable }
// 45: SYNCHRONIZED/M
// 46: ARTIFACT
// 47: DEFAULTMETHOD/M
-// 48:
+// 48: ENUM
// 49:
// 50:
// 51: lateDEFERRED
@@ -119,6 +119,7 @@ class ModifierFlags {
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
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?)
*
@@ -142,7 +143,7 @@ class ModifierFlags {
}
object ModifierFlags extends ModifierFlags
-/** All flags and associated operatins */
+/** All flags and associated operations */
class Flags extends ModifierFlags {
final val METHOD = 1 << 6 // a method
final val MODULE = 1 << 8 // symbol is module or class implementing a module
@@ -446,7 +447,7 @@ class Flags extends ModifierFlags {
case SYNCHRONIZED => "<synchronized>" // (1L << 45)
case ARTIFACT => "<artifact>" // (1L << 46)
case DEFAULTMETHOD => "<defaultmethod>" // (1L << 47)
- case 0x1000000000000L => "" // (1L << 48)
+ case ENUM => "<enum>" // (1L << 48)
case 0x2000000000000L => "" // (1L << 49)
case 0x4000000000000L => "" // (1L << 50)
case `lateDEFERRED` => "<latedeferred>" // (1L << 51)
@@ -478,7 +479,7 @@ class Flags extends ModifierFlags {
)
@deprecated("Use flagString on the flag-carrying member", "2.10.0")
- def flagsToString(flags: Long, privateWithin: String): String = {
+ private[scala] def flagsToString(flags: Long, privateWithin: String): String = {
val access = accessString(flags, privateWithin)
val nonAccess = flagsToString(flags & ~AccessFlags)
@@ -486,7 +487,7 @@ class Flags extends ModifierFlags {
}
@deprecated("Use flagString on the flag-carrying member", "2.10.0")
- def flagsToString(flags: Long): String = {
+ private[scala] def flagsToString(flags: Long): String = {
// Fast path for common case
if (flags == 0L) "" else {
var sb: StringBuilder = null
diff --git a/src/reflect/scala/reflect/internal/HasFlags.scala b/src/reflect/scala/reflect/internal/HasFlags.scala
index ecbf839bab..1131c94da0 100644
--- a/src/reflect/scala/reflect/internal/HasFlags.scala
+++ b/src/reflect/scala/reflect/internal/HasFlags.scala
@@ -82,6 +82,7 @@ trait HasFlags {
def hasAbstractFlag = hasFlag(ABSTRACT)
def hasAccessorFlag = hasFlag(ACCESSOR)
def hasDefault = hasFlag(DEFAULTPARAM) && hasFlag(METHOD | PARAM) // Second condition disambiguates with TRAIT
+ def hasEnumFlag = hasFlag(ENUM)
def hasLocalFlag = hasFlag(LOCAL)
def hasModuleFlag = hasFlag(MODULE)
def hasPackageFlag = hasFlag(PACKAGE)
diff --git a/src/reflect/scala/reflect/internal/Importers.scala b/src/reflect/scala/reflect/internal/Importers.scala
index 26d55e21c4..483d0dd656 100644
--- a/src/reflect/scala/reflect/internal/Importers.scala
+++ b/src/reflect/scala/reflect/internal/Importers.scala
@@ -268,8 +268,8 @@ trait Importers extends api.Importers { to: SymbolTable =>
val myconstr = new TypeConstraint(their.constr.loBounds map importType, their.constr.hiBounds map importType)
myconstr.inst = importType(their.constr.inst)
TypeVar(importType(their.origin), myconstr, their.typeArgs map importType, their.params map importSymbol)
- case from.AnnotatedType(annots, result, selfsym) =>
- AnnotatedType(annots map importAnnotationInfo, importType(result), importSymbol(selfsym))
+ case from.AnnotatedType(annots, result) =>
+ AnnotatedType(annots map importAnnotationInfo, importType(result))
case from.ErrorType =>
ErrorType
case from.WildcardType =>
diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala
index 9c5a593ca5..6cf4944d18 100644
--- a/src/reflect/scala/reflect/internal/Mirrors.scala
+++ b/src/reflect/scala/reflect/internal/Mirrors.scala
@@ -186,6 +186,15 @@ 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
+ else pre member nme.PACKAGE // otherwise we have to findMember
+ }
override def staticPackage(fullname: String): ModuleSymbol =
ensurePackageSymbol(fullname.toString, getModuleOrClass(newTermNameCached(fullname)), allowModules = false)
diff --git a/src/reflect/scala/reflect/internal/Printers.scala b/src/reflect/scala/reflect/internal/Printers.scala
index 424e73dce8..519d1047a6 100644
--- a/src/reflect/scala/reflect/internal/Printers.scala
+++ b/src/reflect/scala/reflect/internal/Printers.scala
@@ -17,8 +17,6 @@ trait Printers extends api.Printers { self: SymbolTable =>
//nsc import treeInfo.{ IsTrue, IsFalse }
- final val showOuterTests = false
-
/** Adds backticks if the name is a scala keyword. */
def quotedName(name: Name, decode: Boolean): String = {
val s = if (decode) name.decode else name.toString
@@ -53,8 +51,8 @@ trait Printers extends api.Printers { self: SymbolTable =>
*/
def backquotedPath(t: Tree): String = {
t match {
- case Select(qual, name) if name.isTermName => "%s.%s".format(backquotedPath(qual), symName(t, name))
- case Select(qual, name) if name.isTypeName => "%s#%s".format(backquotedPath(qual), symName(t, name))
+ case Select(qual, name) if name.isTermName => s"${backquotedPath(qual)}.${symName(t, name)}"
+ case Select(qual, name) if name.isTypeName => s"${backquotedPath(qual)}#${symName(t, name)}"
case Ident(name) => symName(t, name)
case _ => t.toString
}
@@ -76,7 +74,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
def printPosition(tree: Tree) = if (printPositions) print(tree.pos.show)
- def println() {
+ def println() = {
out.println()
while (indentMargin > indentString.length())
indentString += indentString
@@ -84,116 +82,221 @@ trait Printers extends api.Printers { self: SymbolTable =>
out.write(indentString, 0, indentMargin)
}
- def printSeq[a](ls: List[a])(printelem: a => Unit)(printsep: => Unit) {
+ def printSeq[a](ls: List[a])(printelem: a => Unit)(printsep: => Unit): Unit =
ls match {
case List() =>
case List(x) => printelem(x)
case x :: rest => printelem(x); printsep; printSeq(rest)(printelem)(printsep)
}
- }
- def printColumn(ts: List[Tree], start: String, sep: String, end: String) {
+ def printColumn(ts: List[Tree], start: String, sep: String, end: String) = {
print(start); indent(); println()
printSeq(ts){print(_)}{print(sep); println()}; undent(); println(); print(end)
}
- def printRow(ts: List[Tree], start: String, sep: String, end: String) {
+ def printRow(ts: List[Tree], start: String, sep: String, end: String): Unit = {
print(start); printSeq(ts){print(_)}{print(sep)}; print(end)
}
- def printRow(ts: List[Tree], sep: String) { printRow(ts, "", sep, "") }
+ def printRow(ts: List[Tree], sep: String): Unit = printRow(ts, "", sep, "")
- def printTypeParams(ts: List[TypeDef]) {
- if (!ts.isEmpty) {
+ def printTypeParams(ts: List[TypeDef]): Unit =
+ if (ts.nonEmpty) {
print("["); printSeq(ts){ t =>
printAnnotations(t)
+ if (t.mods.hasFlag(CONTRAVARIANT)) {
+ print("-")
+ } else if (t.mods.hasFlag(COVARIANT)) {
+ print("+")
+ }
printParam(t)
}{print(", ")}; print("]")
}
- }
- def printLabelParams(ps: List[Ident]) {
+ def printLabelParams(ps: List[Ident]) = {
print("(")
printSeq(ps){printLabelParam}{print(", ")}
print(")")
}
- def printLabelParam(p: Ident) {
+ def printLabelParam(p: Ident) = {
print(symName(p, p.name)); printOpt(": ", TypeTree() setType p.tpe)
}
- def printValueParams(ts: List[ValDef]) {
- print("(")
- if (!ts.isEmpty) printFlags(ts.head.mods.flags & IMPLICIT, "")
- printSeq(ts){printParam}{print(", ")}
- print(")")
+ protected def parenthesize(condition: Boolean = true)(body: => Unit) = {
+ if (condition) print("(")
+ body
+ if (condition) print(")")
}
+
+ protected def printImplicitInParamsList(vds: List[ValDef]) =
+ if (vds.nonEmpty) printFlags(vds.head.mods.flags & IMPLICIT, "")
+
+ def printValueParams(ts: List[ValDef], inParentheses: Boolean = true): Unit =
+ parenthesize(inParentheses){
+ printImplicitInParamsList(ts)
+ printSeq(ts){printParam}{print(", ")}
+ }
- def printParam(tree: Tree) {
+ def printParam(tree: Tree) =
tree match {
- case ValDef(mods, name, tp, rhs) =>
+ case vd @ ValDef(mods, name, tp, rhs) =>
printPosition(tree)
- printAnnotations(tree)
+ printAnnotations(vd)
print(symName(tree, name)); printOpt(": ", tp); printOpt(" = ", rhs)
case TypeDef(mods, name, tparams, rhs) =>
printPosition(tree)
print(symName(tree, name))
printTypeParams(tparams); print(rhs)
}
- }
- def printBlock(tree: Tree) {
+ def printBlock(tree: Tree) =
tree match {
case Block(_, _) =>
print(tree)
case _ =>
printColumn(List(tree), "{", ";", "}")
}
- }
private def symFn[T](tree: Tree, f: Symbol => T, orElse: => T): T = tree.symbol match {
- case null | NoSymbol => orElse
- case sym => f(sym)
+ case null | NoSymbol => orElse
+ case sym => f(sym)
}
private def ifSym(tree: Tree, p: Symbol => Boolean) = symFn(tree, p, false)
- def printOpt(prefix: String, tree: Tree) {
- if (!tree.isEmpty) { print(prefix, tree) }
- }
+ def printOpt(prefix: String, tree: Tree) = if (tree.nonEmpty) { print(prefix, tree) }
def printModifiers(tree: Tree, mods: Modifiers): Unit = printFlags(
- if (tree.symbol == NoSymbol) mods.flags else tree.symbol.flags, "" + (
- if (tree.symbol == NoSymbol) mods.privateWithin
- else if (tree.symbol.hasAccessBoundary) tree.symbol.privateWithin.name
- else ""
+ if (tree.symbol == NoSymbol) mods.flags else tree.symbol.flags, "" + (
+ if (tree.symbol == NoSymbol) mods.privateWithin
+ else if (tree.symbol.hasAccessBoundary) tree.symbol.privateWithin.name
+ else ""
)
)
- def printFlags(flags: Long, privateWithin: String) {
+ def printFlags(flags: Long, privateWithin: String) = {
val mask: Long = if (settings.debug) -1L else PrintableFlags
val s = flagsToString(flags & mask, privateWithin)
if (s != "") print(s + " ")
}
- def printAnnotations(tree: Tree) {
+ def printAnnotations(tree: MemberDef) = {
// SI-5885: by default this won't print annotations of not yet initialized symbols
val annots = tree.symbol.annotations match {
- case Nil => tree.asInstanceOf[MemberDef].mods.annotations
+ case Nil => tree.mods.annotations
case anns => anns
}
- annots foreach (annot => print("@"+annot+" "))
+ annots foreach (annot => print(s"@$annot "))
}
private var currentOwner: Symbol = NoSymbol
private var selectorType: Type = NoType
+
+ protected def printPackageDef(tree: PackageDef, separator: String) = {
+ val PackageDef(packaged, stats) = tree
+ printAnnotations(tree)
+ print("package ", packaged); printColumn(stats, " {", separator, "}")
+ }
+
+ protected def printValDef(tree: ValDef, resultName: => String)(printTypeSignature: => Unit)(printRhs: => Unit) = {
+ val ValDef(mods, name, tp, rhs) = tree
+ printAnnotations(tree)
+ printModifiers(tree, mods)
+ print(if (mods.isMutable) "var " else "val ", resultName)
+ printTypeSignature
+ printRhs
+ }
+
+ protected def printDefDef(tree: DefDef, resultName: => String)(printTypeSignature: => Unit)(printRhs: => Unit) = {
+ val DefDef(mods, name, tparams, vparamss, tp, rhs) = tree
+ printAnnotations(tree)
+ printModifiers(tree, mods)
+ print("def " + resultName)
+ printTypeParams(tparams);
+ vparamss foreach {printValueParams(_)}
+ printTypeSignature
+ printRhs
+ }
+
+ protected def printTypeDef(tree: TypeDef, resultName: => String) = {
+ val TypeDef(mods, name, tparams, rhs) = tree
+ if (mods hasFlag (PARAM | DEFERRED)) {
+ printAnnotations(tree)
+ printModifiers(tree, mods)
+ print("type ")
+ printParam(tree)
+ } else {
+ printAnnotations(tree)
+ printModifiers(tree, mods)
+ print("type " + resultName)
+ printTypeParams(tparams)
+ printOpt(" = ", rhs)
+ }
+ }
+
+ protected def printImport(tree: Import, resSelect: => String) = {
+ val Import(expr, selectors) = tree
+ // Is this selector renaming a name (i.e, {name1 => name2})
+ def isNotRename(s: ImportSelector): Boolean =
+ s.name == nme.WILDCARD || s.name == s.rename
+
+ def selectorToString(s: ImportSelector): String = {
+ val from = quotedName(s.name)
+ if (isNotRename(s)) from
+ else from + "=>" + quotedName(s.rename)
+ }
+ print("import ", resSelect, ".")
+ selectors match {
+ case List(s) =>
+ // If there is just one selector and it is not renaming a name, no braces are needed
+ if (isNotRename(s)) print(selectorToString(s))
+ else print("{", selectorToString(s), "}")
+ // If there is more than one selector braces are always needed
+ case many =>
+ print(many.map(selectorToString).mkString("{", ", ", "}"))
+ }
+ }
+
+ protected def printCaseDef(tree: CaseDef) = {
+ val CaseDef(pat, guard, body) = tree
+ print("case ")
+ def patConstr(pat: Tree): Tree = pat match {
+ case Apply(fn, args) => patConstr(fn)
+ case _ => pat
+ }
+
+ print(pat); printOpt(" if ", guard)
+ print(" => ", body)
+ }
+
+ protected def printFunction(tree: Function)(printValueParams: => Unit) = {
+ val Function(vparams, body) = tree
+ print("(");
+ printValueParams
+ print(" => ", body, ")")
+ if (printIds && tree.symbol != null) print("#" + tree.symbol.id)
+ }
+
+ protected def printSuper(tree: Super, resultName: => String) = {
+ val Super(This(qual), mix) = tree
+ if (qual.nonEmpty || tree.symbol != NoSymbol) print(resultName + ".")
+ print("super")
+ if (mix.nonEmpty) print(s"[$mix]")
+ }
+
+ protected def printThis(tree: This, resultName: => String) = {
+ val This(qual) = tree
+ if (qual.nonEmpty) print(resultName + ".")
+ print("this")
+ }
- def printTree(tree: Tree) {
+ def printTree(tree: Tree) = {
tree match {
case EmptyTree =>
print("<empty>")
- case ClassDef(mods, name, tparams, impl) =>
- printAnnotations(tree)
+ case cd @ ClassDef(mods, name, tparams, impl) =>
+ printAnnotations(cd)
printModifiers(tree, mods)
val word =
if (mods.isTrait) "trait"
@@ -204,81 +307,45 @@ trait Printers extends api.Printers { self: SymbolTable =>
printTypeParams(tparams)
print(if (mods.isDeferred) " <: " else " extends ", impl)
- case PackageDef(packaged, stats) =>
- printAnnotations(tree)
- print("package ", packaged); printColumn(stats, " {", ";", "}")
+ case pd @ PackageDef(packaged, stats) =>
+ printPackageDef(pd, ";")
- case ModuleDef(mods, name, impl) =>
- printAnnotations(tree)
+ case md @ ModuleDef(mods, name, impl) =>
+ printAnnotations(md)
printModifiers(tree, mods)
print("object " + symName(tree, name), " extends ", impl)
- case ValDef(mods, name, tp, rhs) =>
- printAnnotations(tree)
- printModifiers(tree, mods)
- print(if (mods.isMutable) "var " else "val ", symName(tree, name))
- printOpt(": ", tp)
- if (!mods.isDeferred)
- print(" = ", if (rhs.isEmpty) "_" else rhs)
+ case vd @ ValDef(mods, name, tp, rhs) =>
+ printValDef(vd, symName(tree, name))(printOpt(": ", tp)) {
+ if (!mods.isDeferred) print(" = ", if (rhs.isEmpty) "_" else rhs)
+ }
- case DefDef(mods, name, tparams, vparamss, tp, rhs) =>
- printAnnotations(tree)
- printModifiers(tree, mods)
- print("def " + symName(tree, name))
- printTypeParams(tparams); vparamss foreach printValueParams
- printOpt(": ", tp); printOpt(" = ", rhs)
+ case dd @ DefDef(mods, name, tparams, vparamss, tp, rhs) =>
+ printDefDef(dd, symName(tree, name))(printOpt(": ", tp))(printOpt(" = ", rhs))
- case TypeDef(mods, name, tparams, rhs) =>
- if (mods hasFlag (PARAM | DEFERRED)) {
- printAnnotations(tree)
- printModifiers(tree, mods); print("type "); printParam(tree)
- } else {
- printAnnotations(tree)
- printModifiers(tree, mods); print("type " + symName(tree, name))
- printTypeParams(tparams); printOpt(" = ", rhs)
- }
+ case td @ TypeDef(mods, name, tparams, rhs) =>
+ printTypeDef(td, symName(tree, name))
case LabelDef(name, params, rhs) =>
print(symName(tree, name)); printLabelParams(params); printBlock(rhs)
- case Import(expr, selectors) =>
- // Is this selector remapping a name (i.e, {name1 => name2})
- def isNotRemap(s: ImportSelector) : Boolean = (s.name == nme.WILDCARD || s.name == s.rename)
- def selectorToString(s: ImportSelector): String = {
- val from = quotedName(s.name)
- if (isNotRemap(s)) from
- else from + "=>" + quotedName(s.rename)
- }
- print("import ", backquotedPath(expr), ".")
- selectors match {
- case List(s) =>
- // If there is just one selector and it is not remapping a name, no braces are needed
- if (isNotRemap(s)) print(selectorToString(s))
- else print("{", selectorToString(s), "}")
- // If there is more than one selector braces are always needed
- case many =>
- print(many.map(selectorToString).mkString("{", ", ", "}"))
- }
+ case imp @ Import(expr, _) =>
+ printImport(imp, backquotedPath(expr))
- case Template(parents, self, body) =>
+ case Template(parents, self, body) =>
val currentOwner1 = currentOwner
if (tree.symbol != NoSymbol) currentOwner = tree.symbol.owner
-// if (parents exists isReferenceToAnyVal) {
-// print("AnyVal")
-// }
-// else {
printRow(parents, " with ")
- if (!body.isEmpty) {
+ if (body.nonEmpty) {
if (self.name != nme.WILDCARD) {
print(" { ", self.name); printOpt(": ", self.tpt); print(" => ")
- } else if (!self.tpt.isEmpty) {
+ } else if (self.tpt.nonEmpty) {
print(" { _ : ", self.tpt, " => ")
} else {
print(" {")
}
printColumn(body, "", ";", "}")
}
-// }
currentOwner = currentOwner1
case Block(stats, expr) =>
@@ -290,18 +357,8 @@ trait Printers extends api.Printers { self: SymbolTable =>
print(selector); printColumn(cases, " match {", "", "}")
selectorType = selectorType1
- case CaseDef(pat, guard, body) =>
- print("case ")
- def patConstr(pat: Tree): Tree = pat match {
- case Apply(fn, args) => patConstr(fn)
- case _ => pat
- }
- if (showOuterTests &&
- needsOuterTest(
- patConstr(pat).tpe.finalResultType, selectorType, currentOwner))
- print("???")
- print(pat); printOpt(" if ", guard)
- print(" => ", body)
+ case cd @ CaseDef(pat, guard, body) =>
+ printCaseDef(cd)
case Alternative(trees) =>
printRow(trees, "(", "| ", ")")
@@ -318,9 +375,8 @@ trait Printers extends api.Printers { self: SymbolTable =>
case ArrayValue(elemtpt, trees) =>
print("Array[", elemtpt); printRow(trees, "]{", ", ", "}")
- case Function(vparams, body) =>
- print("("); printValueParams(vparams); print(" => ", body, ")")
- if (printIds && tree.symbol != null) print("#"+tree.symbol.id)
+ case f @ Function(vparams, body) =>
+ printFunction(f)(printValueParams(vparams))
case Assign(lhs, rhs) =>
print(lhs, " = ", rhs)
@@ -331,7 +387,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
case If(cond, thenp, elsep) =>
print("if (", cond, ")"); indent(); println()
print(thenp); undent()
- if (!elsep.isEmpty) {
+ if (elsep.nonEmpty) {
println(); print("else"); indent(); println(); print(elsep); undent()
}
@@ -340,7 +396,7 @@ trait Printers extends api.Printers { self: SymbolTable =>
case Try(block, catches, finalizer) =>
print("try "); printBlock(block)
- if (!catches.isEmpty) printColumn(catches, " catch {", "", "}")
+ if (catches.nonEmpty) printColumn(catches, " catch {", "", "}")
printOpt(" finally ", finalizer)
case Throw(expr) =>
@@ -362,22 +418,18 @@ trait Printers extends api.Printers { self: SymbolTable =>
print("<apply-dynamic>(", qual, "#", tree.symbol.nameString)
printRow(vargs, ", (", ", ", "))")
- case Super(This(qual), mix) =>
- if (!qual.isEmpty || tree.symbol != NoSymbol) print(symName(tree, qual) + ".")
- print("super")
- if (!mix.isEmpty)
- print("[" + mix + "]")
+ case st @ Super(This(qual), mix) =>
+ printSuper(st, symName(tree, qual))
case Super(qual, mix) =>
print(qual, ".super")
- if (!mix.isEmpty)
+ if (mix.nonEmpty)
print("[" + mix + "]")
- case This(qual) =>
- if (!qual.isEmpty) print(symName(tree, qual) + ".")
- print("this")
+ case th @ This(qual) =>
+ printThis(th, symName(tree, qual))
- case Select(qual @ New(tpe), name) if !settings.debug =>
+ case Select(qual: New, name) if !settings.debug =>
print(qual)
case Select(qualifier, name) =>
@@ -400,10 +452,10 @@ trait Printers extends api.Printers { self: SymbolTable =>
print(tree.tpe.toString)
}
- case Annotated(Apply(Select(New(tpt), nme.CONSTRUCTOR), args), tree) =>
+ case an @ Annotated(Apply(Select(New(tpt), nme.CONSTRUCTOR), args), tree) =>
def printAnnot() {
print("@", tpt)
- if (!args.isEmpty)
+ if (args.nonEmpty)
printRow(args, "(", ",", ")")
}
print(tree, if (tree.isType) " " else ": ")
@@ -435,11 +487,11 @@ trait Printers extends api.Printers { self: SymbolTable =>
print(tpt)
printColumn(whereClauses, " forSome { ", ";", "}")
-// SelectFromArray is no longer visible in scala.reflect.internal.
-// eliminated until we figure out what we will do with both Printers and
-// SelectFromArray.
-// case SelectFromArray(qualifier, name, _) =>
-// print(qualifier); print(".<arr>"); print(symName(tree, name))
+ // SelectFromArray is no longer visible in scala.reflect.internal.
+ // eliminated until we figure out what we will do with both Printers and
+ // SelectFromArray.
+ // case SelectFromArray(qualifier, name, _) =>
+ // print(qualifier); print(".<arr>"); print(symName(tree, name))
case tree =>
xprintTree(this, tree)
@@ -459,11 +511,498 @@ trait Printers extends api.Printers { self: SymbolTable =>
out.print(if (arg == null) "null" else arg.toString)
}
}
+
+ // it's the printer for trees after parser and before typer phases
+ class ParsedTreePrinter(out: PrintWriter) extends TreePrinter(out) {
+ override def withTypes = this
+ override def withIds = this
+ override def withKinds = this
+ override def withMirrors = this
+ override def withPositions = this
+
+ // TODO: add print parameters to typed trees printer
+ printTypes = false
+ printIds = false
+ printKinds = false
+ printMirrors = false
+ printPositions = false
+
+ protected val parentsStack = scala.collection.mutable.Stack[Tree]()
+
+ protected def currentTree = if (parentsStack.nonEmpty) Some(parentsStack.top) else None
+
+ protected def currentParent = if (parentsStack.length > 1) Some(parentsStack(1)) else None
+
+ protected def printedName(name: Name, decoded: Boolean = true) = {
+ import Chars._
+ val decName = name.decoded
+ val bslash = '\\'
+ val brackets = List('[',']','(',')','{','}')
+
+ def addBackquotes(s: String) =
+ if (decoded && (decName.exists(ch => brackets.contains(ch) || isWhitespace(ch)) ||
+ (name.isOperatorName && decName.exists(isOperatorPart) && decName.exists(isScalaLetter) && !decName.contains(bslash))))
+ s"`$s`" else s
+
+ if (name == nme.CONSTRUCTOR) "this"
+ else addBackquotes(quotedName(name, decoded))
+ }
+
+ protected def isIntLitWithDecodedOp(qual: Tree, name: Name) = {
+ val qualIsIntLit = qual match {
+ case Literal(Constant(x: Int)) => true
+ case _ => false
+ }
+ qualIsIntLit && name.isOperatorName
+ }
+
+ protected def needsParentheses(parent: Tree)(insideIf: Boolean = true, insideMatch: Boolean = true,
+ insideTry: Boolean = true, insideAnnotated: Boolean = true, insideBlock: Boolean = true, insideLabelDef: Boolean = true) = {
+ parent match {
+ case _: If => insideIf
+ case _: Match => insideMatch
+ case _: Try => insideTry
+ case _: Annotated => insideAnnotated
+ case _: Block => insideBlock
+ case _: LabelDef => insideLabelDef
+ case _ => false
+ }
+ }
+
+ protected def checkForBlank(cond: Boolean) = if (cond) " " else ""
+ protected def blankForOperatorName(name: Name) = checkForBlank(name.isOperatorName)
+ protected def blankForName(name: Name) = checkForBlank(name.isOperatorName || name.endsWith("_"))
+
+ protected def resolveSelect(t: Tree): String = {
+ t match {
+ // case for: 1) (if (a) b else c).meth1.meth2 or 2) 1 + 5 should be represented as (1).+(5)
+ case Select(qual, name) if (name.isTermName && needsParentheses(qual)(insideLabelDef = false)) || isIntLitWithDecodedOp(qual, name) => s"(${resolveSelect(qual)}).${printedName(name)}"
+ case Select(qual, name) if name.isTermName => s"${resolveSelect(qual)}.${printedName(name)}"
+ case Select(qual, name) if name.isTypeName => s"${resolveSelect(qual)}#${blankForOperatorName(name)}%${printedName(name)}"
+ case Ident(name) => printedName(name)
+ case _ => showCode(t)
+ }
+ }
+
+ val defaultClasses = List(tpnme.AnyRef)
+ val defaultTraitsForCase = List(tpnme.Product, tpnme.Serializable)
+ protected def removeDefaultTypesFromList(trees: List[Tree])(classesToRemove: List[Name] = defaultClasses)(traitsToRemove: List[Name]) = {
+ def removeDefaultTraitsFromList(trees: List[Tree], traitsToRemove: List[Name]): List[Tree] =
+ trees match {
+ case Nil => trees
+ case init :+ last => last match {
+ case Select(Ident(sc), name) if traitsToRemove.contains(name) && sc == nme.scala_ =>
+ removeDefaultTraitsFromList(init, traitsToRemove)
+ case _ => trees
+ }
+ }
+
+ removeDefaultTraitsFromList(removeDefaultClassesFromList(trees, classesToRemove), traitsToRemove)
+ }
+
+ protected def removeDefaultClassesFromList(trees: List[Tree], classesToRemove: List[Name] = defaultClasses) = trees filter {
+ case Select(Ident(sc), name) => !(classesToRemove.contains(name) && sc == nme.scala_)
+ case _ => true
+ }
+
+ def printFlags(mods: Modifiers, primaryCtorParam: Boolean = false): Unit = {
+ val base = AccessFlags | OVERRIDE | ABSTRACT | FINAL | SEALED | LAZY
+ val mask = if (primaryCtorParam) base else base | IMPLICIT
+
+ val s = mods.flagString(mask)
+ if (s != "") print(s"$s ")
+ // case flag should be the last
+ if (mods.isCase) print(mods.flagBitsToString(CASE) + " ")
+ if (mods.isAbstractOverride) print("abstract override ")
+ }
+
+ override def printModifiers(tree: Tree, mods: Modifiers): Unit = printModifiers(mods, primaryCtorParam = false)
+
+ def printModifiers(mods: Modifiers, primaryCtorParam: Boolean): Unit = {
+ def modsAccepted = List(currentTree, currentParent) exists (_ map {
+ case _: ClassDef | _: ModuleDef | _: Template | _: PackageDef => true
+ case _ => false
+ } getOrElse false)
+
+ if (currentParent.isEmpty || modsAccepted)
+ printFlags(mods, primaryCtorParam)
+ else
+ List(IMPLICIT, CASE, LAZY, SEALED).foreach{flag => if (mods.hasFlag(flag)) print(s"${mods.flagBitsToString(flag)} ")}
+ }
+
+ def printParam(tree: Tree, primaryCtorParam: Boolean): Unit =
+ tree match {
+ case vd @ ValDef(mods, name, tp, rhs) =>
+ printAnnotations(vd)
+ val mutableOrOverride = mods.isOverride || mods.isMutable
+ val hideCtorMods = mods.isParamAccessor && mods.isPrivateLocal && !mutableOrOverride
+ val hideCaseCtorMods = mods.isCaseAccessor && mods.isPublic && !mutableOrOverride
+
+ if (primaryCtorParam && !(hideCtorMods || hideCaseCtorMods)) {
+ printModifiers(mods, primaryCtorParam)
+ print(if (mods.isMutable) "var " else "val ");
+ }
+ print(printedName(name), blankForName(name));
+ printOpt(": ", tp);
+ printOpt(" = ", rhs)
+ case TypeDef(_, name, tparams, rhs) =>
+ print(printedName(name))
+ printTypeParams(tparams);
+ print(rhs)
+ case _ =>
+ super.printParam(tree)
+ }
+
+ override def printParam(tree: Tree): Unit = {
+ printParam(tree, primaryCtorParam = false)
+ }
+
+ protected def printArgss(argss: List[List[Tree]]) =
+ argss foreach {x: List[Tree] => if (!(x.isEmpty && argss.size == 1)) printRow(x, "(", ", ", ")")}
+
+ override def printAnnotations(tree: MemberDef) = {
+ val annots = tree.mods.annotations
+ annots foreach {annot => printAnnot(annot); print(" ")}
+ }
+
+ protected def printAnnot(tree: Tree) = {
+ tree match {
+ case treeInfo.Applied(core, _, argss) =>
+ print("@")
+ core match {
+ case Select(New(tree), _) => print(tree)
+ case _ =>
+ }
+ printArgss(argss)
+ case _ => super.printTree(tree)
+ }
+ }
+
+ override def printTree(tree: Tree): Unit = {
+ parentsStack.push(tree)
+ tree match {
+ case cl @ ClassDef(mods, name, tparams, impl) =>
+ if (mods.isJavaDefined) super.printTree(cl)
+ printAnnotations(cl)
+ // traits
+ val clParents: List[Tree] = if (mods.isTrait) {
+ // avoid abstract modifier for traits
+ printModifiers(tree, mods &~ ABSTRACT)
+ print("trait ", printedName(name))
+ printTypeParams(tparams)
+
+ val build.SyntacticTraitDef(_, _, _, _, parents, _, _) = tree
+ parents
+ // classes
+ } else {
+ printModifiers(tree, mods)
+ print("class ", printedName(name))
+ printTypeParams(tparams)
+
+ val build.SyntacticClassDef(_, _, _, ctorMods, vparamss, earlyDefs, parents, selfType, body) = cl
+
+ // constructor's modifier
+ if (ctorMods.hasFlag(AccessFlags)) {
+ print(" ")
+ printModifiers(ctorMods, primaryCtorParam = false)
+ }
+
+ def printConstrParams(ts: List[ValDef]): Unit = {
+ parenthesize() {
+ printImplicitInParamsList(ts)
+ printSeq(ts)(printParam(_, primaryCtorParam = true))(print(", "))
+ }
+ }
+ // constructor's params processing (don't print single empty constructor param list)
+ vparamss match {
+ case Nil | List(Nil) if (!mods.isCase && !ctorMods.hasFlag(AccessFlags)) =>
+ case _ => vparamss foreach printConstrParams
+ }
+ parents
+ }
+
+ // get trees without default classes and traits (when they are last)
+ val printedParents = removeDefaultTypesFromList(clParents)()(if (mods.hasFlag(CASE)) defaultTraitsForCase else Nil)
+ print(if (mods.isDeferred) "<: " else if (printedParents.nonEmpty) " extends " else "", impl)
+
+ case pd @ PackageDef(packaged, stats) =>
+ packaged match {
+ case Ident(name) if name == nme.EMPTY_PACKAGE_NAME =>
+ printSeq(stats) {
+ print(_)
+ } {
+ print(";");
+ println()
+ };
+ case _ =>
+ val separator = scala.util.Properties.lineSeparator
+ printPackageDef(pd, separator)
+ }
+
+ case md @ ModuleDef(mods, name, impl) =>
+ printAnnotations(md)
+ printModifiers(tree, mods)
+ val Template(parents, self, methods) = impl
+ val parWithoutAnyRef = removeDefaultClassesFromList(parents)
+ print("object " + printedName(name), if (parWithoutAnyRef.nonEmpty) " extends " else "", impl)
+
+ case vd @ ValDef(mods, name, tp, rhs) =>
+ printValDef(vd, printedName(name)) {
+ // place space after symbolic def name (val *: Unit does not compile)
+ printOpt(s"${blankForName(name)}: ", tp)
+ } {
+ if (!mods.isDeferred) print(" = ", if (rhs.isEmpty) "_" else rhs)
+ }
+
+ case dd @ DefDef(mods, name, tparams, vparamss, tp, rhs) =>
+ printDefDef(dd, printedName(name)) {
+ if (tparams.isEmpty && (vparamss.isEmpty || vparamss(0).isEmpty)) print(blankForName(name))
+ printOpt(": ", tp)
+ } {
+ printOpt(" = " + (if (mods.isMacro) "macro " else ""), rhs)
+ }
+
+ case td @ TypeDef(mods, name, tparams, rhs) =>
+ printTypeDef(td, printedName(name))
+
+ case LabelDef(name, params, rhs) =>
+ if (name.startsWith(nme.WHILE_PREFIX)) {
+ val If(cond, thenp, elsep) = rhs
+ print("while (", cond, ") ")
+ val Block(list, wh) = thenp
+ printColumn(list, "", ";", "")
+ } else if (name.startsWith(nme.DO_WHILE_PREFIX)) {
+ val Block(bodyList, ifCond @ If(cond, thenp, elsep)) = rhs
+ print("do ")
+ printColumn(bodyList, "", ";", "")
+ print(" while (", cond, ") ")
+ } else {
+ print(printedName(name)); printLabelParams(params);
+ printBlock(rhs)
+ }
+
+ case imp @ Import(expr, _) =>
+ printImport(imp, resolveSelect(expr))
+
+ case Template(parents, self, body) =>
+ val printedParents =
+ currentParent map {
+ case _: CompoundTypeTree => parents
+ case ClassDef(mods, name, _, _) if mods.isCase => removeDefaultTypesFromList(parents)()(List(tpnme.Product, tpnme.Serializable))
+ case _ => removeDefaultClassesFromList(parents)
+ } getOrElse (parents)
+
+ val primaryCtr = treeInfo.firstConstructor(body)
+ val ap: Option[Apply] = primaryCtr match {
+ case DefDef(_, _, _, _, _, Block(ctBody, _)) =>
+ val earlyDefs = treeInfo.preSuperFields(ctBody) ::: body.filter {
+ case td: TypeDef => treeInfo.isEarlyDef(td)
+ case _ => false
+ }
+ if (earlyDefs.nonEmpty) {
+ print("{")
+ printColumn(earlyDefs, "", ";", "")
+ print("} " + (if (printedParents.nonEmpty) "with " else ""))
+ }
+ ctBody collectFirst {
+ case apply: Apply => apply
+ }
+ case _ => None
+ }
+
+ if (printedParents.nonEmpty) {
+ val (clParent :: traits) = printedParents
+ print(clParent)
+
+ val constrArgss = ap match {
+ case Some(treeInfo.Applied(_, _, argss)) => argss
+ case _ => Nil
+ }
+ printArgss(constrArgss)
+ if (traits.nonEmpty) {
+ printRow(traits, " with ", " with ", "")
+ }
+ }
+ /* Remove primary constr def and constr val and var defs
+ * right contains all constructors
+ */
+ val (left, right) = body.filter {
+ // remove valdefs defined in constructor and presuper vals
+ case vd: ValDef => !vd.mods.isParamAccessor && !treeInfo.isEarlyValDef(vd)
+ // remove $this$ from traits
+ case dd: DefDef => dd.name != nme.MIXIN_CONSTRUCTOR
+ case td: TypeDef => !treeInfo.isEarlyDef(td)
+ case EmptyTree => false
+ case _ => true
+ } span {
+ case dd: DefDef => dd.name != nme.CONSTRUCTOR
+ case _ => true
+ }
+ val modBody = left ::: right.drop(1)
+ val showBody = !(modBody.isEmpty && (self == noSelfType || self.isEmpty))
+ if (showBody) {
+ if (self.name != nme.WILDCARD) {
+ print(" { ", self.name);
+ printOpt(": ", self.tpt);
+ print(" =>")
+ } else if (self.tpt.nonEmpty) {
+ print(" { _ : ", self.tpt, " =>")
+ } else {
+ print(" {")
+ }
+ printColumn(modBody, "", ";", "}")
+ }
+
+ case Block(stats, expr) => super.printTree(tree)
+
+ case Match(selector, cases) =>
+ /* Insert braces if match is inner
+ * make this function available for other cases
+ * passing required type for checking
+ */
+ def insertBraces(body: => Unit): Unit =
+ if (parentsStack.nonEmpty && parentsStack.tail.exists(_.isInstanceOf[Match])) {
+ print("(")
+ body
+ print(")")
+ } else body
+
+ val printParentheses = needsParentheses(selector)(insideLabelDef = false)
+ tree match {
+ case Match(EmptyTree, cs) =>
+ printColumn(cases, "{", "", "}")
+ case _ =>
+ insertBraces {
+ parenthesize(printParentheses)(print(selector))
+ printColumn(cases, " match {", "", "}")
+ }
+ }
+
+ case cd @ CaseDef(pat, guard, body) =>
+ printCaseDef(cd)
+
+ case Star(elem) =>
+ print(elem, "*")
+
+ case Bind(name, t) =>
+ if (t == EmptyTree) print("(", printedName(name), ")")
+ else if (t.exists(_.isInstanceOf[Star])) print(printedName(name), " @ ", t)
+ else print("(", printedName(name), " @ ", t, ")")
+
+ case f @ Function(vparams, body) =>
+ // parentheses are not allowed for val a: Int => Int = implicit x => x
+ val printParentheses = vparams match {
+ case head :: _ => !head.mods.isImplicit
+ case _ => true
+ }
+ printFunction(f)(printValueParams(vparams, inParentheses = printParentheses))
+
+ case Typed(expr, tp) =>
+ tp match {
+ case Function(List(), EmptyTree) => print("(", expr, " _)") //func _
+ // parentheses required when (a match {}) : Type
+ case _ => print("((", expr, "): ", tp, ")")
+ }
+
+ case Apply(fun, vargs) =>
+ tree match {
+ // processing methods ending on colons (x \: list)
+ case Apply(Block(l1 @ List(sVD: ValDef), a1 @ Apply(Select(_, methodName), l2 @ List(Ident(iVDName)))), l3)
+ if sVD.mods.isSynthetic && treeInfo.isLeftAssoc(methodName) && sVD.name == iVDName =>
+ val printBlock = Block(l1, Apply(a1, l3))
+ print(printBlock)
+ case Apply(tree1, _) if (needsParentheses(tree1)(insideAnnotated = false)) =>
+ parenthesize()(print(fun)); printRow(vargs, "(", ", ", ")")
+ case _ => super.printTree(tree)
+ }
+
+ case st @ Super(This(qual), mix) =>
+ printSuper(st, printedName(qual))
+
+ case th @ This(qual) =>
+ printThis(th, printedName(qual))
+
+ case Select(qual: New, name) =>
+ print(qual)
+
+ case Select(qualifier, name) => {
+ val printParentheses = needsParentheses(qualifier)(insideAnnotated = false) || isIntLitWithDecodedOp(qualifier, name)
+ if (printParentheses) print("(", resolveSelect(qualifier), ").", printedName(name))
+ else print(resolveSelect(qualifier), ".", printedName(name))
+ }
+
+ case id @ Ident(name) =>
+ if (name.nonEmpty) {
+ if (name == nme.dollarScope) {
+ print(s"scala.xml.${nme.TopScope}")
+ } else {
+ val str = printedName(name)
+ val strIsBackquoted = str.startsWith("`") && str.endsWith("`")
+ print(if (id.isBackquoted && !strIsBackquoted) "`" + str + "`" else str)
+ }
+ } else {
+ print("")
+ }
+
+ case l @ Literal(x) =>
+ import Chars.LF
+ x match {
+ case Constant(v: String) if {
+ val strValue = x.stringValue
+ strValue.contains(LF) && strValue.contains("\"\"\"") && strValue.size > 1
+ } =>
+ val splitValue = x.stringValue.split(s"$LF").toList
+ val multilineStringValue = if (x.stringValue.endsWith(s"$LF")) splitValue :+ "" else splitValue
+ val trQuotes = "\"\"\""
+ print(trQuotes); printSeq(multilineStringValue) { print(_) } { print(LF) }; print(trQuotes)
+ case _ =>
+ // processing Float constants
+ val printValue = x.escapedStringValue + (if (x.value.isInstanceOf[Float]) "F" else "")
+ print(printValue)
+ }
+
+ case an @ Annotated(ap, tree) =>
+ val printParentheses = needsParentheses(tree)()
+ parenthesize(printParentheses) { print(tree) }; print(if (tree.isType) " " else ": ")
+ printAnnot(ap)
+
+ case SelectFromTypeTree(qualifier, selector) =>
+ print("(", qualifier, ")#", blankForOperatorName(selector), printedName(selector))
+
+ case AppliedTypeTree(tp, args) =>
+ // it's possible to have (=> String) => String type but Function1[=> String, String] is not correct
+ val containsByNameTypeParam = args exists treeInfo.isByNameParamType
+
+ if (containsByNameTypeParam) {
+ print("(")
+ printRow(args.init, "(", ", ", ")")
+ print(" => ", args.last, ")")
+ } else {
+ if (treeInfo.isRepeatedParamType(tree) && args.nonEmpty) {
+ print(args(0), "*")
+ } else if (treeInfo.isByNameParamType(tree)) {
+ print("=> ", if (args.isEmpty) "()" else args(0))
+ } else
+ super.printTree(tree)
+ }
+
+ case ExistentialTypeTree(tpt, whereClauses) =>
+ print("(", tpt);
+ printColumn(whereClauses, " forSome { ", ";", "})")
+
+ case EmptyTree =>
+
+ case tree => super.printTree(tree)
+ }
+ parentsStack.pop()
+ }
+ }
/** Hook for extensions */
def xprintTree(treePrinter: TreePrinter, tree: Tree) =
treePrinter.print(tree.productPrefix+tree.productIterator.mkString("(", ", ", ")"))
+ def newCodePrinter(writer: PrintWriter): TreePrinter = new ParsedTreePrinter(writer)
def newTreePrinter(writer: PrintWriter): TreePrinter = new TreePrinter(writer)
def newTreePrinter(stream: OutputStream): TreePrinter = newTreePrinter(new PrintWriter(stream))
def newTreePrinter(): TreePrinter = newTreePrinter(new PrintWriter(ConsoleWriter))
diff --git a/src/reflect/scala/reflect/internal/Scopes.scala b/src/reflect/scala/reflect/internal/Scopes.scala
index b7a1681838..cf3f356daa 100644
--- a/src/reflect/scala/reflect/internal/Scopes.scala
+++ b/src/reflect/scala/reflect/internal/Scopes.scala
@@ -387,7 +387,7 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
if (toList forall p) this
else newScopeWith(toList filter p: _*)
)
- @deprecated("Use `toList.reverse` instead", "2.10.0")
+ @deprecated("Use `toList.reverse` instead", "2.10.0") // Used in SBT 0.12.4
def reverse: List[Symbol] = toList.reverse
override def mkString(start: String, sep: String, end: String) =
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index ea6afa7349..ed3e7dbc4c 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -686,6 +686,7 @@ trait StdNames {
val inlinedEquals: NameType = "inlinedEquals"
val isArray: NameType = "isArray"
val isDefinedAt: NameType = "isDefinedAt"
+ val isEmpty: NameType = "isEmpty"
val isInstanceOf_ : NameType = "isInstanceOf"
val isInstanceOf_Ob : NameType = "$isInstanceOf"
val java: NameType = "java"
@@ -762,8 +763,8 @@ trait StdNames {
val unapplySeq: NameType = "unapplySeq"
val unbox: NameType = "unbox"
val universe: NameType = "universe"
- val UnliftHelper1: NameType = "UnliftHelper1"
- val UnliftHelper2: NameType = "UnliftHelper2"
+ val UnliftListElementwise: NameType = "UnliftListElementwise"
+ val UnliftListOfListsElementwise: NameType = "UnliftListOfListsElementwise"
val update: NameType = "update"
val updateDynamic: NameType = "updateDynamic"
val value: NameType = "value"
diff --git a/src/reflect/scala/reflect/internal/SymbolTable.scala b/src/reflect/scala/reflect/internal/SymbolTable.scala
index c46a559d6d..571c4cfa5d 100644
--- a/src/reflect/scala/reflect/internal/SymbolTable.scala
+++ b/src/reflect/scala/reflect/internal/SymbolTable.scala
@@ -65,9 +65,6 @@ abstract class SymbolTable extends macros.Universe
def isPastTyper = false
protected def isDeveloper: Boolean = settings.debug
- @deprecated("Give us a reason", "2.10.0")
- def abort(): Nothing = abort("unknown error")
-
@deprecated("Use devWarning if this is really a warning; otherwise use log", "2.11.0")
def debugwarn(msg: => String): Unit = devWarning(msg)
@@ -356,16 +353,18 @@ abstract class SymbolTable extends macros.Universe
// Weak references so the garbage collector will take care of
// letting us know when a cache is really out of commission.
- private val caches = WeakHashSet[Clearable]()
+ import java.lang.ref.WeakReference
+ private var caches = List[WeakReference[Clearable]]()
def recordCache[T <: Clearable](cache: T): T = {
- caches += cache
+ caches ::= new WeakReference(cache)
cache
}
def clearAll() = {
debuglog("Clearing " + caches.size + " caches.")
- caches foreach (_.clear)
+ caches foreach (ref => Option(ref.get).foreach(_.clear))
+ caches = caches.filterNot(_.get == null)
}
def newWeakMap[K, V]() = recordCache(mutable.WeakHashMap[K, V]())
@@ -376,9 +375,9 @@ abstract class SymbolTable extends macros.Universe
val NoCached: T = null.asInstanceOf[T]
var cached: T = NoCached
var cachedRunId = NoRunId
- caches += new Clearable {
+ recordCache(new Clearable {
def clear(): Unit = cached = NoCached
- }
+ })
() => {
if (currentRunId != cachedRunId || cached == NoCached) {
cached = f
@@ -403,10 +402,9 @@ abstract class SymbolTable extends macros.Universe
*/
def isCompilerUniverse = false
- @deprecated("Use enteringPhase", "2.10.0")
+ @deprecated("Use enteringPhase", "2.10.0") // Used in SBT 0.12.4
@inline final def atPhase[T](ph: Phase)(op: => T): T = enteringPhase(ph)(op)
- @deprecated("Use enteringPhaseNotLaterThan", "2.10.0")
- @inline final def atPhaseNotLaterThan[T](target: Phase)(op: => T): T = enteringPhaseNotLaterThan(target)(op)
+
/**
* Adds the `sm` String interpolator to a [[scala.StringContext]].
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index e15b33e5d7..f49ddaf6ca 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -2419,7 +2419,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
else if (isTrait) ("trait", "trait", "TRT")
else if (isClass) ("class", "class", "CLS")
else if (isType) ("type", "type", "TPE")
- else if (isClassConstructor && isPrimaryConstructor) ("primary constructor", "constructor", "PCTOR")
+ else if (isClassConstructor && (owner.hasCompleteInfo && isPrimaryConstructor)) ("primary constructor", "constructor", "PCTOR")
else if (isClassConstructor) ("constructor", "constructor", "CTOR")
else if (isSourceMethod) ("method", "method", "METH")
else if (isTerm) ("value", "value", "VAL")
@@ -2519,6 +2519,10 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
if (settings.debug.value) parentsString(tp.parents)
else briefParentsString(tp.parents)
)
+ def isStructuralThisType = (
+ // prevents disasters like SI-8158
+ owner.isInitialized && owner.isStructuralRefinement && tp == owner.tpe
+ )
if (isType) typeParamsString(tp) + (
if (isClass) " extends " + parents
else if (isAliasType) " = " + tp.resultType
@@ -2529,10 +2533,11 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
)
else if (isModule) "" // avoid "object X of type X.type"
else tp match {
- case PolyType(tparams, res) => typeParamsString(tp) + infoString(res)
- case NullaryMethodType(res) => infoString(res)
- case MethodType(params, res) => valueParamsString(tp) + infoString(res)
- case _ => ": " + tp
+ case PolyType(tparams, res) => typeParamsString(tp) + infoString(res)
+ case NullaryMethodType(res) => infoString(res)
+ case MethodType(params, res) => valueParamsString(tp) + infoString(res)
+ case _ if isStructuralThisType => ": " + owner.name
+ case _ => ": " + tp
}
}
diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala
index f6d21ec9bd..b16cbd8325 100644
--- a/src/reflect/scala/reflect/internal/TreeGen.scala
+++ b/src/reflect/scala/reflect/internal/TreeGen.scala
@@ -95,7 +95,7 @@ abstract class TreeGen extends macros.TreeBuilder {
case ConstantType(value) =>
Literal(value) setType tpe
- case AnnotatedType(_, atp, _) =>
+ case AnnotatedType(_, atp) =>
mkAttributedQualifier(atp)
case RefinedType(parents, _) =>
@@ -191,11 +191,7 @@ abstract class TreeGen extends macros.TreeBuilder {
)
val pkgQualifier =
if (needsPackageQualifier) {
- // 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.
- val packageObject = if (sym.owner.isModuleClass) sym.owner.sourceModule else qual.tpe member nme.PACKAGE
+ val packageObject = rootMirror.getPackageObjectWithMember(qual.tpe, sym)
Select(qual, nme.PACKAGE) setSymbol packageObject setType singleType(qual.tpe, packageObject)
}
else qual
diff --git a/src/reflect/scala/reflect/internal/TreeInfo.scala b/src/reflect/scala/reflect/internal/TreeInfo.scala
index 8fdf4dc27a..497a7c91b1 100644
--- a/src/reflect/scala/reflect/internal/TreeInfo.scala
+++ b/src/reflect/scala/reflect/internal/TreeInfo.scala
@@ -612,8 +612,8 @@ abstract class TreeInfo {
def effectivePatternArity(args: List[Tree]): Int = flattenedPatternArgs(args).length
def flattenedPatternArgs(args: List[Tree]): List[Tree] = args map unbind match {
- case Apply(fun, xs) :: Nil if isTupleSymbol(fun.symbol) => xs
- case xs => xs
+ case build.SyntacticTuple(xs) :: Nil => xs
+ case xs => xs
}
// used in the symbols for labeldefs and valdefs emitted by the pattern matcher
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index 45daa2ae04..9ddaea4c62 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -8,7 +8,6 @@ package reflect
package internal
import scala.collection.{ mutable, immutable, generic }
-import generic.Clearable
import scala.ref.WeakReference
import mutable.ListBuffer
import Flags._
@@ -44,7 +43,7 @@ import TypeConstants._
// parent1 with ... with parentn { defs }
case ExistentialType(tparams, result) =>
// result forSome { tparams }
- case AnnotatedType(annots, tp, selfsym) =>
+ case AnnotatedType(annots, tp) =>
// tp @annots
// the following are non-value types; you cannot write them down in Scala source.
@@ -895,7 +894,7 @@ trait Types
if (sym == btssym) return mid
else if (sym isLess btssym) hi = mid - 1
else if (btssym isLess sym) lo = mid + 1
- else abort()
+ else abort("sym is neither `sym == btssym`, `sym isLess btssym` nor `btssym isLess sym`")
}
-1
}
@@ -1191,13 +1190,6 @@ trait Types
def setAnnotations(annots: List[AnnotationInfo]): Type = annotatedType(annots, this)
def withAnnotations(annots: List[AnnotationInfo]): Type = annotatedType(annots, this)
- /** Set the self symbol of an annotated type, or do nothing
- * otherwise. */
- def withSelfsym(sym: Symbol) = this
-
- /** The selfsym of an annotated type, or NoSymbol of anything else */
- def selfsym: Symbol = NoSymbol
-
/** The kind of this type; used for debugging */
def kind: String = "unknown type of class "+getClass()
}
@@ -1457,7 +1449,7 @@ trait Types
override def safeToString = scalaNotation(_.toString)
- /** Bounds notation used in Scala sytanx.
+ /** Bounds notation used in Scala syntax.
* For example +This <: scala.collection.generic.Sorted[K,This].
*/
private[internal] def scalaNotation(typeString: Type => String): String = {
@@ -1999,7 +1991,9 @@ trait Types
if (sym.typeParams.size != args.size)
devWarning(s"$this.transform($tp), but tparams.isEmpty and args=$args")
- asSeenFromOwner(tp).instantiateTypeParams(sym.typeParams, args)
+ val GenPolyType(tparams, result) = asSeenFromOwner(tp)
+ assert((tparams eq Nil) || tparams == sym.typeParams, (tparams, sym.typeParams))
+ result.instantiateTypeParams(sym.typeParams, args)
}
// note: does not go through typeRef. There's no need to because
@@ -2309,7 +2303,14 @@ trait Types
}
thisInfo.decls
}
- protected[Types] def baseTypeSeqImpl: BaseTypeSeq = sym.info.baseTypeSeq map transform
+ protected[Types] def baseTypeSeqImpl: BaseTypeSeq =
+ if (sym.info.baseTypeSeq exists (_.typeSymbolDirect.isAbstractType))
+ // SI-8046 base type sequence might have more elements in a subclass, we can't map it element wise.
+ transform(sym.info).baseTypeSeq
+ else
+ // Optimization: no abstract types, we can compute the BTS of this TypeRef as an element-wise map
+ // of the BTS of the referenced symbol.
+ sym.info.baseTypeSeq map transform
override def baseTypeSeq: BaseTypeSeq = {
val cache = baseTypeSeqCache
@@ -3239,13 +3240,9 @@ trait Types
*
* @param annotations the list of annotations on the type
* @param underlying the type without the annotation
- * @param selfsym a "self" symbol with type `underlying`;
- * only available if -Yself-in-annots is turned on. Can be `NoSymbol`
- * if it is not used.
*/
case class AnnotatedType(override val annotations: List[AnnotationInfo],
- override val underlying: Type,
- override val selfsym: Symbol)
+ override val underlying: Type)
extends RewrappingTypeProxy with AnnotatedTypeApi {
assert(!annotations.isEmpty, "" + underlying)
@@ -3278,9 +3275,6 @@ trait Types
*/
override def withoutAnnotations = underlying.withoutAnnotations
- /** Set the self symbol */
- override def withSelfsym(sym: Symbol) = copy(selfsym = sym)
-
/** Drop the annotations on the bounds, unless the low and high
* bounds are exactly tp.
*/
@@ -3295,7 +3289,7 @@ trait Types
formals, actuals), info.args, info.assocs).setPos(info.pos))
val underlying1 = underlying.instantiateTypeParams(formals, actuals)
if ((annotations1 eq annotations) && (underlying1 eq underlying)) this
- else AnnotatedType(annotations1, underlying1, selfsym)
+ else AnnotatedType(annotations1, underlying1)
}
/** Return the base type sequence of tp, dropping the annotations, unless the base type sequence of tp
@@ -3314,9 +3308,9 @@ trait Types
/** Creator for AnnotatedTypes. It returns the underlying type if annotations.isEmpty
* rather than walking into the assertion.
*/
- def annotatedType(annots: List[AnnotationInfo], underlying: Type, selfsym: Symbol = NoSymbol): Type =
+ def annotatedType(annots: List[AnnotationInfo], underlying: Type): Type =
if (annots.isEmpty) underlying
- else AnnotatedType(annots, underlying, selfsym)
+ else AnnotatedType(annots, underlying)
object AnnotatedType extends AnnotatedTypeExtractor
@@ -3569,7 +3563,7 @@ trait Types
case RefinedType(parents, decls) => RefinedType(parents map (appliedType(_, args)), decls) // @PP: Can this be right?
case TypeBounds(lo, hi) => TypeBounds(appliedType(lo, args), appliedType(hi, args)) // @PP: Can this be right?
case tv@TypeVar(_, _) => tv.applyArgs(args)
- case AnnotatedType(annots, underlying, self) => AnnotatedType(annots, appliedType(underlying, args), self)
+ case AnnotatedType(annots, underlying) => AnnotatedType(annots, appliedType(underlying, args))
case ErrorType | WildcardType => tycon
case _ => abort(debugString(tycon))
}
@@ -3605,7 +3599,7 @@ trait Types
}
def genPolyType(params: List[Symbol], tpe: Type): Type = GenPolyType(params, tpe)
- @deprecated("use genPolyType(...) instead", "2.10.0")
+ @deprecated("use genPolyType(...) instead", "2.10.0") // Used in reflection API
def polyType(params: List[Symbol], tpe: Type): Type = GenPolyType(params, tpe)
/** A creator for anonymous type functions, where the symbol for the type function still needs to be created.
@@ -3664,7 +3658,11 @@ trait Types
if (Statistics.canEnable) Statistics.incCounter(rawTypeCount)
if (uniqueRunId != currentRunId) {
uniques = util.WeakHashSet[Type](initialUniquesCapacity)
- perRunCaches.recordCache(uniques)
+ // JZ: We used to register this as a perRunCache so it would be cleared eagerly at
+ // the end of the compilation run. But, that facility didn't actually clear this map (SI-8129)!
+ // When i fixed that bug, run/tpeCache-tyconCache.scala started failing. Why was that?
+ // I've removed the registration for now. I don't think its particularly harmful anymore
+ // as a) this is now a weak set, and b) it is discarded completely before the next run.
uniqueRunId = currentRunId
}
(uniques findEntryOrUpdate tp).asInstanceOf[T]
@@ -3674,7 +3672,7 @@ trait Types
class TypeUnwrapper(poly: Boolean, existential: Boolean, annotated: Boolean, nullary: Boolean) extends (Type => Type) {
def apply(tp: Type): Type = tp match {
- case AnnotatedType(_, underlying, _) if annotated => apply(underlying)
+ case AnnotatedType(_, underlying) if annotated => apply(underlying)
case ExistentialType(_, underlying) if existential => apply(underlying)
case PolyType(_, underlying) if poly => apply(underlying)
case NullaryMethodType(underlying) if nullary => apply(underlying)
@@ -3717,7 +3715,7 @@ trait Types
def transparentShallowTransform(container: Symbol, tp: Type)(f: Type => Type): Type = {
def loop(tp: Type): Type = tp match {
- case tp @ AnnotatedType(_, underlying, _) => tp.copy(underlying = loop(underlying))
+ case tp @ AnnotatedType(_, underlying) => tp.copy(underlying = loop(underlying))
case tp @ ExistentialType(_, underlying) => tp.copy(underlying = loop(underlying))
case tp @ PolyType(_, resultType) => tp.copy(resultType = loop(resultType))
case tp @ NullaryMethodType(resultType) => tp.copy(resultType = loop(resultType))
@@ -4078,7 +4076,7 @@ trait Types
private def isValueElseNonValue(tp: Type): Boolean = tp match {
case tp if isAlwaysValueType(tp) => true
case tp if isAlwaysNonValueType(tp) => false
- case AnnotatedType(_, underlying, _) => isValueElseNonValue(underlying)
+ case AnnotatedType(_, underlying) => isValueElseNonValue(underlying)
case SingleType(_, sym) => sym.isValue // excludes packages and statics
case TypeRef(_, _, _) if tp.isHigherKinded => false // excludes type constructors
case ThisType(sym) => !sym.isPackageClass // excludes packages
diff --git a/src/reflect/scala/reflect/internal/Variances.scala b/src/reflect/scala/reflect/internal/Variances.scala
index cd09e83cd3..a7cac5254c 100644
--- a/src/reflect/scala/reflect/internal/Variances.scala
+++ b/src/reflect/scala/reflect/internal/Variances.scala
@@ -84,7 +84,7 @@ trait Variances {
loop(base, Covariant)
}
def isUncheckedVariance(tp: Type) = tp match {
- case AnnotatedType(annots, _, _) => annots exists (_ matches definitions.uncheckedVarianceClass)
+ case AnnotatedType(annots, _) => annots exists (_ matches definitions.uncheckedVarianceClass)
case _ => false
}
@@ -202,7 +202,7 @@ trait Variances {
case MethodType(params, restpe) => inSyms(params).flip & inType(restpe)
case PolyType(tparams, restpe) => inSyms(tparams).flip & inType(restpe)
case ExistentialType(tparams, restpe) => inSyms(tparams) & inType(restpe)
- case AnnotatedType(annots, tp, _) => inTypes(annots map (_.atp)) & inType(tp)
+ case AnnotatedType(annots, tp) => inTypes(annots map (_.atp)) & inType(tp)
}
inType(tp)
diff --git a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
index 3d222fce10..2a19441476 100644
--- a/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
+++ b/src/reflect/scala/reflect/internal/pickling/UnPickler.scala
@@ -362,7 +362,7 @@ abstract class UnPickler {
case METHODtpe => MethodTypeRef(readTypeRef(), readSymbols())
case POLYtpe => PolyOrNullaryType(readTypeRef(), readSymbols())
case EXISTENTIALtpe => ExistentialType(underlying = readTypeRef(), quantified = readSymbols())
- case ANNOTATEDtpe => AnnotatedType(underlying = readTypeRef(), annotations = readAnnots(), selfsym = NoSymbol)
+ case ANNOTATEDtpe => AnnotatedType(underlying = readTypeRef(), annotations = readAnnots())
}
}
diff --git a/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala b/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala
index 6b33aca025..1c4d05ae32 100644
--- a/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala
+++ b/src/reflect/scala/reflect/internal/tpe/GlbLubs.scala
@@ -316,7 +316,7 @@ private[internal] trait GlbLubs {
NullaryMethodType(lub0(matchingRestypes(ts, Nil)))
case ts @ TypeBounds(_, _) :: rest =>
TypeBounds(glb(ts map (_.bounds.lo), depth), lub(ts map (_.bounds.hi), depth))
- case ts @ AnnotatedType(annots, tpe, _) :: rest =>
+ case ts @ AnnotatedType(annots, tpe) :: rest =>
annotationsLub(lub0(ts map (_.withoutAnnotations)), ts)
case ts =>
lubResults get ((depth, ts)) match {
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
index b60fecd66e..3c4e93f11d 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeComparers.scala
@@ -17,20 +17,15 @@ trait TypeComparers {
private val _pendingSubTypes = new mutable.HashSet[SubTypePair]
def pendingSubTypes = _pendingSubTypes
- class SubTypePair(val tp1: Type, val tp2: Type) {
- override def hashCode = tp1.hashCode * 41 + tp2.hashCode
- override def equals(other: Any) = (this eq other.asInstanceOf[AnyRef]) || (other match {
- // suspend TypeVars in types compared by =:=,
- // since we don't want to mutate them simply to check whether a subtype test is pending
- // in addition to making subtyping "more correct" for type vars,
- // it should avoid the stackoverflow that's been plaguing us (https://groups.google.com/d/topic/scala-internals/2gHzNjtB4xA/discussion)
- // this method is only called when subtyping hits a recursion threshold (subsametypeRecursions >= LogPendingSubTypesThreshold)
- case stp: SubTypePair =>
- val tvars = List(tp1, stp.tp1, tp2, stp.tp2) flatMap (t => if (t.isGround) Nil else typeVarsInType(t))
- suspendingTypeVars(tvars)(tp1 =:= stp.tp1 && tp2 =:= stp.tp2)
- case _ =>
- false
- })
+ final case class SubTypePair(tp1: Type, tp2: Type) {
+ // SI-8146 we used to implement equality here in terms of pairwise =:=.
+ // But, this was inconsistent with hashCode, which was based on the
+ // Type#hashCode, based on the structure of types, not the meaning.
+ // Now, we use `Type#{equals,hashCode}` as the (consistent) basis for
+ // detecting cycles (aka keeping subtyping decidable.)
+ //
+ // I added a tests to show that we detect the cycle: neg/t8146-no-finitary*
+
override def toString = tp1+" <:<? "+tp2
}
@@ -170,11 +165,20 @@ trait TypeComparers {
// corresponds does not check length of two sequences before checking the predicate,
// but SubstMap assumes it has been checked (SI-2956)
( sameLength(tparams1, tparams2)
- && (tparams1 corresponds tparams2)((p1, p2) => p1.info =:= subst(p2.info))
+ && (tparams1 corresponds tparams2)((p1, p2) => methodHigherOrderTypeParamsSameVariance(p1, p2) && p1.info =:= subst(p2.info))
&& (res1 =:= subst(res2))
)
}
+ // SI-2066 This prevents overrides with incompatible variance in higher order type parameters.
+ private def methodHigherOrderTypeParamsSameVariance(sym1: Symbol, sym2: Symbol) = {
+ def ignoreVariance(sym: Symbol) = !(sym.isHigherOrderTypeParameter && sym.logicallyEnclosingMember.isMethod)
+ ignoreVariance(sym1) || ignoreVariance(sym2) || sym1.variance == sym2.variance
+ }
+
+ private def methodHigherOrderTypeParamsSubVariance(low: Symbol, high: Symbol) =
+ methodHigherOrderTypeParamsSameVariance(low, high) || low.variance.isInvariant
+
def isSameType2(tp1: Type, tp2: Type): Boolean = {
def retry(lhs: Type, rhs: Type) = ((lhs ne tp1) || (rhs ne tp2)) && isSameType(lhs, rhs)
@@ -262,7 +266,7 @@ trait TypeComparers {
if (subsametypeRecursions >= LogPendingSubTypesThreshold) {
val p = new SubTypePair(tp1, tp2)
if (pendingSubTypes(p))
- false
+ false // see neg/t8146-no-finitary*
else
try {
pendingSubTypes += p
@@ -327,7 +331,10 @@ trait TypeComparers {
val substitutes = if (isMethod) tparams1 else cloneSymbols(tparams1)
def sub1(tp: Type) = if (isMethod) tp else tp.substSym(tparams1, substitutes)
def sub2(tp: Type) = tp.substSym(tparams2, substitutes)
- def cmp(p1: Symbol, p2: Symbol) = sub2(p2.info) <:< sub1(p1.info)
+ def cmp(p1: Symbol, p2: Symbol) = (
+ methodHigherOrderTypeParamsSubVariance(p2, p1)
+ && sub2(p2.info) <:< sub1(p1.info)
+ )
(tparams1 corresponds tparams2)(cmp) && (sub1(res1) <:< sub2(res2))
}
@@ -403,14 +410,14 @@ trait TypeComparers {
case _ =>
secondTry
}
- case AnnotatedType(_, _, _) =>
+ case AnnotatedType(_, _) =>
isSubType(tp1.withoutAnnotations, tp2.withoutAnnotations, depth) &&
annotationsConform(tp1, tp2)
case BoundedWildcardType(bounds) =>
isSubType(tp1, bounds.hi, depth)
case tv2 @ TypeVar(_, constr2) =>
tp1 match {
- case AnnotatedType(_, _, _) | BoundedWildcardType(_) =>
+ case AnnotatedType(_, _) | BoundedWildcardType(_) =>
secondTry
case _ =>
tv2.registerBound(tp1, isLowerBound = true)
@@ -425,7 +432,7 @@ trait TypeComparers {
* - handle existential types by skolemization.
*/
def secondTry = tp1 match {
- case AnnotatedType(_, _, _) =>
+ case AnnotatedType(_, _) =>
isSubType(tp1.withoutAnnotations, tp2.withoutAnnotations, depth) &&
annotationsConform(tp1, tp2)
case BoundedWildcardType(bounds) =>
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
index f5aa048e6a..09f4389b82 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeMaps.scala
@@ -48,7 +48,7 @@ private[internal] trait TypeMaps {
case TypeRef(_, sym, _) if sym.isAliasType => apply(tp.dealias)
case TypeRef(_, sym, _) if sym.isAbstractType => apply(tp.bounds.hi)
case rtp @ RefinedType(parents, decls) => copyRefinedType(rtp, parents mapConserve this, decls)
- case AnnotatedType(_, _, _) => mapOver(tp)
+ case AnnotatedType(_, _) => mapOver(tp)
case _ => tp // no recursion - top level only
}
}
@@ -174,12 +174,12 @@ private[internal] trait TypeMaps {
case tv@TypeVar(_, constr) =>
if (constr.instValid) this(constr.inst)
else tv.applyArgs(mapOverArgs(tv.typeArgs, tv.params)) //@M !args.isEmpty implies !typeParams.isEmpty
- case AnnotatedType(annots, atp, selfsym) =>
+ case AnnotatedType(annots, atp) =>
val annots1 = mapOverAnnotations(annots)
val atp1 = this(atp)
if ((annots1 eq annots) && (atp1 eq atp)) tp
else if (annots1.isEmpty) atp1
- else AnnotatedType(annots1, atp1, selfsym)
+ else AnnotatedType(annots1, atp1)
/*
case ErrorType => tp
case WildcardType => tp
@@ -1142,7 +1142,7 @@ private[internal] trait TypeMaps {
case SuperType(_, _) => mapOver(tp)
case TypeBounds(_, _) => mapOver(tp)
case TypeVar(_, _) => mapOver(tp)
- case AnnotatedType(_,_,_) => mapOver(tp)
+ case AnnotatedType(_, _) => mapOver(tp)
case ExistentialType(_, _) => mapOver(tp)
case _ => tp
}
diff --git a/src/reflect/scala/reflect/internal/tpe/TypeToStrings.scala b/src/reflect/scala/reflect/internal/tpe/TypeToStrings.scala
index ebc4394d25..a062fc8209 100644
--- a/src/reflect/scala/reflect/internal/tpe/TypeToStrings.scala
+++ b/src/reflect/scala/reflect/internal/tpe/TypeToStrings.scala
@@ -3,19 +3,29 @@ package reflect
package internal
package tpe
+import scala.collection.mutable.HashSet
+
private[internal] trait TypeToStrings {
self: SymbolTable =>
/** The maximum number of recursions allowed in toString
*/
- final val maxTostringRecursions = 50
+ final val maxToStringRecursions = 50
+
+ private var _toStringRecursions = 0
+ def toStringRecursions = _toStringRecursions
+ def toStringRecursions_=(value: Int) = _toStringRecursions = value
- private var _tostringRecursions = 0
- def tostringRecursions = _tostringRecursions
- def tostringRecursions_=(value: Int) = _tostringRecursions = value
+ private var _toStringSubjects = HashSet[Type]()
+ def toStringSubjects = _toStringSubjects
protected def typeToString(tpe: Type): String =
- if (tostringRecursions >= maxTostringRecursions) {
+ // if (toStringSubjects contains tpe) {
+ // // handles self-referential anonymous classes and who knows what else
+ // "..."
+ // }
+ // else
+ if (toStringRecursions >= maxToStringRecursions) {
devWarning("Exceeded recursion depth attempting to print " + util.shortClassOfInstance(tpe))
if (settings.debug)
(new Throwable).printStackTrace
@@ -24,9 +34,15 @@ private[internal] trait TypeToStrings {
}
else
try {
- tostringRecursions += 1
+ toStringRecursions += 1
+ // TODO: study performance impact of this cache
+ // to quote Jason:
+ // I'm a little uneasy with the performance impact of the fail-safe. We end up calling Type#toString
+ // when we generate error messages, including, importantly, errors issued during silent mode that are never issued.
+ // toStringSubjects += tpe
tpe.safeToString
} finally {
- tostringRecursions -= 1
+ // toStringSubjects -= tpe
+ toStringRecursions -= 1
}
}
diff --git a/src/reflect/scala/reflect/internal/transform/Erasure.scala b/src/reflect/scala/reflect/internal/transform/Erasure.scala
index addc7eb389..786ff2210c 100644
--- a/src/reflect/scala/reflect/internal/transform/Erasure.scala
+++ b/src/reflect/scala/reflect/internal/transform/Erasure.scala
@@ -144,7 +144,7 @@ trait Erasure {
else apply(mt.resultType(mt.paramTypes)))
case RefinedType(parents, decls) =>
apply(mergeParents(parents))
- case AnnotatedType(_, atp, _) =>
+ case AnnotatedType(_, atp) =>
apply(atp)
case ClassInfoType(parents, decls, clazz) =>
ClassInfoType(
diff --git a/src/reflect/scala/reflect/internal/util/Position.scala b/src/reflect/scala/reflect/internal/util/Position.scala
index 15cfda26b5..f3eedb88e7 100644
--- a/src/reflect/scala/reflect/internal/util/Position.scala
+++ b/src/reflect/scala/reflect/internal/util/Position.scala
@@ -202,12 +202,31 @@ private[util] trait InternalPositionImpl {
def line: Int = if (hasSource) source.offsetToLine(point) + 1 else 0
def column: Int = if (hasSource) calculateColumn() else 0
def lineContent: String = if (hasSource) source.lineToString(line - 1) else ""
- def lineCarat: String = if (hasSource) " " * (column - 1) + "^" else ""
-
- def showError(msg: String): String = finalPosition match {
- case FakePos(fmsg) => s"$fmsg $msg"
- case NoPosition => msg
- case pos => s"${pos.line}: $msg\n${pos.lineContent}\n${pos.lineCarat}"
+ def lineCaret: String = if (hasSource) " " * (column - 1) + "^" else ""
+ @deprecated("use `lineCaret`", since="2.11.0")
+ def lineCarat: String = lineCaret
+
+ def showError(msg: String): String = {
+ def escaped(s: String) = {
+ def u(c: Int) = f"\\u$c%04x"
+ def uable(c: Int) = (c < 0x20 && c != '\t') || c == 0x7F
+ if (s exists (c => uable(c))) {
+ val sb = new StringBuilder
+ s foreach (c => sb append (if (uable(c)) u(c) else c))
+ sb.toString
+ } else s
+ }
+ def errorAt(p: Pos) = {
+ def where = p.line
+ def content = escaped(p.lineContent)
+ def indicator = p.lineCaret
+ f"$where: $msg%n$content%n$indicator"
+ }
+ finalPosition match {
+ case FakePos(fmsg) => s"$fmsg $msg"
+ case NoPosition => msg
+ case pos => errorAt(pos)
+ }
}
def showDebug: String = toString
def show = (
@@ -239,8 +258,8 @@ private[util] trait InternalPositionImpl {
private[util] trait DeprecatedPosition {
self: Position =>
- @deprecated("use `point`", "2.9.0")
- def offset: Option[Int] = if (isDefined) Some(point) else None // used by sbt
+ @deprecated("use `point`", "2.9.0") // Used in SBT 0.12.4
+ def offset: Option[Int] = if (isDefined) Some(point) else None
@deprecated("use `focus`", "2.11.0")
def toSingleLine: Position = this
@@ -254,7 +273,7 @@ private[util] trait DeprecatedPosition {
@deprecated("use `finalPosition`", "2.11.0")
def inUltimateSource(source: SourceFile): Position = source positionInUltimateSource this
- @deprecated("use `lineCarat`", "2.11.0")
+ @deprecated("use `lineCaret`", since="2.11.0")
def lineWithCarat(maxWidth: Int): (String, String) = ("", "")
@deprecated("Use `withSource(source)` and `withShift`", "2.11.0")
diff --git a/src/reflect/scala/reflect/internal/util/SourceFile.scala b/src/reflect/scala/reflect/internal/util/SourceFile.scala
index 3b6c57e955..9866b043bb 100644
--- a/src/reflect/scala/reflect/internal/util/SourceFile.scala
+++ b/src/reflect/scala/reflect/internal/util/SourceFile.scala
@@ -16,12 +16,13 @@ import scala.reflect.internal.Chars._
/** abstract base class of a source file used in the compiler */
abstract class SourceFile {
- def content : Array[Char] // normalized, must end in SU
- def file : AbstractFile
- def isLineBreak(idx : Int) : Boolean
+ def content: Array[Char] // normalized, must end in SU
+ def file : AbstractFile
+ def isLineBreak(idx: Int): Boolean
+ def isEndOfLine(idx: Int): Boolean
def isSelfContained: Boolean
def length : Int
- def position(offset: Int) : Position = {
+ def position(offset: Int): Position = {
assert(offset < length, file + ": " + offset + " >= " + length)
Position.offset(this, offset)
}
@@ -36,8 +37,12 @@ abstract class SourceFile {
override def toString() = file.name
def path = file.path
- def lineToString(index: Int): String =
- content drop lineToOffset(index) takeWhile (c => !isLineBreakChar(c.toChar)) mkString ""
+ def lineToString(index: Int): String = {
+ val start = lineToOffset(index)
+ var end = start
+ while (!isEndOfLine(end)) end += 1
+ content.slice(start, end) mkString ""
+ }
@tailrec
final def skipWhitespace(offset: Int): Int =
@@ -52,6 +57,7 @@ object NoSourceFile extends SourceFile {
def content = Array()
def file = NoFile
def isLineBreak(idx: Int) = false
+ def isEndOfLine(idx: Int) = false
def isSelfContained = true
def length = -1
def offsetToLine(offset: Int) = -1
@@ -128,18 +134,24 @@ class BatchSourceFile(val file : AbstractFile, val content0: Array[Char]) extend
super.identifier(pos)
}
- def isLineBreak(idx: Int) =
- if (idx >= length) false else {
- val ch = content(idx)
- // don't identify the CR in CR LF as a line break, since LF will do.
- if (ch == CR) (idx + 1 == length) || (content(idx + 1) != LF)
- else isLineBreakChar(ch)
- }
+ private def charAtIsEOL(idx: Int)(p: Char => Boolean) = {
+ // don't identify the CR in CR LF as a line break, since LF will do.
+ def notCRLF0 = content(idx) != CR || idx + 1 >= length || content(idx + 1) != LF
+
+ idx < length && notCRLF0 && p(content(idx))
+ }
+
+ def isLineBreak(idx: Int) = charAtIsEOL(idx)(isLineBreakChar)
+
+ def isEndOfLine(idx: Int) = charAtIsEOL(idx) {
+ case CR | LF => true
+ case _ => false
+ }
def calculateLineIndices(cs: Array[Char]) = {
val buf = new ArrayBuffer[Int]
buf += 0
- for (i <- 0 until cs.length) if (isLineBreak(i)) buf += i + 1
+ for (i <- 0 until cs.length) if (isEndOfLine(i)) buf += i + 1
buf += cs.length // sentinel, so that findLine below works smoother
buf.toArray
}
@@ -149,8 +161,8 @@ class BatchSourceFile(val file : AbstractFile, val content0: Array[Char]) extend
private var lastLine = 0
- /** Convert offset to line in this source file
- * Lines are numbered from 0
+ /** Convert offset to line in this source file.
+ * Lines are numbered from 0.
*/
def offsetToLine(offset: Int): Int = {
val lines = lineIndices
diff --git a/src/reflect/scala/reflect/macros/Aliases.scala b/src/reflect/scala/reflect/macros/Aliases.scala
index ca599dbd49..d2b878d081 100644
--- a/src/reflect/scala/reflect/macros/Aliases.scala
+++ b/src/reflect/scala/reflect/macros/Aliases.scala
@@ -5,11 +5,11 @@ package macros
/**
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
*
- * A slice of [[scala.reflect.macros.BlackboxContext the Scala macros context]] that defines shorthands for the
+ * A slice of [[scala.reflect.macros.blackbox.Context the Scala macros context]] that defines shorthands for the
* most frequently used types and functions of the underlying compiler universe.
*/
trait Aliases {
- self: BlackboxContext =>
+ self: blackbox.Context =>
/** The type of symbols representing declarations. */
type Symbol = universe.Symbol
@@ -40,10 +40,16 @@ trait Aliases {
/** The type of tree modifiers. */
type Modifiers = universe.Modifiers
- /** The type of compilation runs. */
+ /** The type of compilation runs.
+ * @see [[scala.reflect.macros.Enclosures]]
+ */
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
type Run = universe.Run
- /** The type of compilation units. */
+ /** The type of compilation units.
+ * @see [[scala.reflect.macros.Enclosures]]
+ */
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
type CompilationUnit = universe.CompilationUnit
/** Expr wraps an abstract syntax tree and tags it with its type. */
diff --git a/src/reflect/scala/reflect/macros/BlackboxMacro.scala b/src/reflect/scala/reflect/macros/BlackboxMacro.scala
deleted file mode 100644
index df142e9238..0000000000
--- a/src/reflect/scala/reflect/macros/BlackboxMacro.scala
+++ /dev/null
@@ -1,36 +0,0 @@
-package scala.reflect
-package macros
-
-/**
- * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
- *
- * Traditionally macro implementations are defined as methods,
- * but this trait provides an alternative way of encoding macro impls as
- * bundles, traits which extend `scala.reflect.macros.BlackboxMacro` or`scala.reflect.macros.WhiteboxMacro` .
- *
- * Instead of:
- *
- * def impl[T: c.WeakTypeTag](c: BlackboxContext)(x: c.Expr[Int]) = ...
- *
- * One can write:
- *
- * trait Impl extends BlackboxMacro {
- * def apply[T: c.WeakTypeTag](x: c.Expr[Int]) = ...
- * }
- *
- * Without changing anything else at all.
- *
- * This language feature is useful in itself in cases when macro implementations
- * are complex and need to be modularized. State of the art technique of addressing this need is quite heavyweight:
- * http://docs.scala-lang.org/overviews/macros/overview.html#writing_bigger_macros.
- *
- * @see `scala.reflect.macros.WhiteboxMacro`
- */
-trait BlackboxMacro {
- /** The context to be used by the macro implementation.
- *
- * Vanilla macro implementations have to carry it in their signatures, however when a macro is a full-fledged module,
- * it can define the context next to the implementation, makes implementation signature more lightweight.
- */
- val c: BlackboxContext
-}
diff --git a/src/reflect/scala/reflect/macros/Enclosures.scala b/src/reflect/scala/reflect/macros/Enclosures.scala
index f3e934d12b..1ced2e54c6 100644
--- a/src/reflect/scala/reflect/macros/Enclosures.scala
+++ b/src/reflect/scala/reflect/macros/Enclosures.scala
@@ -7,13 +7,25 @@ import scala.language.existentials // SI-6541
/**
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
*
- * A slice of [[scala.reflect.macros.BlackboxContext the Scala macros context]] that exposes
- * enclosing trees (method, class, compilation unit and currently compiled application),
+ * A slice of [[scala.reflect.macros.blackbox.Context the Scala macros context]] that exposes
+ * enclosing trees (method, class, compilation unit and currently compiled macro application),
* the enclosing position of the macro expansion, as well as macros and implicits
* that are currently in-flight.
+ *
+ * Starting from Scala 2.11.0, the APIs to get the trees enclosing by the current macro application are deprecated,
+ * and the reasons for that are two-fold. Firstly, we would like to move towards the philosophy of locally-expanded macros,
+ * as it has proven to be important for understanding of code. Secondly, within the current architecture of scalac,
+ * we are unable to have c.enclosingTree-style APIs working robustly. Required changes to the typechecker would greatly
+ * exceed the effort that we would like to expend on this feature given the existence of more pressing concerns at the moment.
+ * 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
+ * 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.
*/
trait Enclosures {
- self: BlackboxContext =>
+ self: blackbox.Context =>
/** The tree that undergoes macro expansion.
* Can be useful to get an offset or a range position of the entire tree being processed.
@@ -30,7 +42,7 @@ trait Enclosures {
* Unlike `openMacros`, this is a val, which means that it gets initialized when the context is created
* and always stays the same regardless of whatever happens during macro expansion.
*/
- def enclosingMacros: List[BlackboxContext]
+ def enclosingMacros: List[blackbox.Context]
/** Tries to guess a position for the enclosing application.
* But that is simple, right? Just dereference `pos` of `macroApplication`? Not really.
@@ -40,46 +52,62 @@ trait Enclosures {
def enclosingPosition: Position
/** Tree that corresponds to the enclosing method, or EmptyTree if not applicable.
+ * @see [[scala.reflect.macros.Enclosures]]
*/
- @deprecated("Use enclosingDef instead, but be wary of changes in semantics", "2.10.1")
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
def enclosingMethod: Tree
/** Tree that corresponds to the enclosing class, or EmptyTree if not applicable.
+ * @see [[scala.reflect.macros.Enclosures]]
*/
- @deprecated("Use enclosingImpl instead, but be wary of changes in semantics", "2.10.1")
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
def enclosingClass: Tree
/** Tree that corresponds to the enclosing DefDef tree.
* Throws `EnclosureException` if there's no such enclosing tree.
+ * @see [[scala.reflect.macros.Enclosures]]
*/
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
def enclosingDef: universe.DefDef
/** Tree that corresponds to the enclosing Template tree.
* Throws `EnclosureException` if there's no such enclosing tree.
+ * @see [[scala.reflect.macros.Enclosures]]
*/
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
def enclosingTemplate: universe.Template
/** Tree that corresponds to the enclosing ImplDef tree (i.e. either ClassDef or ModuleDef).
* Throws `EnclosureException` if there's no such enclosing tree.
+ * @see [[scala.reflect.macros.Enclosures]]
*/
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
def enclosingImpl: universe.ImplDef
/** Tree that corresponds to the enclosing PackageDef tree.
* Throws `EnclosureException` if there's no such enclosing tree.
+ * @see [[scala.reflect.macros.Enclosures]]
*/
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
def enclosingPackage: universe.PackageDef
/** Compilation unit that contains this macro application.
+ * @see [[scala.reflect.macros.Enclosures]]
*/
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
def enclosingUnit: CompilationUnit
/** Compilation run that contains this macro application.
+ * @see [[scala.reflect.macros.Enclosures]]
*/
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
def enclosingRun: Run
/** Indicates than one of the enclosure methods failed to find a tree
* of required type among enclosing trees.
+ * @see [[scala.reflect.macros.Enclosures]]
*/
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
case class EnclosureException(expected: Class[_], enclosingTrees: List[Tree])
extends Exception(s"Couldn't find a tree of type $expected among enclosing trees $enclosingTrees")
}
diff --git a/src/reflect/scala/reflect/macros/Evals.scala b/src/reflect/scala/reflect/macros/Evals.scala
index eb37e83cad..222ae43d79 100644
--- a/src/reflect/scala/reflect/macros/Evals.scala
+++ b/src/reflect/scala/reflect/macros/Evals.scala
@@ -5,11 +5,11 @@ package macros
/**
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
*
- * A slice of [[scala.reflect.macros.BlackboxContext the Scala macros context]] that provides
+ * A slice of [[scala.reflect.macros.blackbox.Context the Scala macros context]] that provides
* a facility to evaluate trees.
*/
trait Evals {
- self: BlackboxContext =>
+ self: blackbox.Context =>
/** Takes a typed wrapper for a tree of type `T` and evaluates it to a value of type `T`.
*
@@ -21,12 +21,12 @@ trait Evals {
* mutates the tree in place, therefore the conventional approach is to `duplicate` the tree first.
*
* {{{
- * scala> def impl(c: BlackboxContext)(x: c.Expr[String]) = {
+ * scala> def impl(c: Context)(x: c.Expr[String]) = {
* | val x1 = c.Expr[String](c.resetAllAttrs(x.tree.duplicate))
* | println(s"compile-time value is: \${c.eval(x1)}")
* | x
* | }
- * impl: (c: BlackboxContext)(x: c.Expr[String])c.Expr[String]
+ * impl: (c: Context)(x: c.Expr[String])c.Expr[String]
*
* scala> def test(x: String) = macro impl
* test: (x: String)String
diff --git a/src/reflect/scala/reflect/macros/ExprUtils.scala b/src/reflect/scala/reflect/macros/ExprUtils.scala
index 58b61e446a..c438653c92 100644
--- a/src/reflect/scala/reflect/macros/ExprUtils.scala
+++ b/src/reflect/scala/reflect/macros/ExprUtils.scala
@@ -5,11 +5,11 @@ package macros
/**
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
*
- * A slice of [[scala.reflect.macros.BlackboxContext the Scala macros context]] that defines shorthands for the
+ * A slice of [[scala.reflect.macros.blackbox.Context the Scala macros context]] that defines shorthands for the
* most common `Expr`-creating functions.
*/
trait ExprUtils {
- self: BlackboxContext =>
+ self: blackbox.Context =>
/** Shorthand for `Literal(Constant(null))` in the underlying `universe`. */
@deprecated("Use quasiquotes instead", "2.11.0")
diff --git a/src/reflect/scala/reflect/macros/FrontEnds.scala b/src/reflect/scala/reflect/macros/FrontEnds.scala
index 3a910d89ad..a770f325b2 100644
--- a/src/reflect/scala/reflect/macros/FrontEnds.scala
+++ b/src/reflect/scala/reflect/macros/FrontEnds.scala
@@ -5,12 +5,12 @@ package macros
/**
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
*
- * A slice of [[scala.reflect.macros.BlackboxContext the Scala macros context]] that
+ * A slice of [[scala.reflect.macros.blackbox.Context the Scala macros context]] that
* provides facilities to communicate with the compiler's front end
* (emit warnings, errors and other sorts of messages).
*/
trait FrontEnds {
- self: BlackboxContext =>
+ self: blackbox.Context =>
/** For sending a message which should not be labeled as a warning/error,
* but also shouldn't require -verbose to be visible.
diff --git a/src/reflect/scala/reflect/macros/Infrastructure.scala b/src/reflect/scala/reflect/macros/Infrastructure.scala
index b6585f94d2..0f2d9ce4cf 100644
--- a/src/reflect/scala/reflect/macros/Infrastructure.scala
+++ b/src/reflect/scala/reflect/macros/Infrastructure.scala
@@ -5,11 +5,11 @@ package macros
/**
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
*
- * A slice of [[scala.reflect.macros.BlackboxContext the Scala macros context]] that
+ * A slice of [[scala.reflect.macros.blackbox.Context the Scala macros context]] that
* provides facilities to communicate with the compiler's infrastructure.
*/
trait Infrastructure {
- self: BlackboxContext =>
+ self: blackbox.Context =>
/** Exposes macro-specific settings as a list of strings.
* These settings are passed to the compiler via the "-Xmacro-settings:setting1,setting2...,settingN" command-line option.
diff --git a/src/reflect/scala/reflect/macros/Names.scala b/src/reflect/scala/reflect/macros/Names.scala
index 6bd3e1a199..af60dffbfc 100644
--- a/src/reflect/scala/reflect/macros/Names.scala
+++ b/src/reflect/scala/reflect/macros/Names.scala
@@ -5,11 +5,11 @@ package macros
/**
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
*
- * A slice of [[scala.reflect.macros.BlackboxContext the Scala macros context]] that
+ * A slice of [[scala.reflect.macros.blackbox.Context the Scala macros context]] that
* provides functions that generate unique names.
*/
trait Names {
- self: BlackboxContext =>
+ self: blackbox.Context =>
/** Creates a unique string. */
@deprecated("Use freshName instead", "2.11.0")
diff --git a/src/reflect/scala/reflect/macros/Parsers.scala b/src/reflect/scala/reflect/macros/Parsers.scala
index 9d4a7e2953..720b754649 100644
--- a/src/reflect/scala/reflect/macros/Parsers.scala
+++ b/src/reflect/scala/reflect/macros/Parsers.scala
@@ -5,11 +5,11 @@ package macros
/**
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
*
- * A slice of [[scala.reflect.macros.BlackboxContext the Scala macros context]] that
+ * A slice of [[scala.reflect.macros.blackbox.Context the Scala macros context]] that
* exposes functions to parse strings with Scala code into trees.
*/
trait Parsers {
- self: BlackboxContext =>
+ self: blackbox.Context =>
/** Parses a string with a Scala expression into an abstract syntax tree.
* Only works for expressions, i.e. parsing a package declaration will fail.
diff --git a/src/reflect/scala/reflect/macros/Reifiers.scala b/src/reflect/scala/reflect/macros/Reifiers.scala
index 67d10dc10a..ff1f7a3b28 100644
--- a/src/reflect/scala/reflect/macros/Reifiers.scala
+++ b/src/reflect/scala/reflect/macros/Reifiers.scala
@@ -5,11 +5,11 @@ package macros
/**
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
*
- * A slice of [[scala.reflect.macros.BlackboxContext the Scala macros context]] that
+ * A slice of [[scala.reflect.macros.blackbox.Context the Scala macros context]] that
* exposes functions to save reflection artifacts for runtime.
*/
trait Reifiers {
- self: BlackboxContext =>
+ self: blackbox.Context =>
/** Given a tree, generate a tree that when compiled and executed produces the original tree.
* For more information and examples see the documentation for `Universe.reify`.
diff --git a/src/reflect/scala/reflect/macros/Typers.scala b/src/reflect/scala/reflect/macros/Typers.scala
index f215e8769d..87de442921 100644
--- a/src/reflect/scala/reflect/macros/Typers.scala
+++ b/src/reflect/scala/reflect/macros/Typers.scala
@@ -5,11 +5,11 @@ package macros
/**
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
*
- * A slice of [[scala.reflect.macros.BlackboxContext the Scala macros context]] that
+ * A slice of [[scala.reflect.macros.blackbox.Context the Scala macros context]] that
* partially exposes the type checker to macro writers.
*/
trait Typers {
- self: BlackboxContext =>
+ self: blackbox.Context =>
/** Contexts that represent macros in-flight, including the current one. Very much like a stack trace, but for macros only.
* Can be useful for interoperating with other macros and for imposing compiler-friendly limits on macro expansion.
@@ -21,7 +21,7 @@ trait Typers {
* Unlike `enclosingMacros`, this is a def, which means that it gets recalculated on every invocation,
* so it might change depending on what is going on during macro expansion.
*/
- def openMacros: List[BlackboxContext]
+ def openMacros: List[blackbox.Context]
/** @see `Typers.typecheck`
*/
diff --git a/src/reflect/scala/reflect/macros/Universe.scala b/src/reflect/scala/reflect/macros/Universe.scala
index 297bac2999..d84e6aa737 100644
--- a/src/reflect/scala/reflect/macros/Universe.scala
+++ b/src/reflect/scala/reflect/macros/Universe.scala
@@ -197,34 +197,44 @@ abstract class Universe extends scala.reflect.api.Universe {
def capturedVariableType(vble: Symbol): Type
/** The type of compilation runs.
+ * @see [[scala.reflect.macros.Enclosures]]
* @template
* @group Macros
*/
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
type Run <: RunContextApi
/** Compilation run uniquely identifies current invocation of the compiler
* (e.g. can be used to implement per-run caches for macros) and provides access to units of work
* of the invocation (currently processed unit of work and the list of all units).
+ * @see [[scala.reflect.macros.Enclosures]]
* @group API
*/
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
trait RunContextApi {
/** Currently processed unit of work (a real or a virtual file). */
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
def currentUnit: CompilationUnit
/** All units of work comprising this compilation run. */
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
def units: Iterator[CompilationUnit]
}
/** The type of compilation units.
+ * @see [[scala.reflect.macros.Enclosures]]
* @template
* @group Macros
*/
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
type CompilationUnit <: CompilationUnitContextApi
/** Compilation unit describes a unit of work of the compilation run.
* It provides such information as file name, textual representation of the unit and the underlying AST.
+ * @see [[scala.reflect.macros.Enclosures]]
* @group API
*/
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
trait CompilationUnitContextApi {
/** Source file corresponding to this compilation unit.
*
@@ -235,9 +245,11 @@ abstract class Universe extends scala.reflect.api.Universe {
* 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.
*/
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
def source: scala.reflect.internal.util.SourceFile
/** The AST that corresponds to this compilation unit. */
+ @deprecated("c.enclosingTree-style APIs are now deprecated; consult the scaladoc for more information", "2.11.0")
def body: Tree
}
}
diff --git a/src/reflect/scala/reflect/macros/WhiteboxMacro.scala b/src/reflect/scala/reflect/macros/WhiteboxMacro.scala
deleted file mode 100644
index 1c581313eb..0000000000
--- a/src/reflect/scala/reflect/macros/WhiteboxMacro.scala
+++ /dev/null
@@ -1,36 +0,0 @@
-package scala.reflect
-package macros
-
-/**
- * <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
- *
- * Traditionally macro implementations are defined as methods,
- * but this trait provides an alternative way of encoding macro impls as
- * bundles, traits which extend `scala.reflect.macros.BlackboxMacro` or`scala.reflect.macros.WhiteboxMacro` .
- *
- * Instead of:
- *
- * def impl[T: c.WeakTypeTag](c: WhiteboxContext)(x: c.Expr[Int]) = ...
- *
- * One can write:
- *
- * trait Impl extends WhiteboxMacro {
- * def apply[T: c.WeakTypeTag](x: c.Expr[Int]) = ...
- * }
- *
- * Without changing anything else at all.
- *
- * This language feature is useful in itself in cases when macro implementations
- * are complex and need to be modularized. State of the art technique of addressing this need is quite heavyweight:
- * http://docs.scala-lang.org/overviews/macros/overview.html#writing_bigger_macros.
- *
- * @see `scala.reflect.macros.BlackboxMacro`
- */
-trait WhiteboxMacro {
- /** The context to be used by the macro implementation.
- *
- * Vanilla macro implementations have to carry it in their signatures, however when a macro is a full-fledged module,
- * it can define the context next to the implementation, makes implementation signature more lightweight.
- */
- val c: WhiteboxContext
-}
diff --git a/src/reflect/scala/reflect/macros/BlackboxContext.scala b/src/reflect/scala/reflect/macros/blackbox/Context.scala
index 2c77289866..05d9595c3a 100644
--- a/src/reflect/scala/reflect/macros/BlackboxContext.scala
+++ b/src/reflect/scala/reflect/macros/blackbox/Context.scala
@@ -1,6 +1,7 @@
package scala
package reflect
package macros
+package blackbox
/**
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
@@ -24,24 +25,24 @@ package macros
* enclosing trees and compilation units, evaluating trees, logging warnings/errors and much more.
* Refer to the documentation of top-level traits in this package to learn the details.
*
- * If a macro def refers to a macro impl that uses `BlackboxContext`, then this macro def becomes a blackbox macro,
+ * If a macro def refers to a macro impl that uses `blackbox.Context`, then this macro def becomes a blackbox macro,
* which means that its expansion will be upcast to its return type, enforcing faithfullness of that macro to its
- * type signature. Whitebox macros, i.e. the ones defined with `WhiteboxContext`, aren't bound by this restriction,
+ * type signature. Whitebox macros, i.e. the ones defined with `whitebox.Context`, aren't bound by this restriction,
* which enables a number of important use cases, but they are also going to enjoy less support than blackbox macros,
* so choose wisely. See the [[http://docs.scala-lang.org/overviews/macros.html Macros Guide]] for more information.
*
- * @see `scala.reflect.macros.WhiteboxContext`
+ * @see `scala.reflect.macros.whitebox.Context`
*/
-trait BlackboxContext extends Aliases
- with Enclosures
- with Names
- with Reifiers
- with FrontEnds
- with Infrastructure
- with Typers
- with Parsers
- with Evals
- with ExprUtils {
+trait Context extends Aliases
+ with Enclosures
+ with Names
+ with Reifiers
+ with FrontEnds
+ with Infrastructure
+ with Typers
+ with Parsers
+ with Evals
+ with ExprUtils {
/** The compile-time universe. */
val universe: Universe
@@ -63,7 +64,7 @@ trait BlackboxContext extends Aliases
* scala> class Coll[T] {
* | def filter(p: T => Boolean): Coll[T] = macro M.filter[T]
* | }; object M {
- * | def filter[T](c: BlackboxContext { type PrefixType = Coll[T] })
+ * | def filter[T](c: Context { type PrefixType = Coll[T] })
* | (p: c.Expr[T => Boolean]): c.Expr[Coll[T]] =
* | {
* | println(c.prefix.tree)
diff --git a/src/reflect/scala/reflect/macros/package.scala b/src/reflect/scala/reflect/macros/package.scala
index 6a8434a163..cc7111d794 100644
--- a/src/reflect/scala/reflect/macros/package.scala
+++ b/src/reflect/scala/reflect/macros/package.scala
@@ -19,10 +19,10 @@ package object macros {
* with the former being better supported and the latter being more powerful. You can read about
* the details of the split and the associated trade-offs in the [[http://docs.scala-lang.org/overviews/macros.html Macros Guide]].
*
- * `scala.reflect.macros.Context` follows this tendency and turns into `scala.reflect.macros.BlackboxContext`
- * and `scala.reflect.macros.WhiteboxContext`. The original `Context` is left in place for compatibility reasons,
+ * `scala.reflect.macros.Context` follows this tendency and turns into `scala.reflect.macros.blackbox.Context`
+ * and `scala.reflect.macros.whitebox.Context`. The original `Context` is left in place for compatibility reasons,
* but it is now deprecated, nudging the users to choose between blackbox and whitebox macros.
*/
- @deprecated("Use BlackboxContext or WhiteboxContext instead", "2.11.0")
- type Context = WhiteboxContext
+ @deprecated("Use blackbox.Context or whitebox.Context instead", "2.11.0")
+ type Context = whitebox.Context
} \ No newline at end of file
diff --git a/src/reflect/scala/reflect/macros/WhiteboxContext.scala b/src/reflect/scala/reflect/macros/whitebox/Context.scala
index 9d65a5c16e..bd48df46cc 100644
--- a/src/reflect/scala/reflect/macros/WhiteboxContext.scala
+++ b/src/reflect/scala/reflect/macros/whitebox/Context.scala
@@ -1,6 +1,7 @@
package scala
package reflect
package macros
+package whitebox
/**
* <span class="badge badge-red" style="float: right;">EXPERIMENTAL</span>
@@ -24,22 +25,22 @@ package macros
* enclosing trees and compilation units, evaluating trees, logging warnings/errors and much more.
* Refer to the documentation of top-level traits in this package to learn the details.
*
- * If a macro def refers to a macro impl that uses `WhiteboxContext`, then this macro def becomes a whitebox macro,
+ * If a macro def refers to a macro impl that uses `whitebox.Context`, then this macro def becomes a whitebox macro,
* gaining the ability to refine the type of its expansion beyond its official return type, which enables a number of important use cases.
- * Blackbox macros, i.e. the ones defined with `BlackboxContext`, can't do that, so they are less powerful.
+ * Blackbox macros, i.e. the ones defined with `blackbox.Context`, can't do that, so they are less powerful.
* However blackbox macros are also going to enjoy better support than whitebox macros, so choose wisely.
* See the [[http://docs.scala-lang.org/overviews/macros.html Macros Guide]] for more information.
*
- * @see `scala.reflect.macros.BlackboxContext`
+ * @see `scala.reflect.macros.blackbox.Context`
*/
-trait WhiteboxContext extends BlackboxContext {
+trait Context extends blackbox.Context {
/** @inheritdoc
*/
- def openMacros: List[WhiteboxContext]
+ def openMacros: List[Context]
/** @inheritdoc
*/
- def enclosingMacros: List[WhiteboxContext]
+ def enclosingMacros: List[Context]
/** Information about one of the currently considered implicit candidates.
* Candidates are used in plural form, because implicit parameters may themselves have implicit parameters,
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index 9dfa5bcf2e..b9b171c7ed 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -41,7 +41,8 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
// inaccessible: this._lubResults
// inaccessible: this._glbResults
// inaccessible: this._indent
- // inaccessible: this._tostringRecursions
+ // inaccessible: this._toStringRecursions
+ // inaccessible: this._toStringSubjects
// inaccessible: this.atomicIds
// inaccessible: this.atomicExistentialIds
// inaccessible: this._recursionTable
@@ -199,6 +200,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.ErroneousCollector
this.adaptToNewRunMap
// inaccessible: this.commonOwnerMapObj
+ this.SubTypePair
this.SymbolKind
this.NoSymbol
this.CyclicReference
@@ -274,6 +276,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.ComparableClass
definitions.JavaCloneableClass
definitions.JavaNumberClass
+ definitions.JavaEnumClass
definitions.RemoteInterfaceClass
definitions.RemoteExceptionClass
definitions.ByNameParamClass
@@ -320,8 +323,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.MirrorClass
definitions.TypeCreatorClass
definitions.TreeCreatorClass
- definitions.BlackboxMacroClass
- definitions.WhiteboxMacroClass
definitions.BlackboxContextClass
definitions.WhiteboxContextClass
definitions.MacroImplAnnotation
diff --git a/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala b/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala
index de78e527a7..83d471f91e 100644
--- a/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala
+++ b/src/reflect/scala/reflect/runtime/SynchronizedTypes.scala
@@ -81,9 +81,12 @@ private[reflect] trait SynchronizedTypes extends internal.Types { self: SymbolTa
override def indent = _indent.get
override def indent_=(value: String) = _indent.set(value)
- private lazy val _tostringRecursions = mkThreadLocalStorage(0)
- override def tostringRecursions = _tostringRecursions.get
- override def tostringRecursions_=(value: Int) = _tostringRecursions.set(value)
+ private lazy val _toStringRecursions = mkThreadLocalStorage(0)
+ override def toStringRecursions = _toStringRecursions.get
+ override def toStringRecursions_=(value: Int) = _toStringRecursions.set(value)
+
+ private lazy val _toStringSubjects = mkThreadLocalStorage(new mutable.HashSet[Type])
+ override def toStringSubjects = _toStringSubjects.get
/* The idea of caches is as follows.
* When in reflexive mode, a cache is either null, or one sentinal
diff --git a/src/reflect/scala/reflect/runtime/package.scala b/src/reflect/scala/reflect/runtime/package.scala
index 3a7688aa2c..3c9bbccba3 100644
--- a/src/reflect/scala/reflect/runtime/package.scala
+++ b/src/reflect/scala/reflect/runtime/package.scala
@@ -26,7 +26,7 @@ package object runtime {
package runtime {
private[scala] object Macros {
- def currentMirror(c: scala.reflect.macros.BlackboxContext): c.Expr[universe.Mirror] = {
+ def currentMirror(c: scala.reflect.macros.blackbox.Context): c.Expr[universe.Mirror] = {
import c.universe._
val runtimeClass = c.reifyEnclosingRuntimeClass
if (runtimeClass.isEmpty) c.abort(c.enclosingPosition, "call site does not have an enclosing class")