Skip to content

Commit

Permalink
Move Liftable into the Universe cake; add additional standard Liftables
Browse files Browse the repository at this point in the history
Previously we believed that having Liftable outside of the Universe will
bring some advantages but it turned out this wasn’t worth it. Due to
infectious nature of path dependent types inside of the universe one
had to cast a lot. A nice example of what I’m talking about is a change
in trait ArbitraryTreesAndNames.

Additionally a number of standard Liftables is added for types that are
available through Predef and/or default scala._ import: Array, Vector,
List, Map, Set, Option, Either, TupleN.
  • Loading branch information
densh committed Dec 10, 2013
1 parent 26a3348 commit f3c260b
Show file tree
Hide file tree
Showing 10 changed files with 153 additions and 80 deletions.
4 changes: 2 additions & 2 deletions src/compiler/scala/tools/reflect/quasiquotes/Holes.scala
Expand Up @@ -80,10 +80,10 @@ trait Holes { self: Quasiquotes =>
def cardinality(tpe: Type): Cardinality = parseCardinality(tpe)._1

def lifter(tpe: Type): Option[Tree => Tree] = {
val lifterTpe = appliedType(LiftableClass.toType, List(tpe))
val lifterTpe = appliedType(liftableType, List(tpe))
val lifter = c.inferImplicitValue(lifterTpe, silent = true)
if (lifter != EmptyTree) Some(tree => {
val lifted = Apply(lifter, List(u, tree))
val lifted = Apply(lifter, List(tree))
val targetType = Select(u, tpnme.Tree)
atPos(tree.pos)(TypeApply(Select(lifted, nme.asInstanceOf_), List(targetType)))
}) else None
Expand Down
32 changes: 0 additions & 32 deletions src/reflect/scala/reflect/api/Liftable.scala

This file was deleted.

132 changes: 110 additions & 22 deletions src/reflect/scala/reflect/api/StandardLiftables.scala

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions src/reflect/scala/reflect/api/StandardNames.scala
Expand Up @@ -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.
Expand Down
3 changes: 2 additions & 1 deletion src/reflect/scala/reflect/internal/Definitions.scala
Expand Up @@ -481,7 +481,7 @@ 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 LiftableClass = NoSymbol

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))
Expand Down Expand Up @@ -1371,6 +1371,7 @@ 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 iterableTreeType = appliedType(IterableClass, treeType)
lazy val listTreeType = appliedType(ListClass, treeType)
lazy val listListTreeType = appliedType(ListClass, listTreeType)
Expand Down
15 changes: 12 additions & 3 deletions src/reflect/scala/reflect/internal/StdNames.scala
Expand Up @@ -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"
Expand Down Expand Up @@ -239,6 +246,7 @@ trait StdNames {
final val Enum: NameType = "Enum"
final val Group: NameType = "Group"
final val implicitNotFound: NameType = "implicitNotFound"
final val Liftable: NameType = "Liftable"
final val Name: NameType = "Name"
final val Tree: NameType = "Tree"
final val TermName: NameType = "TermName"
Expand Down Expand Up @@ -753,6 +761,7 @@ 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"
Expand Down Expand Up @@ -786,7 +795,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
Expand Down Expand Up @@ -839,8 +848,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"
Expand Down
1 change: 1 addition & 0 deletions src/reflect/scala/reflect/runtime/JavaUniverseForce.scala
Expand Up @@ -204,6 +204,7 @@ trait JavaUniverseForce { self: runtime.JavaUniverse =>
this.TermName
this.TypeName
this.BooleanFlag
this.Liftable
this.WeakTypeTag
this.TypeTag
this.Expr
Expand Down
17 changes: 7 additions & 10 deletions test/files/pos/macro-implicit-invalidate-on-error.scala
@@ -1,23 +1,20 @@
package scala.reflect
package api

import scala.language.experimental.macros
import scala.reflect.macros.Context

trait Liftable[T] {
def apply(universe: api.Universe, value: T): universe.Tree
trait LegacyLiftable[T] {
def apply(universe: scala.reflect.api.Universe, value: T): universe.Tree
}

object Liftable {
implicit def liftCaseClass[T <: Product]: Liftable[T] = macro liftCaseClassImpl[T]
object LegacyLiftable {
implicit def liftCaseClass[T <: Product]: LegacyLiftable[T] = macro liftCaseClassImpl[T]

def liftCaseClassImpl[T: c.WeakTypeTag](c: Context): c.Expr[Liftable[T]] = {
def liftCaseClassImpl[T: c.WeakTypeTag](c: Context): c.Expr[LegacyLiftable[T]] = {
import c.universe._
val tpe = weakTypeOf[T]
if (!tpe.typeSymbol.asClass.isCaseClass) c.abort(c.enclosingPosition, "denied")
val p = List(q"Literal(Constant(1))")
c.Expr[Liftable[T]] { q"""
new scala.reflect.api.Liftable[$tpe] {
c.Expr[LegacyLiftable[T]] { q"""
new LegacyLiftable[$tpe] {
def apply(universe: scala.reflect.api.Universe, value: $tpe): universe.Tree = {
import universe._
Apply(Select(Ident(TermName("C")), TermName("apply")), List(..$p))
Expand Down
11 changes: 2 additions & 9 deletions test/files/scalacheck/quasiquotes/ArbitraryTreesAndNames.scala
@@ -1,5 +1,4 @@
import org.scalacheck._, Prop._, Gen._, Arbitrary._
import scala.reflect.api.{Liftable, Universe}
import scala.reflect.runtime.universe._, Flag._

trait ArbitraryTreesAndNames {
Expand Down Expand Up @@ -265,14 +264,8 @@ trait ArbitraryTreesAndNames {
def genTreeIsTypeWrapped(size: Int) =
for(tit <- genTreeIsType(size)) yield TreeIsType(tit)

implicit object liftTreeIsTerm extends Liftable[TreeIsTerm] {
def apply(universe: Universe, value: TreeIsTerm): universe.Tree =
value.tree.asInstanceOf[universe.Tree]
}
implicit object liftTreeIsType extends Liftable[TreeIsType] {
def apply(universe: Universe, value: TreeIsType): universe.Tree =
value.tree.asInstanceOf[universe.Tree]
}
implicit val liftTreeIsTerm = Liftable[TreeIsTerm] { _.tree }
implicit val liftTreeIsType = Liftable[TreeIsType] { _.tree }
implicit def treeIsTerm2tree(tit: TreeIsTerm): Tree = tit.tree
implicit def treeIsType2tree(tit: TreeIsType): Tree = tit.tree

Expand Down
4 changes: 3 additions & 1 deletion test/files/scalacheck/quasiquotes/QuasiquoteProperties.scala
Expand Up @@ -120,4 +120,6 @@ trait Helpers {
def annot(name: TypeName): Tree = annot(name, Nil)
def annot(name: String, args: List[Tree]): Tree = annot(TypeName(name), args)
def annot(name: TypeName, args: List[Tree]): Tree = q"new $name(..$args)"
}

val scalapkg = build.setSymbol(Ident(TermName("scala")), definitions.ScalaPackage)
}

0 comments on commit f3c260b

Please sign in to comment.