summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/plugins/Plugin.scala93
-rw-r--r--src/compiler/scala/tools/nsc/plugins/PluginLoadException.scala15
-rw-r--r--src/compiler/scala/tools/nsc/plugins/Plugins.scala21
-rw-r--r--src/compiler/scala/tools/nsc/transform/Erasure.scala13
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala76
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala4
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala2
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Holes.scala280
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala7
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala41
-rw-r--r--src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala183
-rw-r--r--src/interactive/scala/tools/nsc/interactive/Global.scala6
-rw-r--r--src/library/scala/MatchError.scala10
-rw-r--r--src/library/scala/collection/immutable/Queue.scala12
-rw-r--r--src/reflect/scala/reflect/api/BuildUtils.scala55
-rw-r--r--src/reflect/scala/reflect/api/Liftable.scala32
-rw-r--r--src/reflect/scala/reflect/api/StandardLiftables.scala230
-rw-r--r--src/reflect/scala/reflect/api/StandardNames.scala14
-rw-r--r--src/reflect/scala/reflect/internal/BuildUtils.scala133
-rw-r--r--src/reflect/scala/reflect/internal/Definitions.scala3
-rw-r--r--src/reflect/scala/reflect/internal/StdAttachments.scala3
-rw-r--r--src/reflect/scala/reflect/internal/StdNames.scala27
-rw-r--r--src/reflect/scala/reflect/internal/Symbols.scala21
-rw-r--r--src/reflect/scala/reflect/internal/Types.scala13
-rw-r--r--src/reflect/scala/reflect/internal/util/StringOps.scala16
-rw-r--r--src/reflect/scala/reflect/runtime/JavaUniverseForce.scala4
-rw-r--r--src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala5
-rw-r--r--src/swing/scala/swing/Publisher.scala2
28 files changed, 849 insertions, 472 deletions
diff --git a/src/compiler/scala/tools/nsc/plugins/Plugin.scala b/src/compiler/scala/tools/nsc/plugins/Plugin.scala
index d194c095f8..183752d4a2 100644
--- a/src/compiler/scala/tools/nsc/plugins/Plugin.scala
+++ b/src/compiler/scala/tools/nsc/plugins/Plugin.scala
@@ -12,7 +12,8 @@ import scala.reflect.io.{ Directory, File, Path }
import java.io.InputStream
import java.util.zip.ZipException
-import scala.collection.mutable.ListBuffer
+import scala.collection.mutable
+import mutable.ListBuffer
import scala.util.{ Try, Success, Failure }
/** Information about a plugin loaded from a jar file.
@@ -99,7 +100,7 @@ object Plugin {
private def loadDescriptionFromJar(jarp: Path): Try[PluginDescription] = {
// XXX Return to this once we have more ARM support
def read(is: Option[InputStream]) = is match {
- case None => throw new RuntimeException(s"Missing $PluginXML in $jarp")
+ case None => throw new PluginLoadException(jarp.path, s"Missing $PluginXML in $jarp")
case Some(is) => PluginDescription.fromXML(is)
}
Try(new Jar(jarp.jfile).withEntryStream(PluginXML)(read))
@@ -113,11 +114,14 @@ object Plugin {
/** Use a class loader to load the plugin class.
*/
def load(classname: String, loader: ClassLoader): Try[AnyClass] = {
- Try[AnyClass] {
- loader loadClass classname
- } recoverWith {
- case _: Exception =>
- Failure(new RuntimeException(s"Warning: class not found: ${classname}"))
+ import scala.util.control.NonFatal
+ try {
+ Success[AnyClass](loader loadClass classname)
+ } catch {
+ case NonFatal(e) =>
+ Failure(new PluginLoadException(classname, s"Error: unable to load class: $classname"))
+ case e: NoClassDefFoundError =>
+ Failure(new PluginLoadException(classname, s"Error: class not found: ${e.getMessage} required by $classname"))
}
}
@@ -128,33 +132,54 @@ object Plugin {
* A single classloader is created and used to load all of them.
*/
def loadAllFrom(
- jars: List[Path],
+ paths: List[List[Path]],
dirs: List[Path],
ignoring: List[String]): List[Try[AnyClass]] =
{
- // List[(jar, Success(descriptor))] in dir
- def scan(d: Directory) = for {
- f <- d.files.toList sortBy (_.name)
- if Jar isJarOrZip f
- pd = loadDescriptionFromJar(f)
- if pd.isSuccess
- } yield (f, pd)
- // (dir, Try(descriptor))
- def explode(d: Directory) = d -> loadDescriptionFromFile(d / PluginXML)
- // (j, Try(descriptor))
- def required(j: Path) = j -> loadDescriptionFromJar(j)
-
- type Paired = Tuple2[Path, Try[PluginDescription]]
- val included: List[Paired] = (dirs flatMap (_ ifDirectory scan)).flatten
- val exploded: List[Paired] = jars flatMap (_ ifDirectory explode)
- val explicit: List[Paired] = jars flatMap (_ ifFile required)
- def ignored(p: Paired) = p match {
- case (path, Success(pd)) => ignoring contains pd.name
- case _ => false
+ // List[(jar, Try(descriptor))] in dir
+ def scan(d: Directory) =
+ d.files.toList sortBy (_.name) filter (Jar isJarOrZip _) map (j => (j, loadDescriptionFromJar(j)))
+
+ type PDResults = List[Try[(PluginDescription, ScalaClassLoader)]]
+
+ // scan plugin dirs for jars containing plugins, ignoring dirs with none and other jars
+ val fromDirs: PDResults = dirs filter (_.isDirectory) flatMap { d =>
+ scan(d.toDirectory) collect {
+ case (j, Success(pd)) => Success((pd, loaderFor(Seq(j))))
+ }
+ }
+
+ // scan jar paths for plugins, taking the first plugin you find.
+ // a path element can be either a plugin.jar or an exploded dir.
+ def findDescriptor(ps: List[Path]) = {
+ def loop(qs: List[Path]): Try[PluginDescription] = qs match {
+ case Nil => Failure(new MissingPluginException(ps))
+ case p :: rest =>
+ if (p.isDirectory) loadDescriptionFromFile(p.toDirectory / PluginXML)
+ else if (p.isFile) loadDescriptionFromJar(p.toFile)
+ else loop(rest)
+ }
+ loop(ps)
+ }
+ val fromPaths: PDResults = paths map (p => (p, findDescriptor(p))) map {
+ case (p, Success(pd)) => Success((pd, loaderFor(p)))
+ case (_, Failure(e)) => Failure(e)
}
- val (locs, pds) = ((explicit ::: exploded ::: included) filterNot ignored).unzip
- val loader = loaderFor(locs.distinct)
- (pds filter (_.isSuccess) map (_.get.classname)).distinct map (Plugin load (_, loader))
+
+ val seen = mutable.HashSet[String]()
+ val enabled = (fromPaths ::: fromDirs) map {
+ case Success((pd, loader)) if seen(pd.classname) =>
+ // a nod to SI-7494, take the plugin classes distinctly
+ Failure(new PluginLoadException(pd.name, s"Ignoring duplicate plugin ${pd.name} (${pd.classname})"))
+ case Success((pd, loader)) if ignoring contains pd.name =>
+ Failure(new PluginLoadException(pd.name, s"Disabling plugin ${pd.name}"))
+ case Success((pd, loader)) =>
+ seen += pd.classname
+ Plugin.load(pd.classname, loader)
+ case Failure(e) =>
+ Failure(e)
+ }
+ enabled // distinct and not disabled
}
/** Instantiate a plugin class, given the class and
@@ -164,3 +189,11 @@ object Plugin {
(clazz getConstructor classOf[Global] newInstance global).asInstanceOf[Plugin]
}
}
+
+class PluginLoadException(val path: String, message: String, cause: Exception) extends Exception(message, cause) {
+ def this(path: String, message: String) = this(path, message, null)
+}
+
+class MissingPluginException(path: String) extends PluginLoadException(path, s"No plugin in path $path") {
+ def this(paths: List[Path]) = this(paths mkString File.pathSeparator)
+}
diff --git a/src/compiler/scala/tools/nsc/plugins/PluginLoadException.scala b/src/compiler/scala/tools/nsc/plugins/PluginLoadException.scala
deleted file mode 100644
index c5da24993e..0000000000
--- a/src/compiler/scala/tools/nsc/plugins/PluginLoadException.scala
+++ /dev/null
@@ -1,15 +0,0 @@
-/* NSC -- new Scala compiler
- * Copyright 2007-2013 LAMP/EPFL
- * @author Lex Spoon
- */
-
-package scala.tools.nsc
-package plugins
-
-/** ...
- *
- * @author Lex Spoon
- * @version 1.0, 2007-5-21
- */
-class PluginLoadException(filename: String, cause: Exception)
-extends Exception(cause)
diff --git a/src/compiler/scala/tools/nsc/plugins/Plugins.scala b/src/compiler/scala/tools/nsc/plugins/Plugins.scala
index 4769705404..12f9aeba27 100644
--- a/src/compiler/scala/tools/nsc/plugins/Plugins.scala
+++ b/src/compiler/scala/tools/nsc/plugins/Plugins.scala
@@ -8,6 +8,7 @@ package scala.tools.nsc
package plugins
import scala.reflect.io.{ File, Path }
+import scala.tools.nsc.util.ClassPath
import scala.tools.util.PathResolver.Defaults
/** Support for run-time loading of compiler plugins.
@@ -16,8 +17,7 @@ import scala.tools.util.PathResolver.Defaults
* @version 1.1, 2009/1/2
* Updated 2009/1/2 by Anders Bach Nielsen: Added features to implement SIP 00002
*/
-trait Plugins {
- self: Global =>
+trait Plugins { global: Global =>
/** Load a rough list of the plugins. For speed, it
* does not instantiate a compiler run. Therefore it cannot
@@ -25,13 +25,20 @@ trait Plugins {
* filtered from the final list of plugins.
*/
protected def loadRoughPluginsList(): List[Plugin] = {
- val jars = settings.plugin.value map Path.apply
- def injectDefault(s: String) = if (s.isEmpty) Defaults.scalaPluginPath else s
- val dirs = (settings.pluginsDir.value split File.pathSeparator).toList map injectDefault map Path.apply
- val maybes = Plugin.loadAllFrom(jars, dirs, settings.disable.value)
+ def asPath(p: String) = ClassPath split p
+ val paths = settings.plugin.value filter (_ != "") map (s => asPath(s) map Path.apply)
+ val dirs = {
+ def injectDefault(s: String) = if (s.isEmpty) Defaults.scalaPluginPath else s
+ asPath(settings.pluginsDir.value) map injectDefault map Path.apply
+ }
+ val maybes = Plugin.loadAllFrom(paths, dirs, settings.disable.value)
val (goods, errors) = maybes partition (_.isSuccess)
// Explicit parameterization of recover to suppress -Xlint warning about inferred Any
- errors foreach (_.recover[Any] { case e: Exception => inform(e.getMessage) })
+ errors foreach (_.recover[Any] {
+ // legacy behavior ignores altogether, so at least warn devs
+ case e: MissingPluginException => if (global.isDeveloper) warning(e.getMessage)
+ case e: Exception => inform(e.getMessage)
+ })
val classes = goods map (_.get) // flatten
// Each plugin must only be instantiated once. A common pattern
diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala
index 6fe0f34105..6732900ef2 100644
--- a/src/compiler/scala/tools/nsc/transform/Erasure.scala
+++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala
@@ -714,11 +714,24 @@ abstract class Erasure extends AddInterfaces
/** TODO - adapt SymbolPairs so it can be used here. */
private def checkNoDeclaredDoubleDefs(base: Symbol) {
val decls = base.info.decls
+
+ // SI-8010 force infos, otherwise makeNotPrivate in ExplicitOuter info transformer can trigger
+ // a scope rehash while were iterating and we can see the same entry twice!
+ // Inspection of SymbolPairs (the basis of OverridingPairs), suggests that it is immune
+ // from this sort of bug as it copies the symbols into a temporary scope *before* any calls to `.info`,
+ // ie, no variant of it calls `info` or `tpe` in `SymbolPair#exclude`.
+ //
+ // Why not just create a temporary scope here? We need to force the name changes in any case before
+ // we do these checks, so that we're comparing same-named methods based on the expanded names that actually
+ // end up in the bytecode.
+ exitingPostErasure(decls.foreach(_.info))
+
var e = decls.elems
while (e ne null) {
if (e.sym.isTerm) {
var e1 = decls lookupNextEntry e
while (e1 ne null) {
+ assert(e.sym ne e1.sym, s"Internal error: encountered ${e.sym.debugLocationString} twice during scope traversal. This might be related to SI-8010.")
if (sameTypeAfterErasure(e.sym, e1.sym))
doubleDefError(new SymbolPair(base, e.sym, e1.sym))
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index 2be6d92ed0..53bc9a2772 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -773,7 +773,7 @@ trait Contexts { self: Analyzer =>
// Implicit collection
//
- private var implicitsCache: List[List[ImplicitInfo]] = null
+ private var implicitsCache: List[ImplicitInfo] = null
private var implicitsRunId = NoRunId
def resetCache() {
@@ -832,35 +832,53 @@ trait Contexts { self: Analyzer =>
* filtered out later by `eligibleInfos` (SI-4270 / 9129cfe9), as they don't type-check.
*/
def implicitss: List[List[ImplicitInfo]] = {
- val imports = this.imports
val nextOuter = this.nextOuter
- if (implicitsRunId != currentRunId) {
- implicitsRunId = currentRunId
- implicitsCache = List()
- val newImplicits: List[ImplicitInfo] =
- if (owner != nextOuter.owner && owner.isClass && !owner.isPackageClass && !inSelfSuperCall) {
- if (!owner.isInitialized) return nextOuter.implicitss
- // debuglog("collect member implicits " + owner + ", implicit members = " + owner.thisType.implicitMembers)//DEBUG
- savingEnclClass(this) {
- // !!! In the body of `class C(implicit a: A) { }`, `implicitss` returns `List(List(a), List(a), List(<predef..)))`
- // it handled correctly by implicit search, which considers the second `a` to be shadowed, but should be
- // remedied nonetheless.
- collectImplicits(owner.thisType.implicitMembers, owner.thisType)
- }
- } else if (scope != nextOuter.scope && !owner.isPackageClass) {
- debuglog("collect local implicits " + scope.toList)//DEBUG
- collectImplicits(scope, NoPrefix)
- } else if (firstImport != nextOuter.firstImport) {
- assert(imports.tail.headOption == nextOuter.firstImport, (imports, nextOuter.imports))
- collectImplicitImports(imports.head)
- } else if (owner.isPackageClass) {
- // the corresponding package object may contain implicit members.
- collectImplicits(owner.tpe.implicitMembers, owner.tpe)
- } else List()
- implicitsCache = if (newImplicits.isEmpty) nextOuter.implicitss
- else newImplicits :: nextOuter.implicitss
+ def withOuter(is: List[ImplicitInfo]): List[List[ImplicitInfo]] =
+ is match {
+ case Nil => nextOuter.implicitss
+ case _ => is :: nextOuter.implicitss
+ }
+
+ val CycleMarker = NoRunId - 1
+ if (implicitsRunId == CycleMarker) {
+ debuglog(s"cycle while collecting implicits at owner ${owner}, probably due to an implicit without an explicit return type. Continuing with implicits from enclosing contexts.")
+ withOuter(Nil)
+ } else if (implicitsRunId != currentRunId) {
+ implicitsRunId = CycleMarker
+ implicits(nextOuter) match {
+ case None =>
+ implicitsRunId = NoRunId
+ withOuter(Nil)
+ case Some(is) =>
+ implicitsRunId = currentRunId
+ implicitsCache = is
+ withOuter(is)
+ }
}
- implicitsCache
+ else withOuter(implicitsCache)
+ }
+
+ /** @return None if a cycle is detected, or Some(infos) containing the in-scope implicits at this context */
+ private def implicits(nextOuter: Context): Option[List[ImplicitInfo]] = {
+ val imports = this.imports
+ if (owner != nextOuter.owner && owner.isClass && !owner.isPackageClass && !inSelfSuperCall) {
+ if (!owner.isInitialized) None
+ else savingEnclClass(this) {
+ // !!! In the body of `class C(implicit a: A) { }`, `implicitss` returns `List(List(a), List(a), List(<predef..)))`
+ // it handled correctly by implicit search, which considers the second `a` to be shadowed, but should be
+ // remedied nonetheless.
+ Some(collectImplicits(owner.thisType.implicitMembers, owner.thisType))
+ }
+ } else if (scope != nextOuter.scope && !owner.isPackageClass) {
+ debuglog("collect local implicits " + scope.toList)//DEBUG
+ Some(collectImplicits(scope, NoPrefix))
+ } else if (firstImport != nextOuter.firstImport) {
+ assert(imports.tail.headOption == nextOuter.firstImport, (imports, nextOuter.imports))
+ Some(collectImplicitImports(imports.head))
+ } else if (owner.isPackageClass) {
+ // the corresponding package object may contain implicit members.
+ Some(collectImplicits(owner.tpe.implicitMembers, owner.tpe))
+ } else Some(Nil)
}
//
@@ -1108,7 +1126,7 @@ trait Contexts { self: Analyzer =>
impSym = NoSymbol
// Otherwise they are irreconcilably ambiguous
else
- return ambiguousDefnAndImport(defSym.owner, imp1)
+ return ambiguousDefnAndImport(defSym.alternatives.head.owner, imp1)
}
// At this point only one or the other of defSym and impSym might be set.
diff --git a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
index ba135d7d25..069d6d5fb2 100644
--- a/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/PatternTypers.scala
@@ -391,8 +391,10 @@ trait PatternTypers {
else freshUnapplyArgType()
)
)
+ val unapplyArgTree = Ident(unapplyArg) updateAttachment SubpatternsAttachment(args)
+
// clearing the type is necessary so that ref will be stabilized; see bug 881
- val fun1 = typedPos(fun.pos)(Apply(Select(fun.clearType(), unapplyMethod), Ident(unapplyArg) :: Nil))
+ val fun1 = typedPos(fun.pos)(Apply(Select(fun.clearType(), unapplyMethod), unapplyArgTree :: Nil))
def makeTypedUnApply() = {
// the union of the expected type and the inferred type of the argument to unapply
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 520b55400c..5e89440bc0 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -3746,7 +3746,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
val dealiasLocals = new TypeMap {
def apply(tp: Type): Type = tp match {
case TypeRef(pre, sym, args) =>
- if (sym.isAliasType && containsLocal(tp)) apply(tp.dealias)
+ if (sym.isAliasType && containsLocal(tp) && (tp.dealias ne tp)) apply(tp.dealias)
else {
if (pre.isVolatile)
InferTypeWithVolatileTypeSelectionError(tree, pre)
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
index f92c9aa845..f5bcaf68e0 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
@@ -3,6 +3,7 @@ package quasiquotes
import scala.collection.{immutable, mutable}
import scala.reflect.internal.Flags._
+import scala.reflect.macros.TypecheckException
class Cardinality private[Cardinality](val value: Int) extends AnyVal {
def pred = { assert(value - 1 >= 0); new Cardinality(value - 1) }
@@ -30,158 +31,173 @@ trait Holes { self: Quasiquotes =>
import definitions._
import universeTypes._
- /** Location characterizes a kind of a non-terminal in Scala syntax where something is going to be spliced.
- * A location is typically associated with a type of the things that can be spliced there.
- * Associated type might be different from an actual tpe of a splicee due to lifting.
- * This is the first pillar of modularity in the quasiquote reifier.
- */
- sealed abstract class Location(val tpe: Type)
- case object UnknownLocation extends Location(NoType)
- case class TreeLocation(override val tpe: Type) extends Location(tpe)
- case object NameLocation extends Location(nameType)
- case object ModsLocation extends Location(modsType)
- case object FlagsLocation extends Location(flagsType)
- case object SymbolLocation extends Location(symbolType)
- case class IterableLocation(card: Cardinality, sublocation: TreeLocation) extends Location(NoType) {
- override val tpe = {
- def loop(n: Cardinality, tpe: Type): Type =
- if (n == NoDot) tpe
- else appliedType(IterableClass.toType, List(loop(n.pred, tpe)))
- loop(card, sublocation.tpe)
+ protected lazy val IterableTParam = IterableClass.typeParams(0).asType.toType
+ protected def inferParamImplicit(tfun: Type, targ: Type) = c.inferImplicitValue(appliedType(tfun, List(targ)), silent = true)
+ protected def inferLiftable(tpe: Type): Tree = inferParamImplicit(liftableType, tpe)
+ protected def inferUnliftable(tpe: Type): Tree = inferParamImplicit(unliftableType, tpe)
+ protected def isLiftableType(tpe: Type) = inferLiftable(tpe) != EmptyTree
+ protected def isNativeType(tpe: Type) =
+ (tpe <:< treeType) || (tpe <:< nameType) || (tpe <:< modsType) ||
+ (tpe <:< flagsType) || (tpe <:< symbolType)
+ protected def isBottomType(tpe: Type) =
+ tpe <:< NothingClass.tpe || tpe <:< NullClass.tpe
+ protected def stripIterable(tpe: Type, limit: Option[Cardinality] = None): (Cardinality, Type) =
+ if (limit.map { _ == NoDot }.getOrElse { false }) (NoDot, tpe)
+ else if (tpe != null && !isIterableType(tpe)) (NoDot, tpe)
+ else if (isBottomType(tpe)) (NoDot, tpe)
+ else {
+ val targ = IterableTParam.asSeenFrom(tpe, IterableClass)
+ val (card, innerTpe) = stripIterable(targ, limit.map { _.pred })
+ (card.succ, innerTpe)
}
+ protected def iterableTypeFromCard(n: Cardinality, tpe: Type): Type = {
+ if (n == NoDot) tpe
+ else appliedType(IterableClass.toType, List(iterableTypeFromCard(n.pred, tpe)))
}
- /** Hole type describes location, cardinality and a pre-reification routine associated with a hole.
- * An interesting thing about HoleType is that it can be completely inferred from the type of the splicee.
- * This is the second pillar of modularity in the quasiquote reifier.
+ /** Hole encapsulates information about splices in quasiquotes.
+ * It packs together a cardinality of a splice, pre-reified tree
+ * representation (possibly preprocessed) and position.
*/
- case class HoleType(preprocessor: Tree => Tree, location: Location, cardinality: Cardinality) {
- def makeHole(tree: Tree) = Hole(preprocessor(tree), location, cardinality)
+ abstract class Hole {
+ val tree: Tree
+ val pos: Position
+ val cardinality: Cardinality
}
- object HoleType {
- def unapply(tpe: Type): Option[HoleType] = tpe match {
- case NativeType(holeTpe) => Some(holeTpe)
- case LiftableType(holeTpe) => Some(holeTpe)
- case IterableTreeType(holeTpe) => Some(holeTpe)
- case IterableLiftableType(holeTpe) => Some(holeTpe)
- case _ => None
- }
- trait HoleTypeExtractor {
- def unapply(tpe: Type): Option[HoleType] = {
- for {
- preprocessor <- this.preprocessor(tpe)
- location <- this.location(tpe)
- cardinality <- Some(this.cardinality(tpe))
- } yield HoleType(preprocessor, location, cardinality)
- }
- def preprocessor(tpe: Type): Option[Tree => Tree]
- def location(tpe: Type): Option[Location]
- def cardinality(tpe: Type): Cardinality = parseCardinality(tpe)._1
-
- def lifter(tpe: Type): Option[Tree => Tree] = {
- val lifterTpe = appliedType(LiftableClass.toType, List(tpe))
- val lifter = c.inferImplicitValue(lifterTpe, silent = true)
- if (lifter != EmptyTree) Some(tree => {
- val lifted = Apply(lifter, List(u, tree))
- val targetType = Select(u, tpnme.Tree)
- atPos(tree.pos)(TypeApply(Select(lifted, nme.asInstanceOf_), List(targetType)))
- }) else None
- }
+ object Hole {
+ def apply(card: Cardinality, tree: Tree): Hole =
+ if (method != nme.unapply) new ApplyHole(card, tree)
+ else new UnapplyHole(card, tree)
+ def unapply(hole: Hole): Some[(Tree, Cardinality)] = Some((hole.tree, hole.cardinality))
+ }
- def iterator(tpe: Type)(elementTransform: Tree => Tree): Option[Tree => Tree] = {
- def reifyIterable(tree: Tree, n: Cardinality): Tree = {
- def loop(tree: Tree, n: Cardinality) =
- if (n == NoDot) elementTransform(tree)
- else {
- val x: TermName = c.freshName()
- val wrapped = reifyIterable(Ident(x), n.pred)
- val xToWrapped = Function(List(ValDef(Modifiers(PARAM), x, TypeTree(), EmptyTree)), wrapped)
- Select(Apply(Select(tree, nme.map), List(xToWrapped)), nme.toList)
- }
- if (tree.tpe != null && (tree.tpe <:< listTreeType || tree.tpe <:< listListTreeType)) tree
- else atPos(tree.pos)(loop(tree, n))
- }
- val card = parseCardinality(tpe)._1
- if (card != NoDot) Some(reifyIterable(_, card)) else None
- }
+ class ApplyHole(card: Cardinality, splicee: Tree) extends Hole {
+ val (strippedTpe, tpe): (Type, Type) = {
+ if (stripIterable(splicee.tpe)._1.value < card.value) cantSplice()
+ val (_, strippedTpe) = stripIterable(splicee.tpe, limit = Some(card))
+ if (isBottomType(strippedTpe)) cantSplice()
+ else if (isNativeType(strippedTpe)) (strippedTpe, iterableTypeFromCard(card, strippedTpe))
+ else if (isLiftableType(strippedTpe)) (strippedTpe, iterableTypeFromCard(card, treeType))
+ else cantSplice()
}
- object NativeType extends HoleTypeExtractor {
- def preprocessor(tpe: Type) = Some(identity)
- def location(tpe: Type) = {
- if (tpe <:< treeType) Some(TreeLocation(tpe))
- else if (tpe <:< nameType) Some(NameLocation)
- else if (tpe <:< modsType) Some(ModsLocation)
- else if (tpe <:< flagsType) Some(FlagsLocation)
- else if (tpe <:< symbolType) Some(SymbolLocation)
- else None
- }
+ val tree = {
+ def inner(itpe: Type)(tree: Tree) =
+ if (isNativeType(itpe)) tree
+ else if (isLiftableType(itpe)) lifted(itpe)(tree)
+ else global.abort("unreachable")
+ if (card == NoDot) inner(strippedTpe)(splicee)
+ else iterated(card, strippedTpe, inner(strippedTpe))(splicee)
}
- object LiftableType extends HoleTypeExtractor {
- def preprocessor(tpe: Type) = lifter(tpe)
- def location(tpe: Type) = Some(TreeLocation(treeType))
+ val pos = splicee.pos
+
+ val cardinality = stripIterable(tpe)._1
+
+ protected def cantSplice(): Nothing = {
+ val (iterableCard, iterableType) = stripIterable(splicee.tpe)
+ val holeCardMsg = if (card != NoDot) s" with $card" else ""
+ val action = "splice " + splicee.tpe + holeCardMsg
+ val suggestCard = card != iterableCard || card != NoDot
+ val spliceeCardMsg = if (card != iterableCard && iterableCard != NoDot) s"using $iterableCard" else "omitting the dots"
+ val cardSuggestion = if (suggestCard) spliceeCardMsg else ""
+ val suggestLifting = (card == NoDot || iterableCard != NoDot) && !(iterableType <:< treeType) && !isLiftableType(iterableType)
+ val liftedTpe = if (card != NoDot) iterableType else splicee.tpe
+ val liftSuggestion = if (suggestLifting) s"providing an implicit instance of Liftable[$liftedTpe]" else ""
+ val advice =
+ if (isBottomType(iterableType)) "bottom type values often indicate programmer mistake"
+ else "consider " + List(cardSuggestion, liftSuggestion).filter(_ != "").mkString(" or ")
+ c.abort(splicee.pos, s"Can't $action, $advice")
}
- object IterableTreeType extends HoleTypeExtractor {
- def preprocessor(tpe: Type) = iterator(tpe)(identity)
- def location(tpe: Type) = {
- val (card, elementTpe) = parseCardinality(tpe)
- if (card != NoDot && elementTpe <:< treeType) Some(IterableLocation(card, TreeLocation(elementTpe)))
- else None
- }
+ protected def lifted(tpe: Type)(tree: Tree): Tree = {
+ val lifter = inferLiftable(tpe)
+ assert(lifter != EmptyTree, s"couldnt find a liftable for $tpe")
+ val lifted = Apply(lifter, List(tree))
+ val targetType = Select(u, tpnme.Tree)
+ atPos(tree.pos)(TypeApply(Select(lifted, nme.asInstanceOf_), List(targetType)))
}
- object IterableLiftableType extends HoleTypeExtractor {
- def preprocessor(tpe: Type) = {
- val (_, elementTpe) = parseCardinality(tpe)
- for {
- lifter <- this.lifter(elementTpe)
- iterator <- this.iterator(tpe)(lifter)
- } yield iterator
+ protected def iterated(card: Cardinality, tpe: Type, elementTransform: Tree => Tree = identity)(tree: Tree): Tree = {
+ assert(card != NoDot)
+ def reifyIterable(tree: Tree, n: Cardinality): Tree = {
+ def loop(tree: Tree, n: Cardinality): Tree =
+ if (n == NoDot) elementTransform(tree)
+ else {
+ val x: TermName = c.freshName()
+ val wrapped = reifyIterable(Ident(x), n.pred)
+ val xToWrapped = Function(List(ValDef(Modifiers(PARAM), x, TypeTree(), EmptyTree)), wrapped)
+ Select(Apply(Select(tree, nme.map), List(xToWrapped)), nme.toList)
+ }
+ if (tree.tpe != null && (tree.tpe <:< listTreeType || tree.tpe <:< listListTreeType)) tree
+ else atPos(tree.pos)(loop(tree, n))
}
- def location(tpe: Type) = Some(IterableLocation(cardinality(tpe), TreeLocation(treeType)))
+ reifyIterable(tree, card)
}
}
- /** Hole encapsulates information about splices in quasiquotes.
- * It packs together a cardinality of a splice, a splicee (possibly preprocessed)
- * and the description of the location in Scala syntax where the splicee can be spliced.
- * This is the third pillar of modularity in the quasiquote reifier.
- */
- case class Hole(tree: Tree, location: Location, cardinality: Cardinality)
-
- object Hole {
- def apply(splicee: Tree, holeCard: Cardinality): Hole = {
- if (method == nme.unapply) return new Hole(splicee, UnknownLocation, holeCard)
- val (spliceeCard, elementTpe) = parseCardinality(splicee.tpe)
- def cantSplice() = {
- val holeCardMsg = if (holeCard != NoDot) s" with $holeCard" else ""
- val action = "splice " + splicee.tpe + holeCardMsg
- val suggestCard = holeCard != spliceeCard || holeCard != NoDot
- val spliceeCardMsg = if (holeCard != spliceeCard && spliceeCard != NoDot) s"using $spliceeCard" else "omitting the dots"
- val cardSuggestion = if (suggestCard) spliceeCardMsg else ""
- def canBeLifted(tpe: Type) = HoleType.LiftableType.unapply(tpe).nonEmpty
- val suggestLifting = (holeCard == NoDot || spliceeCard != NoDot) && !(elementTpe <:< treeType) && !canBeLifted(elementTpe)
- val liftedTpe = if (holeCard != NoDot) elementTpe else splicee.tpe
- val liftSuggestion = if (suggestLifting) s"providing an implicit instance of Liftable[$liftedTpe]" else ""
- val advice = List(cardSuggestion, liftSuggestion).filter(_ != "").mkString(" or ")
- c.abort(splicee.pos, s"Can't $action, consider $advice")
- }
- val holeTpe = splicee.tpe match {
- case _ if holeCard != spliceeCard => cantSplice()
- case HoleType(holeTpe) => holeTpe
- case _ => cantSplice()
- }
- holeTpe.makeHole(splicee)
+ class UnapplyHole(val cardinality: Cardinality, pat: Tree) extends Hole {
+ val (placeholderName, pos, tptopt) = pat match {
+ case Bind(pname, inner @ Bind(_, Typed(Ident(nme.WILDCARD), tpt))) => (pname, inner.pos, Some(tpt))
+ case Bind(pname, inner @ Typed(Ident(nme.WILDCARD), tpt)) => (pname, inner.pos, Some(tpt))
+ case Bind(pname, inner) => (pname, inner.pos, None)
}
+ val treeNoUnlift = Bind(placeholderName, Ident(nme.WILDCARD))
+ lazy val tree =
+ tptopt.map { tpt =>
+ val TypeDef(_, _, _, typedTpt) =
+ try c.typeCheck(TypeDef(NoMods, TypeName("T"), Nil, tpt))
+ catch { case TypecheckException(pos, msg) => c.abort(pos.asInstanceOf[c.Position], msg) }
+ val tpe = typedTpt.tpe
+ val (iterableCard, _) = stripIterable(tpe)
+ if (iterableCard.value < cardinality.value)
+ c.abort(pat.pos, s"Can't extract $tpe with $cardinality, consider using $iterableCard")
+ val (_, strippedTpe) = stripIterable(tpe, limit = Some(cardinality))
+ if (strippedTpe <:< treeType) treeNoUnlift
+ else
+ unlifters.spawn(strippedTpe, cardinality).map {
+ Apply(_, treeNoUnlift :: Nil)
+ }.getOrElse {
+ c.abort(pat.pos, s"Can't find $unliftableType[$strippedTpe], consider providing it")
+ }
+ }.getOrElse { treeNoUnlift }
}
- def parseCardinality(tpe: Type): (Cardinality, Type) = {
- if (tpe != null && isIterableType(tpe)) {
- val (card, innerTpe) = parseCardinality(tpe.typeArguments.head)
- (card.succ, innerTpe)
- } else (NoDot, tpe)
+ /** Full support for unliftable implies that it's possible to interleave
+ * deconstruction with higher cardinality and unlifting of the values.
+ * In particular extraction of List[Tree] as List[T: Unliftable] requires
+ * helper extractors that would do the job: UnliftHelper1[T]. Similarly
+ * List[List[Tree]] needs UnliftHelper2[T].
+ *
+ * See also "unlift list" tests in UnapplyProps.scala
+ */
+ object unlifters {
+ private var records = List.empty[(Type, Cardinality)]
+ // Request an UnliftHelperN[T] where n == card and T == tpe.
+ // If card == 0 then helper is not needed and plain instance
+ // of unliftable is returned.
+ def spawn(tpe: Type, card: Cardinality): Option[Tree] = {
+ val unlifter = inferUnliftable(tpe)
+ if (unlifter == EmptyTree) None
+ else if (card == NoDot) Some(unlifter)
+ else {
+ val idx = records.indexWhere { p => p._1 =:= tpe && p._2 == card }
+ val resIdx = if (idx != -1) idx else { records +:= (tpe, card); records.length - 1}
+ Some(Ident(TermName(nme.QUASIQUOTE_UNLIFT_HELPER + resIdx)))
+ }
+ }
+ // Returns a list of vals that will defined required unlifters
+ def preamble(): List[Tree] =
+ records.zipWithIndex.map { case ((tpe, card), idx) =>
+ val name = TermName(nme.QUASIQUOTE_UNLIFT_HELPER + idx)
+ val helperName = card match { case DotDot => nme.UnliftHelper1 case DotDotDot => nme.UnliftHelper2 }
+ val lifter = inferUnliftable(tpe)
+ assert(helperName.isTermName)
+ // q"val $name: $u.build.${helperName.toTypeName} = $u.build.$helperName($lifter)"
+ ValDef(NoMods, name,
+ AppliedTypeTree(Select(Select(u, nme.build), helperName.toTypeName), List(TypeTree(tpe))),
+ Apply(Select(Select(u, nme.build), helperName), lifter :: Nil))
+ }
}
-} \ No newline at end of file
+}
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala
index 126c14ac81..6e6b617e5c 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Parsers.scala
@@ -161,7 +161,12 @@ trait Parsers { self: Quasiquotes =>
}
object TermParser extends Parser {
- def entryPoint = { parser => gen.mkTreeOrBlock(parser.templateOrTopStatSeq()) }
+ def entryPoint = { parser =>
+ parser.templateOrTopStatSeq() match {
+ case head :: Nil => Block(Nil, head)
+ case lst => gen.mkTreeOrBlock(lst)
+ }
+ }
}
object TypeParser extends Parser {
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala
index 54be9123c7..bdb44ad9a2 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Placeholders.scala
@@ -13,6 +13,7 @@ import scala.collection.{immutable, mutable}
trait Placeholders { self: Quasiquotes =>
import global._
import Cardinality._
+ import universeTypes._
// Step 1: Transform Scala source with holes into vanilla Scala source
@@ -32,13 +33,17 @@ trait Placeholders { self: Quasiquotes =>
def appendHole(tree: Tree, cardinality: Cardinality) = {
val placeholderName = c.freshName(TermName(nme.QUASIQUOTE_PREFIX + sessionSuffix))
sb.append(placeholderName)
- val holeTree = if (method == nme.unapply) Bind(placeholderName, Ident(nme.WILDCARD)) else tree
- holeMap(placeholderName) = Hole(holeTree, cardinality)
+ val holeTree =
+ if (method != nme.unapply) tree
+ else Bind(placeholderName, tree)
+ holeMap(placeholderName) = Hole(cardinality, holeTree)
}
val iargs = method match {
case nme.apply => args
- case nme.unapply => List.fill(parts.length - 1)(EmptyTree)
+ case nme.unapply =>
+ val (dummy @ Ident(nme.SELECTOR_DUMMY)) :: Nil = args
+ dummy.attachments.get[SubpatternsAttachment].get.patterns
case _ => global.abort("unreachable")
}
@@ -78,9 +83,9 @@ trait Placeholders { self: Quasiquotes =>
trait HolePlaceholder {
def matching: PartialFunction[Any, Name]
- def unapply(scrutinee: Any): Option[(Tree, Location, Cardinality)] = {
+ def unapply(scrutinee: Any): Option[Hole] = {
val name = matching.lift(scrutinee)
- name.flatMap { holeMap.get(_).map { case Hole(repr, loc, card) => (repr, loc, card) } }
+ name.flatMap { holeMap.get(_) }
}
}
@@ -128,44 +133,44 @@ trait Placeholders { self: Quasiquotes =>
}
object SymbolPlaceholder {
- def unapply(scrutinee: Any): Option[Tree] = scrutinee match {
- case Placeholder(tree, SymbolLocation, _) => Some(tree)
+ def unapply(scrutinee: Any): Option[Hole] = scrutinee match {
+ case Placeholder(hole: ApplyHole) if hole.tpe <:< symbolType => Some(hole)
case _ => None
}
}
object CasePlaceholder {
- def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match {
- case CaseDef(Apply(Ident(nme.QUASIQUOTE_CASE), List(Placeholder(tree, location, card))), EmptyTree, EmptyTree) => Some((tree, location, card))
+ def unapply(tree: Tree): Option[Hole] = tree match {
+ case CaseDef(Apply(Ident(nme.QUASIQUOTE_CASE), List(Placeholder(hole))), EmptyTree, EmptyTree) => Some(hole)
case _ => None
}
}
object RefineStatPlaceholder {
- def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match {
- case ValDef(_, Placeholder(tree, location, card), Ident(tpnme.QUASIQUOTE_REFINE_STAT), _) => Some((tree, location, card))
+ def unapply(tree: Tree): Option[Hole] = tree match {
+ case ValDef(_, Placeholder(hole), Ident(tpnme.QUASIQUOTE_REFINE_STAT), _) => Some(hole)
case _ => None
}
}
object EarlyDefPlaceholder {
- def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match {
- case ValDef(_, Placeholder(tree, location, card), Ident(tpnme.QUASIQUOTE_EARLY_DEF), _) => Some((tree, location, card))
+ def unapply(tree: Tree): Option[Hole] = tree match {
+ case ValDef(_, Placeholder(hole), Ident(tpnme.QUASIQUOTE_EARLY_DEF), _) => Some(hole)
case _ => None
}
}
object PackageStatPlaceholder {
- def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match {
- case ValDef(NoMods, Placeholder(tree, location, card), Ident(tpnme.QUASIQUOTE_PACKAGE_STAT), EmptyTree) => Some((tree, location, card))
+ def unapply(tree: Tree): Option[Hole] = tree match {
+ case ValDef(NoMods, Placeholder(hole), Ident(tpnme.QUASIQUOTE_PACKAGE_STAT), EmptyTree) => Some(hole)
case _ => None
}
}
object ForEnumPlaceholder {
- def unapply(tree: Tree): Option[(Tree, Location, Cardinality)] = tree match {
- case build.SyntacticValFrom(Bind(Placeholder(tree, location, card), Ident(nme.WILDCARD)), Ident(nme.QUASIQUOTE_FOR_ENUM)) =>
- Some((tree, location, card))
+ def unapply(tree: Tree): Option[Hole] = tree match {
+ case build.SyntacticValFrom(Bind(Placeholder(hole), Ident(nme.WILDCARD)), Ident(nme.QUASIQUOTE_FOR_ENUM)) =>
+ Some(hole)
case _ => None
}
}
diff --git a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
index b28c85cfc2..6d7aafe266 100644
--- a/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
+++ b/src/compiler/scala/tools/reflect/quasiquotes/Reifiers.scala
@@ -13,7 +13,7 @@ trait Reifiers { self: Quasiquotes =>
import Cardinality._
import universeTypes._
- abstract class Reifier extends {
+ abstract class Reifier(val isReifyingExpressions: Boolean) extends {
val global: self.global.type = self.global
val universe = self.universe
val reifee = EmptyTree
@@ -22,7 +22,6 @@ trait Reifiers { self: Quasiquotes =>
} with ReflectReifier {
lazy val typer = throw new UnsupportedOperationException
- def isReifyingExpressions: Boolean
def isReifyingPatterns: Boolean = !isReifyingExpressions
def action = if (isReifyingExpressions) "splice" else "extract"
def holesHaveTypes = isReifyingExpressions
@@ -94,12 +93,12 @@ trait Reifiers { self: Quasiquotes =>
// cq"$tree if $guard => $succ" :: cq"_ => $fail" :: Nil
CaseDef(tree, guard, succ) :: CaseDef(Ident(nme.WILDCARD), EmptyTree, fail) :: Nil
}
- // q"new { def unapply(tree: $AnyClass) = tree match { case ..$cases } }.unapply(..$args)"
+ // q"new { def unapply(tree: $AnyClass) = { ..${unlifters.preamble()}; tree match { case ..$cases } } }.unapply(..$args)"
Apply(
Select(
SyntacticNew(Nil, Nil, noSelfType, List(
DefDef(NoMods, nme.unapply, Nil, List(List(ValDef(NoMods, nme.tree, TypeTree(AnyClass.toType), EmptyTree))), TypeTree(),
- Match(Ident(nme.tree), cases)))),
+ SyntacticBlock(unlifters.preamble() :+ Match(Ident(nme.tree), cases))))),
nme.unapply),
args)
}
@@ -107,7 +106,7 @@ trait Reifiers { self: Quasiquotes =>
def reifyFillingHoles(tree: Tree): Tree = {
val reified = reifyTree(tree)
holeMap.unused.foreach { hole =>
- c.abort(holeMap(hole).tree.pos, s"Don't know how to $action here")
+ c.abort(holeMap(hole).pos, s"Don't know how to $action here")
}
wrap(reified)
}
@@ -117,21 +116,27 @@ trait Reifiers { self: Quasiquotes =>
reifyTreeSyntactically(tree)
def reifyTreePlaceholder(tree: Tree): Tree = tree match {
- case Placeholder(tree, TreeLocation(_), _) if isReifyingExpressions => tree
- case Placeholder(tree, _, NoDot) if isReifyingPatterns => tree
- case Placeholder(tree, _, card @ Dot()) => c.abort(tree.pos, s"Can't $action with $card here")
+ case Placeholder(hole: ApplyHole) if hole.tpe <:< treeType => hole.tree
+ case Placeholder(Hole(tree, NoDot)) if isReifyingPatterns => tree
+ case Placeholder(hole @ Hole(_, card @ Dot())) => c.abort(hole.pos, s"Can't $action with $card here")
case TuplePlaceholder(args) => reifyTuple(args)
case TupleTypePlaceholder(args) => reifyTupleType(args)
case FunctionTypePlaceholder(argtpes, restpe) => reifyFunctionType(argtpes, restpe)
- case CasePlaceholder(tree, location, _) => reifyCase(tree, location)
- case RefineStatPlaceholder(tree, _, _) => reifyRefineStat(tree)
- case EarlyDefPlaceholder(tree, _, _) => reifyEarlyDef(tree)
- case PackageStatPlaceholder(tree, _, _) => reifyPackageStat(tree)
- case ForEnumPlaceholder(tree, _, _) => tree
+ case CasePlaceholder(hole) => hole.tree
+ case RefineStatPlaceholder(hole) => reifyRefineStat(hole)
+ case EarlyDefPlaceholder(hole) => reifyEarlyDef(hole)
+ case PackageStatPlaceholder(hole) => reifyPackageStat(hole)
+ // for enumerators are checked not during splicing but during
+ // desugaring of the for loop in SyntacticFor & SyntacticForYield
+ case ForEnumPlaceholder(hole) => hole.tree
case _ => EmptyTree
}
override def reifyTreeSyntactically(tree: Tree) = tree match {
+ case RefTree(qual, SymbolPlaceholder(Hole(tree, _))) if isReifyingExpressions =>
+ mirrorBuildCall(nme.RefTree, reify(qual), tree)
+ case This(SymbolPlaceholder(Hole(tree, _))) if isReifyingExpressions =>
+ mirrorCall(nme.This, tree)
case SyntacticTraitDef(mods, name, tparams, earlyDefs, parents, selfdef, body) =>
reifyBuildCall(nme.SyntacticTraitDef, mods, name, tparams, earlyDefs, parents, selfdef, body)
case SyntacticClassDef(mods, name, tparams, constrmods, vparamss, earlyDefs, parents, selfdef, body) =>
@@ -161,17 +166,24 @@ trait Reifiers { self: Quasiquotes =>
reifyBuildCall(nme.SyntacticForYield, enums, body)
case SyntacticAssign(lhs, rhs) =>
reifyBuildCall(nme.SyntacticAssign, lhs, rhs)
- case SyntacticApplied(fun, List(args))
- if args.forall { case Placeholder(_, _, DotDotDot) => false case _ => true } =>
- reifyBuildCall(nme.SyntacticApply, fun, args)
case SyntacticApplied(fun, argss) if argss.nonEmpty =>
reifyBuildCall(nme.SyntacticApplied, fun, argss)
case SyntacticTypeApplied(fun, targs) if targs.nonEmpty =>
reifyBuildCall(nme.SyntacticTypeApplied, fun, targs)
case SyntacticFunction(args, body) =>
reifyBuildCall(nme.SyntacticFunction, args, body)
+ case SyntacticIdent(name, isBackquoted) =>
+ reifyBuildCall(nme.SyntacticIdent, name, isBackquoted)
+ case Block(Nil, Placeholder(Hole(tree, DotDot))) =>
+ mirrorBuildCall(nme.SyntacticBlock, tree)
+ case Block(Nil, other) =>
+ reifyTree(other)
case Block(stats, last) =>
reifyBuildCall(nme.SyntacticBlock, stats :+ last)
+ case Try(block, catches, finalizer) =>
+ reifyBuildCall(nme.SyntacticTry, block, catches, finalizer)
+ case Match(selector, cases) =>
+ reifyBuildCall(nme.SyntacticMatch, selector, cases)
// parser emits trees with scala package symbol to ensure
// that some names hygienically point to various scala package
// members; we need to preserve this symbol to preserve
@@ -183,9 +195,10 @@ trait Reifiers { self: Quasiquotes =>
}
override def reifyName(name: Name): Tree = name match {
- case Placeholder(tree, location, _) =>
- if (holesHaveTypes && !(location.tpe <:< nameType)) c.abort(tree.pos, s"$nameType expected but ${location.tpe} found")
- tree
+ case Placeholder(hole: ApplyHole) =>
+ if (!(hole.tpe <:< nameType)) c.abort(hole.pos, s"$nameType expected but ${hole.tpe} found")
+ hole.tree
+ case Placeholder(hole: UnapplyHole) => hole.treeNoUnlift
case FreshName(prefix) if prefix != nme.QUASIQUOTE_NAME_PREFIX =>
def fresh() = c.freshName[TermName](nme.QUASIQUOTE_NAME_PREFIX)
def introduceName() = { val n = fresh(); nameMap(name) += n; n}
@@ -196,15 +209,10 @@ trait Reifiers { self: Quasiquotes =>
super.reifyName(name)
}
- def reifyCase(tree: Tree, location: Location) = {
- if (holesHaveTypes && !(location.tpe <:< caseDefType)) c.abort(tree.pos, s"$caseDefType expected but ${location.tpe} found")
- tree
- }
-
def reifyTuple(args: List[Tree]) = args match {
case Nil => reify(Literal(Constant(())))
- case List(hole @ Placeholder(_, _, NoDot)) => reify(hole)
- case List(Placeholder(_, _, _)) => reifyBuildCall(nme.SyntacticTuple, args)
+ case List(hole @ Placeholder(Hole(_, NoDot))) => reify(hole)
+ case List(Placeholder(_)) => reifyBuildCall(nme.SyntacticTuple, args)
// in a case we only have one element tuple without
// any cardinality annotations this means that this is
// just an expression wrapped in parentheses
@@ -214,8 +222,8 @@ trait Reifiers { self: Quasiquotes =>
def reifyTupleType(args: List[Tree]) = args match {
case Nil => reify(Select(Ident(nme.scala_), tpnme.Unit))
- case List(hole @ Placeholder(_, _, NoDot)) => reify(hole)
- case List(Placeholder(_, _, _)) => reifyBuildCall(nme.SyntacticTupleType, args)
+ case List(hole @ Placeholder(Hole(_, NoDot))) => reify(hole)
+ case List(Placeholder(_)) => reifyBuildCall(nme.SyntacticTupleType, args)
case List(other) => reify(other)
case _ => reifyBuildCall(nme.SyntacticTupleType, args)
}
@@ -223,13 +231,18 @@ trait Reifiers { self: Quasiquotes =>
def reifyFunctionType(argtpes: List[Tree], restpe: Tree) =
reifyBuildCall(nme.SyntacticFunctionType, argtpes, restpe)
- def reifyRefineStat(tree: Tree) = tree
+ def reifyConstructionCheck(name: TermName, hole: Hole) = hole match {
+ case _: UnapplyHole => hole.tree
+ case _: ApplyHole => mirrorBuildCall(name, hole.tree)
+ }
+
+ def reifyRefineStat(hole: Hole) = reifyConstructionCheck(nme.mkRefineStat, hole)
- def reifyEarlyDef(tree: Tree) = tree
+ def reifyEarlyDef(hole: Hole) = reifyConstructionCheck(nme.mkEarlyDef, hole)
- def reifyAnnotation(tree: Tree) = tree
+ def reifyAnnotation(hole: Hole) = reifyConstructionCheck(nme.mkAnnotation, hole)
- def reifyPackageStat(tree: Tree) = tree
+ def reifyPackageStat(hole: Hole) = reifyConstructionCheck(nme.mkPackageStat, hole)
/** Splits list into a list of groups where subsequent elements are considered
* similar by the corresponding function.
@@ -262,7 +275,7 @@ trait Reifiers { self: Quasiquotes =>
*
* reifyMultiCardinalityList(lst) {
* // first we define patterns that extract high-cardinality holeMap (currently ..)
- * case Placeholder(CorrespondsTo(tree, tpe)) if tpe <:< iterableTreeType => tree
+ * case Placeholder(IterableType(_, _)) => tree
* } {
* // in the end we define how single elements are reified, typically with default reify call
* reify(_)
@@ -281,21 +294,22 @@ trait Reifiers { self: Quasiquotes =>
* elements.
*/
override def reifyList(xs: List[Any]): Tree = reifyMultiCardinalityList(xs) {
- case Placeholder(tree, _, DotDot) => tree
- case CasePlaceholder(tree, _, DotDot) => tree
- case RefineStatPlaceholder(tree, _, DotDot) => reifyRefineStat(tree)
- case EarlyDefPlaceholder(tree, _, DotDot) => reifyEarlyDef(tree)
- case PackageStatPlaceholder(tree, _, DotDot) => reifyPackageStat(tree)
- case ForEnumPlaceholder(tree, _, DotDot) => tree
- case List(Placeholder(tree, _, DotDotDot)) => tree
+ case Placeholder(Hole(tree, DotDot)) => tree
+ case CasePlaceholder(Hole(tree, DotDot)) => tree
+ case RefineStatPlaceholder(h @ Hole(_, DotDot)) => reifyRefineStat(h)
+ case EarlyDefPlaceholder(h @ Hole(_, DotDot)) => reifyEarlyDef(h)
+ case PackageStatPlaceholder(h @ Hole(_, DotDot)) => reifyPackageStat(h)
+ case ForEnumPlaceholder(Hole(tree, DotDot)) => tree
+ case List(Placeholder(Hole(tree, DotDotDot))) => tree
} {
reify(_)
}
def reifyAnnotList(annots: List[Tree]): Tree = reifyMultiCardinalityList(annots) {
- case AnnotPlaceholder(tree, _, DotDot) => reifyAnnotation(tree)
+ case AnnotPlaceholder(h @ Hole(_, DotDot)) => reifyAnnotation(h)
} {
- case AnnotPlaceholder(tree, UnknownLocation | TreeLocation(_), NoDot) => reifyAnnotation(tree)
+ case AnnotPlaceholder(h: ApplyHole) if h.tpe <:< treeType => reifyAnnotation(h)
+ case AnnotPlaceholder(h: UnapplyHole) if h.cardinality == NoDot => reifyAnnotation(h)
case other => reify(other)
}
@@ -321,78 +335,55 @@ trait Reifiers { self: Quasiquotes =>
override def mirrorBuildCall(name: TermName, args: Tree*): Tree =
Apply(Select(Select(universe, nme.build), name), args.toList)
- }
-
- class ApplyReifier extends Reifier {
- def isReifyingExpressions = true
- override def reifyTreeSyntactically(tree: Tree): Tree = tree match {
- case RefTree(qual, SymbolPlaceholder(tree)) =>
- mirrorBuildCall(nme.RefTree, reify(qual), tree)
- case This(SymbolPlaceholder(tree)) =>
- mirrorCall(nme.This, tree)
- case _ =>
- super.reifyTreeSyntactically(tree)
- }
+ override def scalaFactoryCall(name: String, args: Tree*): Tree =
+ call("scala." + name, args: _*)
+ }
- override def reifyMultiCardinalityList[T](xs: List[T])(fill: PartialFunction[T, Tree])(fallback: T => Tree): Tree = xs match {
- case Nil => mkList(Nil)
- case _ =>
+ class ApplyReifier extends Reifier(isReifyingExpressions = true) {
+ def reifyMultiCardinalityList[T](xs: List[T])(fill: PartialFunction[T, Tree])(fallback: T => Tree): Tree =
+ if (xs.isEmpty) mkList(Nil)
+ else {
def reifyGroup(group: List[T]): Tree = group match {
case List(elem) if fill.isDefinedAt(elem) => fill(elem)
case elems => mkList(elems.map(fallback))
}
val head :: tail = group(xs) { (a, b) => !fill.isDefinedAt(a) && !fill.isDefinedAt(b) }
tail.foldLeft[Tree](reifyGroup(head)) { (tree, lst) => Apply(Select(tree, nme.PLUSPLUS), List(reifyGroup(lst))) }
- }
+ }
override def reifyModifiers(m: Modifiers) =
if (m == NoMods) super.reifyModifiers(m)
else {
val (modsPlaceholders, annots) = m.annotations.partition {
- case ModsPlaceholder(_, _, _) => true
+ case ModsPlaceholder(_) => true
case _ => false
}
val (mods, flags) = modsPlaceholders.map {
- case ModsPlaceholder(tree, location, card) => (tree, location)
- }.partition { case (tree, location) =>
- location match {
- case ModsLocation => true
- case FlagsLocation => false
- case _ => c.abort(tree.pos, s"$flagsType or $modsType expected but ${tree.tpe} found")
- }
+ case ModsPlaceholder(hole: ApplyHole) => hole
+ }.partition { hole =>
+ if (hole.tpe <:< modsType) true
+ else if (hole.tpe <:< flagsType) false
+ else c.abort(hole.pos, s"$flagsType or $modsType expected but ${hole.tpe} found")
}
mods match {
- case (tree, _) :: Nil =>
- if (flags.nonEmpty) c.abort(flags(0)._1.pos, "Can't splice flags together with modifiers, consider merging flags into modifiers")
- if (annots.nonEmpty) c.abort(tree.pos, "Can't splice modifiers together with annotations, consider merging annotations into modifiers")
- ensureNoExplicitFlags(m, tree.pos)
- tree
- case _ :: (second, _) :: Nil =>
- c.abort(second.pos, "Can't splice multiple modifiers, consider merging them into a single modifiers instance")
+ case hole :: Nil =>
+ if (flags.nonEmpty) c.abort(flags(0).pos, "Can't splice flags together with modifiers, consider merging flags into modifiers")
+ if (annots.nonEmpty) c.abort(hole.pos, "Can't splice modifiers together with annotations, consider merging annotations into modifiers")
+ ensureNoExplicitFlags(m, hole.pos)
+ hole.tree
+ case _ :: hole :: Nil =>
+ c.abort(hole.pos, "Can't splice multiple modifiers, consider merging them into a single modifiers instance")
case _ =>
val baseFlags = reifyFlags(m.flags)
- val reifiedFlags = flags.foldLeft[Tree](baseFlags) { case (flag, (tree, _)) => Apply(Select(flag, nme.OR), List(tree)) }
+ val reifiedFlags = flags.foldLeft[Tree](baseFlags) { case (flag, hole) => Apply(Select(flag, nme.OR), List(hole.tree)) }
mirrorFactoryCall(nme.Modifiers, reifiedFlags, reify(m.privateWithin), reifyAnnotList(annots))
}
}
- override def reifyRefineStat(tree: Tree) = mirrorBuildCall(nme.mkRefineStat, tree)
-
- override def reifyEarlyDef(tree: Tree) = mirrorBuildCall(nme.mkEarlyDef, tree)
-
- override def reifyAnnotation(tree: Tree) = mirrorBuildCall(nme.mkAnnotation, tree)
-
- override def reifyPackageStat(tree: Tree) = mirrorBuildCall(nme.mkPackageStat, tree)
}
-
- class UnapplyReifier extends Reifier {
- def isReifyingExpressions = false
-
- override def scalaFactoryCall(name: String, args: Tree*): Tree =
- call("scala." + name, args: _*)
-
- override def reifyMultiCardinalityList[T](xs: List[T])(fill: PartialFunction[T, Tree])(fallback: T => Tree) = xs match {
+ class UnapplyReifier extends Reifier(isReifyingExpressions = false) {
+ def reifyMultiCardinalityList[T](xs: List[T])(fill: PartialFunction[T, Tree])(fallback: T => Tree): Tree = xs match {
case init :+ last if fill.isDefinedAt(last) =>
init.foldRight[Tree](fill(last)) { (el, rest) =>
val cons = Select(Select(Select(Ident(nme.scala_), nme.collection), nme.immutable), nme.CONS)
@@ -405,14 +396,14 @@ trait Reifiers { self: Quasiquotes =>
override def reifyModifiers(m: Modifiers) =
if (m == NoMods) super.reifyModifiers(m)
else {
- val mods = m.annotations.collect { case ModsPlaceholder(tree, _, _) => tree }
+ val mods = m.annotations.collect { case ModsPlaceholder(hole: UnapplyHole) => hole }
mods match {
- case tree :: Nil =>
- if (m.annotations.length != 1) c.abort(tree.pos, "Can't extract modifiers together with annotations, consider extracting just modifiers")
- ensureNoExplicitFlags(m, tree.pos)
- tree
- case _ :: second :: rest =>
- c.abort(second.pos, "Can't extract multiple modifiers together, consider extracting a single modifiers instance")
+ case hole :: Nil =>
+ if (m.annotations.length != 1) c.abort(hole.pos, "Can't extract modifiers together with annotations, consider extracting just modifiers")
+ ensureNoExplicitFlags(m, hole.pos)
+ hole.treeNoUnlift
+ case _ :: hole :: _ =>
+ c.abort(hole.pos, "Can't extract multiple modifiers together, consider extracting a single modifiers instance")
case Nil =>
mirrorFactoryCall(nme.Modifiers, reifyFlags(m.flags), reify(m.privateWithin), reifyAnnotList(m.annotations))
}
diff --git a/src/interactive/scala/tools/nsc/interactive/Global.scala b/src/interactive/scala/tools/nsc/interactive/Global.scala
index cab5137a87..27f10ff00a 100644
--- a/src/interactive/scala/tools/nsc/interactive/Global.scala
+++ b/src/interactive/scala/tools/nsc/interactive/Global.scala
@@ -1018,7 +1018,11 @@ class Global(settings: Settings, _reporter: Reporter, projectName: String = "")
val enclosing = new Members[ScopeMember]
def addScopeMember(sym: Symbol, pre: Type, viaImport: Tree) =
locals.add(sym, pre, implicitlyAdded = false) { (s, st) =>
- new ScopeMember(s, st, context.isAccessible(s, pre, superAccess = false), viaImport)
+ // imported val and var are always marked as inaccessible, but they could be accessed through their getters. SI-7995
+ if (s.hasGetter)
+ new ScopeMember(s, st, context.isAccessible(s.getter, pre, superAccess = false), viaImport)
+ else
+ new ScopeMember(s, st, context.isAccessible(s, pre, superAccess = false), viaImport)
}
def localsToEnclosing() = {
enclosing.addNonShadowed(locals)
diff --git a/src/library/scala/MatchError.scala b/src/library/scala/MatchError.scala
index 6ba7e833d3..9965bb19b5 100644
--- a/src/library/scala/MatchError.scala
+++ b/src/library/scala/MatchError.scala
@@ -23,9 +23,15 @@ final class MatchError(obj: Any) extends RuntimeException {
/** There's no reason we need to call toString eagerly,
* so defer it until getMessage is called.
*/
- private lazy val objString =
+ private lazy val objString = {
+ def ofClass = "of class " + obj.getClass.getName
if (obj == null) "null"
- else obj.toString() + " (of class " + obj.getClass.getName + ")"
+ else try {
+ obj.toString() + " (" + ofClass + ")"
+ } catch {
+ case _: Throwable => "an instance " + ofClass
+ }
+ }
override def getMessage() = objString
}
diff --git a/src/library/scala/collection/immutable/Queue.scala b/src/library/scala/collection/immutable/Queue.scala
index df1484c4ab..264304db68 100644
--- a/src/library/scala/collection/immutable/Queue.scala
+++ b/src/library/scala/collection/immutable/Queue.scala
@@ -89,6 +89,16 @@ class Queue[+A] protected(protected val in: List[A], protected val out: List[A])
*/
override def length = in.length + out.length
+ override def +:[B >: A, That](elem: B)(implicit bf: CanBuildFrom[Queue[A], B, That]): That = bf match {
+ case _: Queue.GenericCanBuildFrom[_] => new Queue(in, elem :: out).asInstanceOf[That]
+ case _ => super.+:(elem)(bf)
+ }
+
+ override def :+[B >: A, That](elem: B)(implicit bf: CanBuildFrom[Queue[A], B, That]): That = bf match {
+ case _: Queue.GenericCanBuildFrom[_] => enqueue(elem).asInstanceOf[That]
+ case _ => super.:+(elem)(bf)
+ }
+
/** Creates a new queue with element added at the end
* of the old queue.
*
@@ -118,7 +128,7 @@ class Queue[+A] protected(protected val in: List[A], protected val out: List[A])
case x :: xs => (x, new Queue(in, xs))
case _ => throw new NoSuchElementException("dequeue on empty queue")
}
-
+
/** Optionally retrieves the first element and a queue of the remaining elements.
*
* @return A tuple of the first element of the queue, and a new queue with this element removed.
diff --git a/src/reflect/scala/reflect/api/BuildUtils.scala b/src/reflect/scala/reflect/api/BuildUtils.scala
index cf05aefe72..9baf3ec179 100644
--- a/src/reflect/scala/reflect/api/BuildUtils.scala
+++ b/src/reflect/scala/reflect/api/BuildUtils.scala
@@ -122,19 +122,12 @@ private[reflect] trait BuildUtils { self: Universe =>
def unapply(tree: Tree): Some[(Tree, List[List[Tree]])]
}
- val SyntacticApply: SyntacticApplyExtractor
-
- trait SyntacticApplyExtractor {
- def apply(tree: Tree, args: List[Tree]): Tree
- def unapply(tree: Tree): Some[(Tree, List[Tree])]
- }
-
val SyntacticClassDef: SyntacticClassDefExtractor
trait SyntacticClassDefExtractor {
- def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef],
- constrMods: Modifiers, vparamss: List[List[ValDef]], earlyDefs: List[Tree],
- parents: List[Tree], selfType: ValDef, body: List[Tree]): ClassDef
+ def apply(mods: Modifiers, name: TypeName, tparams: List[Tree],
+ constrMods: Modifiers, vparamss: List[List[Tree]], earlyDefs: List[Tree],
+ parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef
def unapply(tree: Tree): Option[(Modifiers, TypeName, List[TypeDef], Modifiers, List[List[ValDef]],
List[Tree], List[Tree], ValDef, List[Tree])]
}
@@ -142,8 +135,8 @@ private[reflect] trait BuildUtils { self: Universe =>
val SyntacticTraitDef: SyntacticTraitDefExtractor
trait SyntacticTraitDefExtractor {
- def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef],
- earlyDefs: List[Tree], parents: List[Tree], selfType: ValDef, body: List[Tree]): ClassDef
+ def apply(mods: Modifiers, name: TypeName, tparams: List[Tree],
+ earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef
def unapply(tree: Tree): Option[(Modifiers, TypeName, List[TypeDef],
List[Tree], List[Tree], ValDef, List[Tree])]
}
@@ -152,7 +145,7 @@ private[reflect] trait BuildUtils { self: Universe =>
trait SyntacticObjectDefExtractor {
def apply(mods: Modifiers, name: TermName, earlyDefs: List[Tree],
- parents: List[Tree], selfType: ValDef, body: List[Tree]): Tree
+ parents: List[Tree], selfType: Tree, body: List[Tree]): Tree
def unapply(tree: Tree): Option[(Modifiers, TermName, List[Tree], List[Tree], ValDef, List[Tree])]
}
@@ -160,7 +153,7 @@ private[reflect] trait BuildUtils { self: Universe =>
trait SyntacticPackageObjectDefExtractor {
def apply(name: TermName, earlyDefs: List[Tree],
- parents: List[Tree], selfType: ValDef, body: List[Tree]): Tree
+ parents: List[Tree], selfType: Tree, body: List[Tree]): Tree
def unapply(tree: Tree): Option[(TermName, List[Tree], List[Tree], ValDef, List[Tree])]
}
@@ -182,7 +175,7 @@ private[reflect] trait BuildUtils { self: Universe =>
val SyntacticNew: SyntacticNewExtractor
trait SyntacticNewExtractor {
- def apply(earlyDefs: List[Tree], parents: List[Tree], selfType: ValDef, body: List[Tree]): Tree
+ def apply(earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): Tree
def unapply(tree: Tree): Option[(List[Tree], List[Tree], ValDef, List[Tree])]
}
@@ -196,7 +189,7 @@ private[reflect] trait BuildUtils { self: Universe =>
val SyntacticFunction: SyntacticFunctionExtractor
trait SyntacticFunctionExtractor {
- def apply(params: List[ValDef], body: Tree): Tree
+ def apply(params: List[Tree], body: Tree): Tree
def unapply(tree: Tree): Option[(List[ValDef], Tree)]
}
@@ -204,7 +197,7 @@ private[reflect] trait BuildUtils { self: Universe =>
val SyntacticDefDef: SyntacticDefDefExtractor
trait SyntacticDefDefExtractor {
- def apply(mods: Modifiers, name: TermName, tparams: List[Tree], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef
+ def apply(mods: Modifiers, name: TermName, tparams: List[Tree], vparamss: List[List[Tree]], tpt: Tree, rhs: Tree): DefDef
def unapply(tree: Tree): Option[(Modifiers, TermName, List[Tree], List[List[ValDef]], Tree, Tree)]
}
@@ -252,5 +245,33 @@ private[reflect] trait BuildUtils { self: Universe =>
def apply(enums: List[Tree], body: Tree): Tree
def unapply(tree: Tree): Option[(List[Tree], Tree)]
}
+
+ def UnliftHelper1[T](unliftable: Unliftable[T]): UnliftHelper1[T]
+ trait UnliftHelper1[T] {
+ def unapply(lst: List[Tree]): Option[List[T]]
+ }
+
+ def UnliftHelper2[T](unliftable: Unliftable[T]): UnliftHelper2[T]
+ trait UnliftHelper2[T] {
+ def unapply(lst: List[List[Tree]]): Option[List[List[T]]]
+ }
+
+ val SyntacticMatch: SyntacticMatchExtractor
+ trait SyntacticMatchExtractor {
+ def apply(selector: Tree, cases: List[Tree]): Match
+ def unapply(tree: Match): Option[(Tree, List[CaseDef])]
+ }
+
+ val SyntacticTry: SyntacticTryExtractor
+ trait SyntacticTryExtractor {
+ def apply(block: Tree, catches: List[Tree], finalizer: Tree): Try
+ def unapply(tree: Try): Option[(Tree, List[CaseDef], Tree)]
+ }
+
+ val SyntacticIdent: SyntacticIdentExtractor
+ trait SyntacticIdentExtractor {
+ def apply(name: Name, isBackquoted: Boolean = false): Ident
+ def unapply(tree: Ident): Option[(Name, Boolean)]
+ }
}
}
diff --git a/src/reflect/scala/reflect/api/Liftable.scala b/src/reflect/scala/reflect/api/Liftable.scala
deleted file mode 100644
index 8f6fe066dd..0000000000
--- a/src/reflect/scala/reflect/api/Liftable.scala
+++ /dev/null
@@ -1,32 +0,0 @@
-package scala.reflect
-package api
-
-trait Liftable[T] {
- def apply(universe: api.Universe, value: T): universe.Tree
-}
-
-object Liftable {
- private class LiftableConstant[T] extends Liftable[T] {
- def apply(universe: Universe, value: T): universe.Tree =
- universe.Literal(universe.Constant(value))
- }
-
- implicit lazy val liftByte: Liftable[Byte] = new LiftableConstant[Byte]
- implicit lazy val liftShort: Liftable[Short] = new LiftableConstant[Short]
- implicit lazy val liftChar: Liftable[Char] = new LiftableConstant[Char]
- implicit lazy val liftInt: Liftable[Int] = new LiftableConstant[Int]
- implicit lazy val liftLong: Liftable[Long] = new LiftableConstant[Long]
- implicit lazy val liftFloat: Liftable[Float] = new LiftableConstant[Float]
- implicit lazy val liftDouble: Liftable[Double] = new LiftableConstant[Double]
- implicit lazy val liftBoolean: Liftable[Boolean] = new LiftableConstant[Boolean]
- implicit lazy val liftString: Liftable[String] = new LiftableConstant[String]
- implicit lazy val liftUnit: Liftable[Unit] = new LiftableConstant[Unit]
-
- implicit lazy val liftScalaSymbol: Liftable[scala.Symbol] = new Liftable[scala.Symbol] {
- def apply(universe: Universe, value: scala.Symbol): universe.Tree = {
- import universe._
- val symbol = Select(Ident(TermName("scala")), TermName("Symbol"))
- Apply(symbol, List(Literal(Constant(value.name))))
- }
- }
-}
diff --git a/src/reflect/scala/reflect/api/StandardLiftables.scala b/src/reflect/scala/reflect/api/StandardLiftables.scala
index ecea550225..57464459be 100644
--- a/src/reflect/scala/reflect/api/StandardLiftables.scala
+++ b/src/reflect/scala/reflect/api/StandardLiftables.scala
@@ -2,35 +2,225 @@ package scala.reflect
package api
trait StandardLiftables { self: Universe =>
+ import build.{SyntacticTuple, ScalaDot}
- private def requireSameUniverse[T](universe: Universe, tp: String, value: T) =
- require(universe eq self, s"Can't lift $tp ${showRaw(value)} from universe ${showRaw(universe)} using lift$tp defined for ${showRaw(self)}.")
+ trait Liftable[T] {
+ def apply(value: T): Tree
+ }
+
+ object Liftable {
+ def apply[T](f: T => Tree): Liftable[T] =
+ new Liftable[T] { def apply(value: T): Tree = f(value) }
+
+ private def lift[T: Liftable](value: T): Tree = implicitly[Liftable[T]].apply(value)
+ private def selectScala(names: Name*) = names.tail.foldLeft(ScalaDot(names.head)) { Select(_, _) }
+ private def callScala(names: Name*)(args: List[Tree]) = Apply(selectScala(names: _*), args)
+ private def callCollection(name: Name)(args: List[Tree]) = callScala(nme.collection, nme.immutable, name)(args)
+ private def 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 liftExpr[T <: Expr[_]]: Liftable[T] = new Liftable[T] {
- def apply(universe: Universe, value: T): universe.Tree = {
- requireSameUniverse(universe, "Expr", value)
- value.tree.asInstanceOf[universe.Tree]
+ implicit def liftScalaSymbol: Liftable[scala.Symbol] = Liftable { v =>
+ callScala(nme.Symbol)(Literal(Constant(v.name)) :: Nil)
}
- }
- implicit def liftType[T <: Type]: Liftable[T] = new Liftable[T] {
- def apply(universe: Universe, value: T): universe.Tree = {
- requireSameUniverse(universe, "Type", value)
- universe.TypeTree(value.asInstanceOf[universe.Type])
+ implicit def liftName[T <: Name]: Liftable[T] = Liftable { name => Ident(name) }
+ implicit def liftExpr[T <: Expr[_]]: Liftable[T] = Liftable { expr => expr.tree }
+ implicit def liftType[T <: Type]: Liftable[T] = Liftable { tpe => TypeTree(tpe) }
+ implicit def liftTypeTag[T <: WeakTypeTag[_]]: Liftable[T] = Liftable { ttag => TypeTree(ttag.tpe) }
+ implicit def liftConstant[T <: Constant]: Liftable[T] = Liftable { const => Literal(const) }
+
+ implicit def liftArray[T: Liftable]: Liftable[Array[T]] = Liftable { arr => callScala(nme.Array)(arr.map(lift(_)).toList) }
+ implicit def liftVector[T: Liftable]: Liftable[Vector[T]] = Liftable { vect => callCollection(nme.Vector)(vect.map(lift(_)).toList) }
+ implicit def liftList[T: Liftable]: Liftable[List[T]] = Liftable { lst => callCollection(nme.List)(lst.map(lift(_))) }
+ implicit def 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 liftOption[T: Liftable]: Liftable[Option[T]] = Liftable {
+ case Some(v) => callScala(nme.Some)(lift(v) :: Nil)
+ case None => selectScala(nme.None)
+ }
+ 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)
}
- }
- implicit def liftTypeTag[T <: WeakTypeTag[_]]: Liftable[T] = new Liftable[T] {
- def apply(universe: Universe, value: T): universe.Tree = {
- requireSameUniverse(universe, "TypeTag", value)
- universe.TypeTree(value.asInstanceOf[universe.WeakTypeTag[_]].tpe)
+ implicit def liftTuple1[T1](implicit liftT1: Liftable[T1]): Liftable[Tuple1[T1]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: Nil)
+ }
+ implicit def liftTuple2[T1, T2](implicit liftT1: Liftable[T1], liftT2: Liftable[T2]): Liftable[Tuple2[T1, T2]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: Nil)
+ }
+ implicit def liftTuple3[T1, T2, T3](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3]): Liftable[Tuple3[T1, T2, T3]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: Nil)
+ }
+ implicit def liftTuple4[T1, T2, T3, T4](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4]): Liftable[Tuple4[T1, T2, T3, T4]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: Nil)
+ }
+ implicit def liftTuple5[T1, T2, T3, T4, T5](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5]): Liftable[Tuple5[T1, T2, T3, T4, T5]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: Nil)
+ }
+ implicit def liftTuple6[T1, T2, T3, T4, T5, T6](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6]): Liftable[Tuple6[T1, T2, T3, T4, T5, T6]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: Nil)
+ }
+ implicit def liftTuple7[T1, T2, T3, T4, T5, T6, T7](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7]): Liftable[Tuple7[T1, T2, T3, T4, T5, T6, T7]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: Nil)
+ }
+ implicit def liftTuple8[T1, T2, T3, T4, T5, T6, T7, T8](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8]): Liftable[Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: Nil)
+ }
+ implicit def liftTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9]): Liftable[Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: Nil)
+ }
+ implicit def liftTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10]): Liftable[Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: Nil)
+ }
+ implicit def liftTuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11]): Liftable[Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: Nil)
+ }
+ implicit def liftTuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12]): Liftable[Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: Nil)
+ }
+ implicit def liftTuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13]): Liftable[Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: Nil)
+ }
+ implicit def liftTuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14]): Liftable[Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: Nil)
+ }
+ implicit def liftTuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14], liftT15: Liftable[T15]): Liftable[Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: liftT15(t._15) :: Nil)
+ }
+ implicit def liftTuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14], liftT15: Liftable[T15], liftT16: Liftable[T16]): Liftable[Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: liftT15(t._15) :: liftT16(t._16) :: Nil)
+ }
+ implicit def liftTuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14], liftT15: Liftable[T15], liftT16: Liftable[T16], liftT17: Liftable[T17]): Liftable[Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: liftT15(t._15) :: liftT16(t._16) :: liftT17(t._17) :: Nil)
+ }
+ implicit def liftTuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14], liftT15: Liftable[T15], liftT16: Liftable[T16], liftT17: Liftable[T17], liftT18: Liftable[T18]): Liftable[Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: liftT15(t._15) :: liftT16(t._16) :: liftT17(t._17) :: liftT18(t._18) :: Nil)
+ }
+ implicit def liftTuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14], liftT15: Liftable[T15], liftT16: Liftable[T16], liftT17: Liftable[T17], liftT18: Liftable[T18], liftT19: Liftable[T19]): Liftable[Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: liftT15(t._15) :: liftT16(t._16) :: liftT17(t._17) :: liftT18(t._18) :: liftT19(t._19) :: Nil)
+ }
+ implicit def liftTuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14], liftT15: Liftable[T15], liftT16: Liftable[T16], liftT17: Liftable[T17], liftT18: Liftable[T18], liftT19: Liftable[T19], liftT20: Liftable[T20]): Liftable[Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: liftT15(t._15) :: liftT16(t._16) :: liftT17(t._17) :: liftT18(t._18) :: liftT19(t._19) :: liftT20(t._20) :: Nil)
+ }
+ implicit def liftTuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14], liftT15: Liftable[T15], liftT16: Liftable[T16], liftT17: Liftable[T17], liftT18: Liftable[T18], liftT19: Liftable[T19], liftT20: Liftable[T20], liftT21: Liftable[T21]): Liftable[Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: liftT15(t._15) :: liftT16(t._16) :: liftT17(t._17) :: liftT18(t._18) :: liftT19(t._19) :: liftT20(t._20) :: liftT21(t._21) :: Nil)
+ }
+ implicit def liftTuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](implicit liftT1: Liftable[T1], liftT2: Liftable[T2], liftT3: Liftable[T3], liftT4: Liftable[T4], liftT5: Liftable[T5], liftT6: Liftable[T6], liftT7: Liftable[T7], liftT8: Liftable[T8], liftT9: Liftable[T9], liftT10: Liftable[T10], liftT11: Liftable[T11], liftT12: Liftable[T12], liftT13: Liftable[T13], liftT14: Liftable[T14], liftT15: Liftable[T15], liftT16: Liftable[T16], liftT17: Liftable[T17], liftT18: Liftable[T18], liftT19: Liftable[T19], liftT20: Liftable[T20], liftT21: Liftable[T21], liftT22: Liftable[T22]): Liftable[Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]] = Liftable { t =>
+ SyntacticTuple(liftT1(t._1) :: liftT2(t._2) :: liftT3(t._3) :: liftT4(t._4) :: liftT5(t._5) :: liftT6(t._6) :: liftT7(t._7) :: liftT8(t._8) :: liftT9(t._9) :: liftT10(t._10) :: liftT11(t._11) :: liftT12(t._12) :: liftT13(t._13) :: liftT14(t._14) :: liftT15(t._15) :: liftT16(t._16) :: liftT17(t._17) :: liftT18(t._18) :: liftT19(t._19) :: liftT20(t._20) :: liftT21(t._21) :: liftT22(t._22) :: Nil)
}
}
- implicit def liftConstant[T <: Constant]: Liftable[T] = new Liftable[T] {
- def apply(universe: Universe, value: T): universe.Tree = {
- requireSameUniverse(universe, "Constant", value)
- universe.Literal(value.asInstanceOf[universe.Constant])
+ trait Unliftable[T] {
+ def unapply(tree: Tree): Option[T]
+ }
+
+ object Unliftable {
+ def apply[T](pf: PartialFunction[Tree, T]): Unliftable[T] = new Unliftable[T] {
+ def unapply(value: Tree): Option[T] = pf.lift(value)
+ }
+
+ private def unliftPrimitive[Unboxed: ClassTag, Boxed: ClassTag] = Unliftable[Unboxed] {
+ case Literal(Constant(value))
+ if value.getClass == implicitly[ClassTag[Boxed]].runtimeClass
+ || value.getClass == implicitly[ClassTag[Unboxed]].runtimeClass =>
+ value.asInstanceOf[Unboxed]
+ }
+ implicit def unliftByte: Unliftable[Byte] = unliftPrimitive[Byte, java.lang.Byte]
+ implicit def unliftShort: Unliftable[Short] = unliftPrimitive[Short, java.lang.Short]
+ implicit def unliftChar: Unliftable[Char] = unliftPrimitive[Char, java.lang.Character]
+ implicit def unliftInt: Unliftable[Int] = unliftPrimitive[Int, java.lang.Integer]
+ implicit def unliftLong: Unliftable[Long] = unliftPrimitive[Long, java.lang.Long]
+ implicit def unliftFloat: Unliftable[Float] = unliftPrimitive[Float, java.lang.Float]
+ implicit def unliftDouble: Unliftable[Double] = unliftPrimitive[Double, java.lang.Double]
+ implicit def unliftBoolean: Unliftable[Boolean] = unliftPrimitive[Boolean, java.lang.Boolean]
+ implicit def unliftUnit: Unliftable[Unit] = unliftPrimitive[Unit, scala.runtime.BoxedUnit]
+ implicit def unliftString: Unliftable[String] = Unliftable { case Literal(Constant(s: String)) => s }
+
+ implicit def unliftScalaSymbol: Unliftable[scala.Symbol] = Unliftable {
+ case Apply(ScalaDot(nme.Symbol), List(Literal(Constant(name: String)))) => scala.Symbol(name)
+ }
+
+ implicit def unliftName[T <: Name : ClassTag]: Unliftable[T] = Unliftable[T] { case Ident(name: T) => name; case Bind(name: T, Ident(nme.WILDCARD)) => name}
+ implicit def unliftType: Unliftable[Type] = Unliftable[Type] { case tt: TypeTree if tt.tpe != null => tt.tpe }
+ implicit def unliftConstant: Unliftable[Constant] = Unliftable[Constant] { case Literal(const) => const }
+
+ implicit def unliftTuple1[T1](implicit UnliftT1: Unliftable[T1]): Unliftable[Tuple1[T1]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: Nil) => Tuple1(v1)
+ }
+ implicit def unliftTuple2[T1, T2](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2]): Unliftable[Tuple2[T1, T2]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: Nil) => Tuple2(v1, v2)
+ }
+ implicit def unliftTuple3[T1, T2, T3](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3]): Unliftable[Tuple3[T1, T2, T3]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: Nil) => Tuple3(v1, v2, v3)
+ }
+ implicit def unliftTuple4[T1, T2, T3, T4](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4]): Unliftable[Tuple4[T1, T2, T3, T4]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: Nil) => Tuple4(v1, v2, v3, v4)
+ }
+ implicit def unliftTuple5[T1, T2, T3, T4, T5](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5]): Unliftable[Tuple5[T1, T2, T3, T4, T5]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: Nil) => Tuple5(v1, v2, v3, v4, v5)
+ }
+ implicit def unliftTuple6[T1, T2, T3, T4, T5, T6](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6]): Unliftable[Tuple6[T1, T2, T3, T4, T5, T6]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: Nil) => Tuple6(v1, v2, v3, v4, v5, v6)
+ }
+ implicit def unliftTuple7[T1, T2, T3, T4, T5, T6, T7](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7]): Unliftable[Tuple7[T1, T2, T3, T4, T5, T6, T7]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: Nil) => Tuple7(v1, v2, v3, v4, v5, v6, v7)
+ }
+ implicit def unliftTuple8[T1, T2, T3, T4, T5, T6, T7, T8](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8]): Unliftable[Tuple8[T1, T2, T3, T4, T5, T6, T7, T8]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: Nil) => Tuple8(v1, v2, v3, v4, v5, v6, v7, v8)
+ }
+ implicit def unliftTuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9]): Unliftable[Tuple9[T1, T2, T3, T4, T5, T6, T7, T8, T9]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: Nil) => Tuple9(v1, v2, v3, v4, v5, v6, v7, v8, v9)
+ }
+ implicit def unliftTuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10]): Unliftable[Tuple10[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: Nil) => Tuple10(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10)
+ }
+ implicit def unliftTuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11]): Unliftable[Tuple11[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: Nil) => Tuple11(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11)
+ }
+ implicit def unliftTuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12]): Unliftable[Tuple12[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: Nil) => Tuple12(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12)
+ }
+ implicit def unliftTuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13]): Unliftable[Tuple13[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: Nil) => Tuple13(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13)
+ }
+ implicit def unliftTuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14]): Unliftable[Tuple14[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: Nil) => Tuple14(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14)
+ }
+ implicit def unliftTuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14], UnliftT15: Unliftable[T15]): Unliftable[Tuple15[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: Nil) => Tuple15(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)
+ }
+ implicit def unliftTuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14], UnliftT15: Unliftable[T15], UnliftT16: Unliftable[T16]): Unliftable[Tuple16[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: UnliftT16(v16) :: Nil) => Tuple16(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16)
+ }
+ implicit def unliftTuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14], UnliftT15: Unliftable[T15], UnliftT16: Unliftable[T16], UnliftT17: Unliftable[T17]): Unliftable[Tuple17[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: UnliftT16(v16) :: UnliftT17(v17) :: Nil) => Tuple17(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17)
+ }
+ implicit def unliftTuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14], UnliftT15: Unliftable[T15], UnliftT16: Unliftable[T16], UnliftT17: Unliftable[T17], UnliftT18: Unliftable[T18]): Unliftable[Tuple18[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: UnliftT16(v16) :: UnliftT17(v17) :: UnliftT18(v18) :: Nil) => Tuple18(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18)
+ }
+ implicit def unliftTuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14], UnliftT15: Unliftable[T15], UnliftT16: Unliftable[T16], UnliftT17: Unliftable[T17], UnliftT18: Unliftable[T18], UnliftT19: Unliftable[T19]): Unliftable[Tuple19[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: UnliftT16(v16) :: UnliftT17(v17) :: UnliftT18(v18) :: UnliftT19(v19) :: Nil) => Tuple19(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19)
+ }
+ implicit def unliftTuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14], UnliftT15: Unliftable[T15], UnliftT16: Unliftable[T16], UnliftT17: Unliftable[T17], UnliftT18: Unliftable[T18], UnliftT19: Unliftable[T19], UnliftT20: Unliftable[T20]): Unliftable[Tuple20[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: UnliftT16(v16) :: UnliftT17(v17) :: UnliftT18(v18) :: UnliftT19(v19) :: UnliftT20(v20) :: Nil) => Tuple20(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20)
+ }
+ implicit def unliftTuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14], UnliftT15: Unliftable[T15], UnliftT16: Unliftable[T16], UnliftT17: Unliftable[T17], UnliftT18: Unliftable[T18], UnliftT19: Unliftable[T19], UnliftT20: Unliftable[T20], UnliftT21: Unliftable[T21]): Unliftable[Tuple21[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: UnliftT16(v16) :: UnliftT17(v17) :: UnliftT18(v18) :: UnliftT19(v19) :: UnliftT20(v20) :: UnliftT21(v21) :: Nil) => Tuple21(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21)
+ }
+ implicit def unliftTuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22](implicit UnliftT1: Unliftable[T1], UnliftT2: Unliftable[T2], UnliftT3: Unliftable[T3], UnliftT4: Unliftable[T4], UnliftT5: Unliftable[T5], UnliftT6: Unliftable[T6], UnliftT7: Unliftable[T7], UnliftT8: Unliftable[T8], UnliftT9: Unliftable[T9], UnliftT10: Unliftable[T10], UnliftT11: Unliftable[T11], UnliftT12: Unliftable[T12], UnliftT13: Unliftable[T13], UnliftT14: Unliftable[T14], UnliftT15: Unliftable[T15], UnliftT16: Unliftable[T16], UnliftT17: Unliftable[T17], UnliftT18: Unliftable[T18], UnliftT19: Unliftable[T19], UnliftT20: Unliftable[T20], UnliftT21: Unliftable[T21], UnliftT22: Unliftable[T22]): Unliftable[Tuple22[T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22]] = Unliftable {
+ case SyntacticTuple(UnliftT1(v1) :: UnliftT2(v2) :: UnliftT3(v3) :: UnliftT4(v4) :: UnliftT5(v5) :: UnliftT6(v6) :: UnliftT7(v7) :: UnliftT8(v8) :: UnliftT9(v9) :: UnliftT10(v10) :: UnliftT11(v11) :: UnliftT12(v12) :: UnliftT13(v13) :: UnliftT14(v14) :: UnliftT15(v15) :: UnliftT16(v16) :: UnliftT17(v17) :: UnliftT18(v18) :: UnliftT19(v19) :: UnliftT20(v20) :: UnliftT21(v21) :: UnliftT22(v22) :: Nil) => Tuple22(v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15, v16, v17, v18, v19, v20, v21, v22)
}
}
}
diff --git a/src/reflect/scala/reflect/api/StandardNames.scala b/src/reflect/scala/reflect/api/StandardNames.scala
index aec5f19fa0..4ea6ddc7f8 100644
--- a/src/reflect/scala/reflect/api/StandardNames.scala
+++ b/src/reflect/scala/reflect/api/StandardNames.scala
@@ -96,6 +96,20 @@ trait StandardNames {
* of non-private vals and vars are renamed using `LOCAL_SUFFIX_STRING`.
*/
val LOCAL_SUFFIX_STRING: String
+
+ protected[reflect] val Array: NameType
+ protected[reflect] val collection: NameType
+ protected[reflect] val immutable: NameType
+ protected[reflect] val Left: NameType
+ protected[reflect] val List: NameType
+ protected[reflect] val Map: NameType
+ protected[reflect] val None: NameType
+ protected[reflect] val Right: NameType
+ protected[reflect] val Set: NameType
+ protected[reflect] val Some: NameType
+ protected[reflect] val Symbol: NameType
+ protected[reflect] val util: NameType
+ protected[reflect] val Vector: NameType
}
/** Defines standard type names that can be accessed via the [[tpnme]] member.
diff --git a/src/reflect/scala/reflect/internal/BuildUtils.scala b/src/reflect/scala/reflect/internal/BuildUtils.scala
index 8fc1869dd2..13c2268227 100644
--- a/src/reflect/scala/reflect/internal/BuildUtils.scala
+++ b/src/reflect/scala/reflect/internal/BuildUtils.scala
@@ -71,12 +71,16 @@ trait BuildUtils { self: SymbolTable =>
def mkAnnotation(trees: List[Tree]): List[Tree] = trees.map(mkAnnotation)
- def mkVparamss(argss: List[List[ValDef]]): List[List[ValDef]] = argss.map(_.map(mkParam))
+ def mkVparamss(argss: List[List[Tree]]): List[List[ValDef]] = argss.map(_.map(mkParam))
- def mkParam(vd: ValDef): ValDef = {
- var newmods = (vd.mods | PARAM) & (~DEFERRED)
- if (vd.rhs.nonEmpty) newmods |= DEFAULTPARAM
- copyValDef(vd)(mods = newmods)
+ def mkParam(tree: Tree): ValDef = tree match {
+ case vd: ValDef =>
+ var newmods = (vd.mods | PARAM) & (~DEFERRED)
+ if (vd.rhs.nonEmpty) newmods |= DEFAULTPARAM
+ copyValDef(vd)(mods = newmods)
+ case _ =>
+ throw new IllegalArgumentException(s"$tree is not valid represenation of function parameter, " +
+ """consider reformatting it into q"val $name: $T = $default" shape""")
}
def mkTparams(tparams: List[Tree]): List[TypeDef] =
@@ -159,18 +163,11 @@ trait BuildUtils { self: SymbolTable =>
def apply(tree: Tree, argss: List[List[Tree]]): Tree =
argss.foldLeft(tree) { (f, args) => Apply(f, args.map(treeInfo.assignmentToMaybeNamedArg)) }
- def unapply(tree: Tree): Some[(Tree, List[List[Tree]])] = {
- val treeInfo.Applied(fun, targs, argss) = tree
- Some((SyntacticTypeApplied(fun, targs), argss))
- }
- }
-
- object SyntacticApply extends SyntacticApplyExtractor {
- def apply(tree: Tree, args: List[Tree]): Tree = SyntacticApplied(tree, List(args))
-
- def unapply(tree: Tree): Some[(Tree, List[Tree])] = tree match {
- case Apply(fun, args) => Some((fun, args))
- case other => Some((other, Nil))
+ def unapply(tree: Tree): Some[(Tree, List[List[Tree]])] = tree match {
+ case UnApply(treeInfo.Unapplied(Select(fun, nme.unapply)), pats) =>
+ Some((fun, pats :: Nil))
+ case treeInfo.Applied(fun, targs, argss) =>
+ Some((SyntacticTypeApplied(fun, targs), argss))
}
}
@@ -215,24 +212,41 @@ trait BuildUtils { self: SymbolTable =>
case Nil :: (tail @ ((head :: _) :: _)) if head.mods.isImplicit => tail
case other => other
}
- // undo flag modifications by mergeing flag info from constructor args and fieldDefs
+ // undo flag modifications by merging flag info from constructor args and fieldDefs
val modsMap = fieldDefs.map { case ValDef(mods, name, _, _) => name -> mods }.toMap
- val vparamss = mmap(vparamssRestoredImplicits) { vd =>
- val originalMods = modsMap(vd.name) | (vd.mods.flags & DEFAULTPARAM)
- atPos(vd.pos)(ValDef(originalMods, vd.name, vd.tpt, vd.rhs))
+ def ctorArgsCorrespondToFields = vparamssRestoredImplicits.flatten.forall { vd => modsMap.contains(vd.name) }
+ if (!ctorArgsCorrespondToFields) None
+ else {
+ val vparamss = mmap(vparamssRestoredImplicits) { vd =>
+ val originalMods = modsMap(vd.name) | (vd.mods.flags & DEFAULTPARAM)
+ atPos(vd.pos)(ValDef(originalMods, vd.name, vd.tpt, vd.rhs))
+ }
+ result(ctorMods, vparamss, edefs, body)
}
- result(ctorMods, vparamss, edefs, body)
}
}
}
}
+ protected def mkSelfType(tree: Tree) = tree match {
+ case vd: ValDef =>
+ require(vd.rhs.isEmpty, "self types must have empty right hand side")
+ copyValDef(vd)(mods = (vd.mods | PRIVATE) & (~DEFERRED))
+ case _ =>
+ throw new IllegalArgumentException(s"$tree is not a valid representation of self type, " +
+ """consider reformatting into q"val $self: $T" shape""")
+ }
+
object SyntacticClassDef extends SyntacticClassDefExtractor {
- def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef],
- constrMods: Modifiers, vparamss: List[List[ValDef]], earlyDefs: List[Tree],
- parents: List[Tree], selfType: ValDef, body: List[Tree]): ClassDef = {
+ def apply(mods: Modifiers, name: TypeName, tparams: List[Tree],
+ constrMods: Modifiers, vparamss: List[List[Tree]], earlyDefs: List[Tree],
+ parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef = {
val extraFlags = PARAMACCESSOR | (if (mods.isCase) CASEACCESSOR else 0L)
- val vparamss0 = vparamss.map { _.map { vd => copyValDef(vd)(mods = (vd.mods | extraFlags) & (~DEFERRED)) } }
+ val vparamss0 = vparamss.map { _.map {
+ case vd: ValDef => copyValDef(vd)(mods = (vd.mods | extraFlags) & (~DEFERRED))
+ case tree => throw new IllegalArgumentException(s"$tree is not valid representation of class parameter, " +
+ """consider reformatting it into q"val $name: $T = $default" shape""")
+ } }
val tparams0 = mkTparams(tparams)
val parents0 = gen.mkParents(mods,
if (mods.isCase) parents.filter {
@@ -241,7 +255,8 @@ trait BuildUtils { self: SymbolTable =>
} else parents
)
val body0 = earlyDefs ::: body
- val templ = gen.mkTemplate(parents0, selfType, constrMods, vparamss0, body0)
+ val selfType0 = mkSelfType(selfType)
+ val templ = gen.mkTemplate(parents0, selfType0, constrMods, vparamss0, body0)
gen.mkClassDef(mods, name, tparams0, templ)
}
@@ -256,10 +271,10 @@ trait BuildUtils { self: SymbolTable =>
}
object SyntacticTraitDef extends SyntacticTraitDefExtractor {
- def apply(mods: Modifiers, name: TypeName, tparams: List[TypeDef], earlyDefs: List[Tree],
- parents: List[Tree], selfType: ValDef, body: List[Tree]): ClassDef = {
+ def apply(mods: Modifiers, name: TypeName, tparams: List[Tree], earlyDefs: List[Tree],
+ parents: List[Tree], selfType: Tree, body: List[Tree]): ClassDef = {
val mods0 = mods | TRAIT | ABSTRACT
- val templ = gen.mkTemplate(parents, selfType, Modifiers(TRAIT), Nil, earlyDefs ::: body)
+ val templ = gen.mkTemplate(parents, mkSelfType(selfType), Modifiers(TRAIT), Nil, earlyDefs ::: body)
gen.mkClassDef(mods0, name, mkTparams(tparams), templ)
}
@@ -274,8 +289,8 @@ trait BuildUtils { self: SymbolTable =>
object SyntacticObjectDef extends SyntacticObjectDefExtractor {
def apply(mods: Modifiers, name: TermName, earlyDefs: List[Tree],
- parents: List[Tree], selfType: ValDef, body: List[Tree]) =
- ModuleDef(mods, name, gen.mkTemplate(parents, selfType, NoMods, Nil, earlyDefs ::: body))
+ parents: List[Tree], selfType: Tree, body: List[Tree]) =
+ ModuleDef(mods, name, gen.mkTemplate(parents, mkSelfType(selfType), NoMods, Nil, earlyDefs ::: body))
def unapply(tree: Tree): Option[(Modifiers, TermName, List[Tree], List[Tree], ValDef, List[Tree])] = tree match {
case ModuleDef(mods, name, UnMkTemplate(parents, selfType, _, _, earlyDefs, body)) =>
@@ -287,7 +302,7 @@ trait BuildUtils { self: SymbolTable =>
object SyntacticPackageObjectDef extends SyntacticPackageObjectDefExtractor {
def apply(name: TermName, earlyDefs: List[Tree],
- parents: List[Tree], selfType: ValDef, body: List[Tree]): Tree =
+ parents: List[Tree], selfType: Tree, body: List[Tree]): Tree =
gen.mkPackageObject(SyntacticObjectDef(NoMods, name, earlyDefs, parents, selfType, body))
def unapply(tree: Tree): Option[(TermName, List[Tree], List[Tree], ValDef, List[Tree])] = tree match {
@@ -377,11 +392,9 @@ trait BuildUtils { self: SymbolTable =>
}
object SyntacticFunction extends SyntacticFunctionExtractor {
- def apply(params: List[ValDef], body: Tree): Tree = {
- val params0 = params.map { arg =>
- require(arg.rhs.isEmpty, "anonymous functions don't support default values")
- mkParam(arg)
- }
+ def apply(params: List[Tree], body: Tree): Tree = {
+ val params0 :: Nil = mkVparamss(params :: Nil)
+ require(params0.forall { _.rhs.isEmpty }, "anonymous functions don't support parameters with default values")
Function(params0, body)
}
@@ -392,8 +405,8 @@ trait BuildUtils { self: SymbolTable =>
}
object SyntacticNew extends SyntacticNewExtractor {
- def apply(earlyDefs: List[Tree], parents: List[Tree], selfType: ValDef, body: List[Tree]): Tree =
- gen.mkNew(parents, selfType, earlyDefs ::: body, NoPosition, NoPosition)
+ def apply(earlyDefs: List[Tree], parents: List[Tree], selfType: Tree, body: List[Tree]): Tree =
+ gen.mkNew(parents, mkSelfType(selfType), earlyDefs ::: body, NoPosition, NoPosition)
def unapply(tree: Tree): Option[(List[Tree], List[Tree], ValDef, List[Tree])] = tree match {
case SyntacticApplied(Select(New(SyntacticTypeApplied(ident, targs)), nme.CONSTRUCTOR), argss) =>
@@ -407,7 +420,7 @@ trait BuildUtils { self: SymbolTable =>
}
object SyntacticDefDef extends SyntacticDefDefExtractor {
- def apply(mods: Modifiers, name: TermName, tparams: List[Tree], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef =
+ def apply(mods: Modifiers, name: TermName, tparams: List[Tree], vparamss: List[List[Tree]], tpt: Tree, rhs: Tree): DefDef =
DefDef(mods, name, mkTparams(tparams), mkVparamss(vparamss), tpt, rhs)
def unapply(tree: Tree): Option[(Modifiers, TermName, List[Tree], List[List[ValDef]], Tree, Tree)] = tree match {
@@ -442,6 +455,20 @@ trait BuildUtils { self: SymbolTable =>
}
}
+ def UnliftHelper1[T](unliftable: Unliftable[T]) = new UnliftHelper1[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 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
+ }
+ }
+
object SyntacticValFrom extends SyntacticValFromExtractor {
def apply(pat: Tree, rhs: Tree): Tree = gen.ValFrom(pat, gen.mkCheckIfRefutable(pat, rhs))
def unapply(tree: Tree): Option[(Tree, Tree)] = tree match {
@@ -672,6 +699,30 @@ trait BuildUtils { self: SymbolTable =>
case annottee => Some(annottee)
}
}
+
+ protected def mkCases(cases: List[Tree]): List[CaseDef] = cases.map {
+ case c: CaseDef => c
+ case tree => throw new IllegalArgumentException("$tree is not valid representation of pattern match case")
+ }
+
+ object SyntacticMatch extends SyntacticMatchExtractor {
+ def apply(selector: Tree, cases: List[Tree]) = Match(selector, mkCases(cases))
+ def unapply(tree: Match): Option[(Tree, List[CaseDef])] = Match.unapply(tree)
+ }
+
+ object SyntacticTry extends SyntacticTryExtractor {
+ def apply(block: Tree, catches: List[Tree], finalizer: Tree) = Try(block, mkCases(catches), finalizer)
+ def unapply(tree: Try): Option[(Tree, List[CaseDef], Tree)] = Try.unapply(tree)
+ }
+
+ object SyntacticIdent extends SyntacticIdentExtractor {
+ def apply(name: Name, isBackquoted: Boolean) = {
+ val id = self.Ident(name)
+ if (isBackquoted) id updateAttachment BackquotedIdentifierAttachment
+ id
+ }
+ def unapply(tree: Ident): Some[(Name, Boolean)] = Some((tree.name, tree.hasAttachment[BackquotedIdentifierAttachment.type]))
+ }
}
val build: BuildImpl = new BuildImpl
diff --git a/src/reflect/scala/reflect/internal/Definitions.scala b/src/reflect/scala/reflect/internal/Definitions.scala
index 19f06894c8..1fe6f249b8 100644
--- a/src/reflect/scala/reflect/internal/Definitions.scala
+++ b/src/reflect/scala/reflect/internal/Definitions.scala
@@ -481,7 +481,6 @@ 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 LiftableClass = getClassIfDefined("scala.reflect.api.Liftable") // 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))
@@ -1371,6 +1370,8 @@ trait Definitions extends api.StandardDefinitions {
lazy val symbolType = universeMemberType(tpnme.Symbol)
lazy val treeType = universeMemberType(tpnme.Tree)
lazy val caseDefType = universeMemberType(tpnme.CaseDef)
+ lazy val liftableType = universeMemberType(tpnme.Liftable)
+ lazy val unliftableType = universeMemberType(tpnme.Unliftable)
lazy val iterableTreeType = appliedType(IterableClass, treeType)
lazy val listTreeType = appliedType(ListClass, treeType)
lazy val listListTreeType = appliedType(ListClass, listTreeType)
diff --git a/src/reflect/scala/reflect/internal/StdAttachments.scala b/src/reflect/scala/reflect/internal/StdAttachments.scala
index 46f241643b..09fd996f39 100644
--- a/src/reflect/scala/reflect/internal/StdAttachments.scala
+++ b/src/reflect/scala/reflect/internal/StdAttachments.scala
@@ -35,4 +35,7 @@ trait StdAttachments {
/** Identifies trees are either result or intermidiate value of for loop desugaring.
*/
case object ForAttachment extends PlainAttachment
+
+ /** Untyped list of subpatterns attached to selector dummy. */
+ case class SubpatternsAttachment(patterns: List[Tree])
}
diff --git a/src/reflect/scala/reflect/internal/StdNames.scala b/src/reflect/scala/reflect/internal/StdNames.scala
index c26e815df1..5ad2b15e8c 100644
--- a/src/reflect/scala/reflect/internal/StdNames.scala
+++ b/src/reflect/scala/reflect/internal/StdNames.scala
@@ -124,8 +124,15 @@ trait StdNames {
final val AnyRef: NameType = "AnyRef"
final val Array: NameType = "Array"
final val List: NameType = "List"
+ final val Left: NameType = "Left"
+ final val Right: NameType = "Right"
+ final val Vector: NameType = "Vector"
final val Seq: NameType = "Seq"
+ final val Set: NameType = "Set"
+ final val Some: NameType = "Some"
final val Symbol: NameType = "Symbol"
+ final val Map: NameType = "Map"
+ final val None: NameType = "None"
final val WeakTypeTag: NameType = "WeakTypeTag"
final val TypeTag : NameType = "TypeTag"
final val Expr: NameType = "Expr"
@@ -239,6 +246,8 @@ trait StdNames {
final val Enum: NameType = "Enum"
final val Group: NameType = "Group"
final val implicitNotFound: NameType = "implicitNotFound"
+ final val Liftable: NameType = "Liftable"
+ final val Unliftable: NameType = "Unliftable"
final val Name: NameType = "Name"
final val Tree: NameType = "Tree"
final val TermName: NameType = "TermName"
@@ -328,6 +337,7 @@ trait StdNames {
val QUASIQUOTE_TUPLE: NameType = "$quasiquote$tuple$"
val QUASIQUOTE_CASE: NameType = "$quasiquote$case$"
val QUASIQUOTE_FOR_ENUM: NameType = "$quasiquote$for$enum$"
+ val QUASIQUOTE_UNLIFT_HELPER: String = "$quasiquote$unlift$helper$"
val MIXIN_CONSTRUCTOR: NameType = "$init$"
val MODULE_INSTANCE_FIELD: NameType = NameTransformer.MODULE_INSTANCE_NAME // "MODULE$"
val OUTER: NameType = "$outer"
@@ -588,7 +598,6 @@ trait StdNames {
val Select: NameType = "Select"
val SelectFromTypeTree: NameType = "SelectFromTypeTree"
val SyntacticApplied: NameType = "SyntacticApplied"
- val SyntacticApply: NameType = "SyntacticApply"
val SyntacticAssign: NameType = "SyntacticAssign"
val SyntacticBlock: NameType = "SyntacticBlock"
val SyntacticClassDef: NameType = "SyntacticClassDef"
@@ -598,10 +607,13 @@ trait StdNames {
val SyntacticForYield: NameType = "SyntacticForYield"
val SyntacticFunction: NameType = "SyntacticFunction"
val SyntacticFunctionType: NameType = "SyntacticFunctionType"
- val SyntacticPackageObjectDef: NameType = "SyntacticPackageObjectDef"
- val SyntacticObjectDef: NameType = "SyntacticObjectDef"
+ val SyntacticIdent: NameType = "SyntacticIdent"
+ val SyntacticMatch: NameType = "SyntacticMatch"
val SyntacticNew: NameType = "SyntacticNew"
+ val SyntacticObjectDef: NameType = "SyntacticObjectDef"
+ val SyntacticPackageObjectDef: NameType = "SyntacticPackageObjectDef"
val SyntacticTraitDef: NameType = "SyntacticTraitDef"
+ val SyntacticTry: NameType = "SyntacticTry"
val SyntacticTuple: NameType = "SyntacticTuple"
val SyntacticTupleType: NameType = "SyntacticTupleType"
val SyntacticTypeApplied: NameType = "SyntacticTypeApplied"
@@ -751,10 +763,13 @@ trait StdNames {
val typedProductIterator: NameType = "typedProductIterator"
val TypeName: NameType = "TypeName"
val typeTagToManifest: NameType = "typeTagToManifest"
+ val util: NameType = "util"
val unapply: NameType = "unapply"
val unapplySeq: NameType = "unapplySeq"
val unbox: NameType = "unbox"
val universe: NameType = "universe"
+ val UnliftHelper1: NameType = "UnliftHelper1"
+ val UnliftHelper2: NameType = "UnliftHelper2"
val update: NameType = "update"
val updateDynamic: NameType = "updateDynamic"
val value: NameType = "value"
@@ -784,7 +799,7 @@ trait StdNames {
final val STAR : NameType = "*"
final val TILDE: NameType = "~"
- final val isUnary: Set[Name] = Set(MINUS, PLUS, TILDE, BANG)
+ final val isUnary: Set[Name] = scala.collection.immutable.Set(MINUS, PLUS, TILDE, BANG)
}
// value-conversion methods
@@ -837,8 +852,8 @@ trait StdNames {
val UNARY_! = encode("unary_!")
// Grouped here so Cleanup knows what tests to perform.
- val CommonOpNames = Set[Name](OR, XOR, AND, EQ, NE)
- val BooleanOpNames = Set[Name](ZOR, ZAND, UNARY_!) ++ CommonOpNames
+ val CommonOpNames = scala.collection.immutable.Set[Name](OR, XOR, AND, EQ, NE)
+ val BooleanOpNames = scala.collection.immutable.Set[Name](ZOR, ZAND, UNARY_!) ++ CommonOpNames
val add: NameType = "add"
val complement: NameType = "complement"
diff --git a/src/reflect/scala/reflect/internal/Symbols.scala b/src/reflect/scala/reflect/internal/Symbols.scala
index 85bc3158f6..0dfcf06874 100644
--- a/src/reflect/scala/reflect/internal/Symbols.scala
+++ b/src/reflect/scala/reflect/internal/Symbols.scala
@@ -1379,6 +1379,13 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
def hasRawInfo: Boolean = infos ne null
def hasCompleteInfo = hasRawInfo && rawInfo.isComplete
+ // does not run adaptToNewRun, which is prone to trigger cycles (SI-8029)
+ // TODO: give this a better name if you understand the intent of the caller.
+ // Is it something to do with `reallyExists` or `isStale`?
+ final def rawInfoIsNoType: Boolean = {
+ hasRawInfo && (infos.info eq NoType)
+ }
+
/** Return info without checking for initialization or completing */
def rawInfo: Type = {
var infos = this.infos
@@ -2038,7 +2045,7 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** Is this symbol defined in the same scope and compilation unit as `that` symbol? */
def isCoDefinedWith(that: Symbol) = (
- (this.rawInfo ne NoType)
+ !rawInfoIsNoType
&& (this.effectiveOwner == that.effectiveOwner)
&& ( !this.effectiveOwner.isPackageClass
|| (this.associatedFile eq NoAbstractFile)
@@ -2475,10 +2482,14 @@ trait Symbols extends api.Symbols { self: SymbolTable =>
/** String representation, including symbol's kind e.g., "class Foo", "method Bar".
* If hasMeaninglessName is true, uses the owner's name to disambiguate identity.
*/
- override def toString: String = compose(
- kindString,
- if (hasMeaninglessName) owner.decodedName + idString else nameString
- )
+ override def toString: String = {
+ if (isPackageObjectOrClass && !settings.debug)
+ s"package object ${owner.decodedName}"
+ else compose(
+ kindString,
+ if (hasMeaninglessName) owner.decodedName + idString else nameString
+ )
+ }
/** String representation of location.
*/
diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala
index e483fa6ba8..99e6ae633f 100644
--- a/src/reflect/scala/reflect/internal/Types.scala
+++ b/src/reflect/scala/reflect/internal/Types.scala
@@ -3392,11 +3392,14 @@ trait Types
/** Rebind symbol `sym` to an overriding member in type `pre`. */
private def rebind(pre: Type, sym: Symbol): Symbol = {
if (!sym.isOverridableMember || sym.owner == pre.typeSymbol) sym
- else pre.nonPrivateMember(sym.name).suchThat(sym =>
- // SI-7928 `isModuleNotMethod` is here to avoid crashing with overloaded module accessor and module symbols
- // after refchecks eliminates a ModuleDef that implements and interface.
- sym.isType || (!sym.isModuleNotMethod && sym.isStable && !sym.hasVolatileType)
- ) orElse sym
+ else pre.nonPrivateMember(sym.name).suchThat { sym =>
+ // SI-7928 `isModuleNotMethod` is here to avoid crashing with spuriously "overloaded" module accessor and module symbols.
+ // These appear after refchecks eliminates ModuleDefs that implement an interface.
+ // Here, we exclude the module symbol, which allows us to bind to the accessor.
+ // SI-8054 We must only do this after refchecks, otherwise we exclude the module symbol which does not yet have an accessor!
+ val isModuleWithAccessor = phase.refChecked && sym.isModuleNotMethod
+ sym.isType || (!isModuleWithAccessor && sym.isStable && !sym.hasVolatileType)
+ } orElse sym
}
/** Convert a `super` prefix to a this-type if `sym` is abstract or final. */
diff --git a/src/reflect/scala/reflect/internal/util/StringOps.scala b/src/reflect/scala/reflect/internal/util/StringOps.scala
index 14f349f502..efb8126ff0 100644
--- a/src/reflect/scala/reflect/internal/util/StringOps.scala
+++ b/src/reflect/scala/reflect/internal/util/StringOps.scala
@@ -23,12 +23,16 @@ trait StringOps {
def oempty(xs: String*) = xs filterNot (x => x == null || x == "")
def ojoin(xs: String*): String = oempty(xs: _*) mkString " "
def longestCommonPrefix(xs: List[String]): String = xs match {
- case Nil => ""
- case xs if xs contains "" => ""
- case x :: xs =>
- val ch = x charAt 0
- if (xs exists (_.head != ch)) ""
- else "" + ch + longestCommonPrefix(xs map (_ substring 1))
+ case Nil => ""
+ case w :: Nil => w
+ case _ =>
+ def lcp(ss: List[String]): String = {
+ val w :: ws = ss
+ if (w == "") ""
+ else if (ws exists (s => s == "" || (s charAt 0) != (w charAt 0))) ""
+ else w.substring(0, 1) + lcp(ss map (_ substring 1))
+ }
+ lcp(xs)
}
/** Like String#trim, but trailing whitespace only.
*/
diff --git a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
index 344f7682c1..0f41506382 100644
--- a/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
+++ b/src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
@@ -57,6 +57,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.CompoundTypeTreeOriginalAttachment
this.BackquotedIdentifierAttachment
this.ForAttachment
+ this.SubpatternsAttachment
this.noPrint
this.typeDebug
// inaccessible: this.maxFree
@@ -204,6 +205,8 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.TermName
this.TypeName
this.BooleanFlag
+ this.Liftable
+ this.Unliftable
this.WeakTypeTag
this.TypeTag
this.Expr
@@ -315,7 +318,6 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
definitions.MirrorClass
definitions.TypeCreatorClass
definitions.TreeCreatorClass
- definitions.LiftableClass
definitions.BlackboxMacroClass
definitions.WhiteboxMacroClass
definitions.BlackboxContextClass
diff --git a/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala b/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala
index 1b3d60d41a..53c7c82e89 100644
--- a/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala
+++ b/src/repl/scala/tools/nsc/interpreter/JLineCompletion.scala
@@ -294,7 +294,7 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
// This is jline's entry point for completion.
override def complete(buf: String, cursor: Int): Candidates = {
verbosity = if (isConsecutiveTabs(buf, cursor)) verbosity + 1 else 0
- repldbg("\ncomplete(%s, %d) last = (%s, %d), verbosity: %s".format(buf, cursor, lastBuf, lastCursor, verbosity))
+ repldbg(f"%ncomplete($buf, $cursor%d) last = ($lastBuf, $lastCursor%d), verbosity: $verbosity")
// we don't try lower priority completions unless higher ones return no results.
def tryCompletion(p: Parsed, completionFunction: Parsed => List[String]): Option[Candidates] = {
@@ -307,8 +307,7 @@ class JLineCompletion(val intp: IMain) extends Completion with CompletionOutput
val advance = longestCommonPrefix(winners)
lastCursor = p.position + advance.length
lastBuf = (buf take p.position) + advance
- repldbg("tryCompletion(%s, _) lastBuf = %s, lastCursor = %s, p.position = %s".format(
- p, lastBuf, lastCursor, p.position))
+ repldbg(s"tryCompletion($p, _) lastBuf = $lastBuf, lastCursor = $lastCursor, p.position = ${p.position}")
p.position
}
diff --git a/src/swing/scala/swing/Publisher.scala b/src/swing/scala/swing/Publisher.scala
index 96207de808..578ef71e09 100644
--- a/src/swing/scala/swing/Publisher.scala
+++ b/src/swing/scala/swing/Publisher.scala
@@ -44,7 +44,7 @@ trait Publisher extends Reactor {
/**
* Notify all registered reactions.
*/
- def publish(e: Event) { for (l <- listeners) l(e) }
+ def publish(e: Event) { for (l <- listeners) if (l.isDefinedAt(e)) l(e) }
listenTo(this)
}