Skip to content

Replace scala.quoted.qctx with scala.quoted.reflect #10289

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,20 @@ import scala.quoted._

object Extractors {

def showTree(using QuoteContext)(tree: qctx.reflect.Tree): String =
def showTree(using qctx: QuoteContext)(tree: reflect.Tree): String =
new ExtractorsPrinter[qctx.type]().visitTree(tree).result()

def showType(using QuoteContext)(tpe: qctx.reflect.TypeRepr): String =
def showType(using qctx: QuoteContext)(tpe: reflect.TypeRepr): String =
new ExtractorsPrinter[qctx.type]().visitType(tpe).result()

def showConstant(using QuoteContext)(const: qctx.reflect.Constant): String =
def showConstant(using qctx: QuoteContext)(const: reflect.Constant): String =
new ExtractorsPrinter[qctx.type]().visitConstant(const).result()

def showSymbol(using QuoteContext)(symbol: qctx.reflect.Symbol): String =
def showSymbol(using qctx: QuoteContext)(symbol: reflect.Symbol): String =
new ExtractorsPrinter[qctx.type]().visitSymbol(symbol).result()

def showFlags(using QuoteContext)(flags: qctx.reflect.Flags): String = {
import qctx.reflect._
def showFlags(using qctx: QuoteContext)(flags: reflect.Flags): String = {
import reflect._
val flagList = List.newBuilder[String]
if (flags.is(Flags.Abstract)) flagList += "Flags.Abstract"
if (flags.is(Flags.Artifact)) flagList += "Flags.Artifact"
Expand Down Expand Up @@ -58,7 +58,7 @@ object Extractors {
}

private class ExtractorsPrinter[QCtx <: QuoteContext & Singleton](using val qctx: QCtx) { self =>
import qctx.reflect._
import reflect._

private val sb: StringBuilder = new StringBuilder

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,20 @@ import scala.annotation.switch
/** Printer for fully elaborated representation of the source code */
object SourceCode {

def showTree(using QuoteContext)(tree: qctx.reflect.Tree)(syntaxHighlight: SyntaxHighlight): String =
def showTree(using qctx: QuoteContext)(tree: reflect.Tree)(syntaxHighlight: SyntaxHighlight): String =
new SourceCodePrinter[qctx.type](syntaxHighlight).printTree(tree).result()

def showType(using QuoteContext)(tpe: qctx.reflect.TypeRepr)(syntaxHighlight: SyntaxHighlight): String =
def showType(using qctx: QuoteContext)(tpe: reflect.TypeRepr)(syntaxHighlight: SyntaxHighlight): String =
new SourceCodePrinter[qctx.type](syntaxHighlight).printType(tpe)(using None).result()

def showConstant(using QuoteContext)(const: qctx.reflect.Constant)(syntaxHighlight: SyntaxHighlight): String =
def showConstant(using qctx: QuoteContext)(const: reflect.Constant)(syntaxHighlight: SyntaxHighlight): String =
new SourceCodePrinter[qctx.type](syntaxHighlight).printConstant(const).result()

def showSymbol(using QuoteContext)(symbol: qctx.reflect.Symbol)(syntaxHighlight: SyntaxHighlight): String =
def showSymbol(using qctx: QuoteContext)(symbol: reflect.Symbol)(syntaxHighlight: SyntaxHighlight): String =
symbol.fullName

def showFlags(using QuoteContext)(flags: qctx.reflect.Flags)(syntaxHighlight: SyntaxHighlight): String = {
import qctx.reflect._
def showFlags(using qctx: QuoteContext)(flags: reflect.Flags)(syntaxHighlight: SyntaxHighlight): String = {
import reflect._
val flagList = List.newBuilder[String]
if (flags.is(Flags.Abstract)) flagList += "abstract"
if (flags.is(Flags.Artifact)) flagList += "artifact"
Expand Down Expand Up @@ -60,7 +60,7 @@ object SourceCode {

private class SourceCodePrinter[QCtx <: QuoteContext & Singleton](syntaxHighlight: SyntaxHighlight)(using val qctx: QCtx) {
import syntaxHighlight._
import qctx.reflect._
import reflect._

private[this] val sb: StringBuilder = new StringBuilder

Expand Down
6 changes: 3 additions & 3 deletions library/src-bootstrapped/scala/quoted/Expr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ object Expr {
* Some bindings may be elided as an early optimization.
*/
def betaReduce[T](expr: Expr[T])(using qctx: QuoteContext): Expr[T] =
import qctx.reflect._
import reflect._
Term.betaReduce(Term.of(expr)) match
case Some(expr1) => expr1.asExpr.asInstanceOf[Expr[T]]
case _ => expr
Expand All @@ -24,7 +24,7 @@ object Expr {
* will be equivalent to `'{ $s1; $s2; ...; $e }`.
*/
def block[T](statements: List[Expr[Any]], expr: Expr[T])(using qctx: QuoteContext): Expr[T] = {
import qctx.reflect._
import reflect._
Block(statements.map(Term.of), Term.of(expr)).asExpr.asInstanceOf[Expr[T]]
}

Expand Down Expand Up @@ -210,7 +210,7 @@ object Expr {
* @param qctx current context
*/
def summon[T](using tpe: Type[T])(using qctx: QuoteContext): Option[Expr[T]] = {
import qctx.reflect._
import reflect._
Implicits.search(TypeRepr.of[T]) match {
case iss: ImplicitSearchSuccess => Some(iss.tree.asExpr.asInstanceOf[Expr[T]])
case isf: ImplicitSearchFailure => None
Expand Down
2 changes: 1 addition & 1 deletion library/src-bootstrapped/scala/quoted/ExprMap.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ trait ExprMap:

/** Map subexpressions an expression `e` with a type `tpe` */
def transformChildren[T](e: Expr[T])(using qctx: QuoteContext, tpe: Type[T]): Expr[T] = {
import qctx.reflect._
import reflect._
final class MapChildren() {

def transformStatement(tree: Statement)(using ctx: Context): Statement = {
Expand Down
20 changes: 10 additions & 10 deletions library/src-bootstrapped/scala/quoted/Liftable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -24,70 +24,70 @@ object Liftable {
/** Default liftable for Boolean */
given BooleanLiftable[T <: Boolean] as Liftable[T] {
def toExpr(x: T) =
import qctx.reflect._
import reflect._
Literal(Constant.Boolean(x)).asExpr.asInstanceOf[Expr[T]]
}

/** Default liftable for Byte */
given ByteLiftable[T <: Byte] as Liftable[T] {
def toExpr(x: T) =
import qctx.reflect._
import reflect._
Literal(Constant.Byte(x)).asExpr.asInstanceOf[Expr[T]]
}

/** Default liftable for Short */
given ShortLiftable[T <: Short] as Liftable[T] {
def toExpr(x: T) =
import qctx.reflect._
import reflect._
Literal(Constant.Short(x)).asExpr.asInstanceOf[Expr[T]]
}

/** Default liftable for Int */
given IntLiftable[T <: Int] as Liftable[T] {
def toExpr(x: T) =
import qctx.reflect._
import reflect._
Literal(Constant.Int(x)).asExpr.asInstanceOf[Expr[T]]
}

/** Default liftable for Long */
given LongLiftable[T <: Long] as Liftable[T] {
def toExpr(x: T) =
import qctx.reflect._
import reflect._
Literal(Constant.Long(x)).asExpr.asInstanceOf[Expr[T]]
}

/** Default liftable for Float */
given FloatLiftable[T <: Float] as Liftable[T] {
def toExpr(x: T) =
import qctx.reflect._
import reflect._
Literal(Constant.Float(x)).asExpr.asInstanceOf[Expr[T]]
}

/** Default liftable for Double */
given DoubleLiftable[T <: Double] as Liftable[T] {
def toExpr(x: T) =
import qctx.reflect._
import reflect._
Literal(Constant.Double(x)).asExpr.asInstanceOf[Expr[T]]
}

/** Default liftable for Char */
given CharLiftable[T <: Char] as Liftable[T] {
def toExpr(x: T) =
import qctx.reflect._
import reflect._
Literal(Constant.Char(x)).asExpr.asInstanceOf[Expr[T]]
}

/** Default liftable for String */
given StringLiftable[T <: String] as Liftable[T] {
def toExpr(x: T) =
import qctx.reflect._
import reflect._
Literal(Constant.String(x)).asExpr.asInstanceOf[Expr[T]]
}

/** Default liftable for Class[T] */
given ClassLiftable[T] as Liftable[Class[T]] = new Liftable[Class[T]] {
def toExpr(x: Class[T]) = {
import qctx.reflect._
import reflect._
Ref(defn.Predef_classOf).appliedToType(TypeRepr.typeConstructorOf(x)).asExpr.asInstanceOf[Expr[Class[T]]]
}
}
Expand Down
4 changes: 2 additions & 2 deletions library/src-bootstrapped/scala/quoted/Type.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,11 @@ object Type:

/** Show a source code like representation of this type without syntax highlight */
def show[T](using tp: Type[T])(using qctx: QuoteContext): String =
qctx.reflect.TypeTree.of[T].show
reflect.TypeTree.of[T].show

/** Shows the tree as fully typed source code colored with ANSI */
def showAnsiColored[T](using tp: Type[T])(using qctx: QuoteContext): String =
qctx.reflect.TypeTree.of[T].showAnsiColored
reflect.TypeTree.of[T].showAnsiColored

/** Return a quoted.Type with the given type */
@compileTimeOnly("Reference to `scala.quoted.Type.of` was not handled by PickleQuotes")
Expand Down
2 changes: 1 addition & 1 deletion library/src/scala/quoted/Const.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ object Const {
* ```
*/
def unapply[T](expr: Expr[T])(using qctx: QuoteContext): Option[T] = {
import qctx.reflect._
import reflect._
def rec(tree: Term): Option[T] = tree match {
case Literal(c) => Some(c.value.asInstanceOf[T])
case Block(Nil, e) => rec(e)
Expand Down
8 changes: 4 additions & 4 deletions library/src/scala/quoted/QuoteContext.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import scala.reflect.TypeTest
* It contains the low-level Typed AST API metaprogramming API.
* This API does not have the static type guarantiees that `Expr` and `Type` provide.
*
* @param tasty Typed AST API. Usage: `def f(qctx: QuoteContext) = { import qctx.reflect._; ... }`.
* @param tasty Typed AST API. Usage: `def f(qctx: QuoteContext) = { import reflect._; ... }`.
*/
trait QuoteContext { self: internal.QuoteUnpickler & internal.QuoteMatching =>

Expand Down Expand Up @@ -3552,7 +3552,7 @@ trait QuoteContext { self: internal.QuoteUnpickler & internal.QuoteMatching =>
*
* Usage:
* ```
* import qctx.reflect._
* import reflect._
* class MyTreeMap extends TreeMap {
* override def transformTree(tree: Tree)(using ctx: Context): Tree = ...
* }
Expand Down Expand Up @@ -3722,10 +3722,10 @@ trait QuoteContext { self: internal.QuoteUnpickler & internal.QuoteMatching =>
* to explicitly state that a context is nested as in the following example:
*
* ```scala
* def run(using qctx: QuoteContext)(tree: qctx.reflect.Tree): Unit =
* def run(using qctx: QuoteContext)(tree: reflect.Tree): Unit =
* def nested()(using qctx.Nested): Expr[Int] = '{ ${ makeExpr(tree) } + 1 }
* '{ ${ nested() } + 2 }
* def makeExpr(using qctx: QuoteContext)(tree: qctx.reflect.Tree): Expr[Int] = ???
* def makeExpr(using qctx: QuoteContext)(tree: reflect.Tree): Expr[Int] = ???
* ```
*/
type Nested = QuoteContext {
Expand Down
4 changes: 2 additions & 2 deletions library/src/scala/quoted/Varargs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ object Varargs {
* ```
*/
def apply[T](xs: Seq[Expr[T]])(using tp: Type[T], qctx: QuoteContext): Expr[Seq[T]] = {
import qctx.reflect._
import reflect._
Repeated(xs.map(Term.of).toList, TypeTree.of[T]).asExpr.asInstanceOf[Expr[Seq[T]]]
}

Expand All @@ -33,7 +33,7 @@ object Varargs {
* ```
*/
def unapply[T](expr: Expr[Seq[T]])(using qctx: QuoteContext): Option[Seq[Expr[T]]] = {
import qctx.reflect._
import reflect._
def rec(tree: Term): Option[Seq[Expr[T]]] = tree match {
case Typed(Repeated(elems, _), _) => Some(elems.map(x => x.asExpr.asInstanceOf[Expr[T]]))
case Block(Nil, e) => rec(e)
Expand Down
18 changes: 18 additions & 0 deletions library/src/scala/quoted/reflect.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package scala.quoted

/** Current QuoteContext.reflect in scope
*
* Usage:
* To use reflection inside a method
* ```
* def f(using QuoteContext) = { // or (using qctx: QuoteContext)
* import reflect._ // equivalent to import reflect._
* ...
* }
* ```
* or to use reflection in the signature of a method
* ```
* def f(using QuoteContext)(tree: reflect.Tree): reflect.Position = ...
* ```
*/
def reflect(using qctx: QuoteContext): qctx.reflect.type = qctx.reflect
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What about #10295 ? There is no precedent in the language where we can import an unstable prefix. Or at least, with inline and checks?

Meanwhile, it seems to me that import qctx.reflect._ is better than import reflect._, as the former tells some information about the relationship between qctx and reflect, while the latter makes me wonder what's the magic behind.

8 changes: 4 additions & 4 deletions library/src/scala/quoted/report.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ object report:

/** Report an error at the position of the macro expansion */
def error(msg: => String)(using qctx: QuoteContext): Unit =
import qctx.reflect._
import reflect._
Reporting.error(msg, Position.ofMacroExpansion)

/** Report an error at the on the position of `expr` */
def error(msg: => String, expr: Expr[Any])(using qctx: QuoteContext): Unit =
import qctx.reflect._
import reflect._
Reporting.error(msg, Term.of(expr).pos)

/** Report an error at the position of the macro expansion and throws a StopMacroExpansion */
Expand All @@ -25,12 +25,12 @@ object report:

/** Report a warning */
def warning(msg: => String)(using qctx: QuoteContext): Unit =
import qctx.reflect._
import reflect._
Reporting.warning(msg, Position.ofMacroExpansion)

/** Report a warning at the on the position of `expr` */
def warning(msg: => String, expr: Expr[Any])(using qctx: QuoteContext): Unit =
import qctx.reflect._
import reflect._
Reporting.warning(msg, Term.of(expr).pos)

end report
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ trait TastyInspector:
self =>

/** Process a TASTy file using TASTy reflect */
protected def processCompilationUnit(using QuoteContext)(root: qctx.reflect.Tree): Unit
protected def processCompilationUnit(using QuoteContext)(root: reflect.Tree): Unit

/** Called after all compilation units are processed */
protected def postProcess(using QuoteContext): Unit = ()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ object SummonJsonEncoderTest {
inline def encodeAndMessAroundType[T](value: =>T): String = ${ encodeAndMessAroundTypeImpl('value) }

def encodeAndMessAroundTypeImpl[T: Type](value: Expr[T])(using qctx: QuoteContext): Expr[String] = {
import qctx.reflect._
import reflect._

val mirrorExpr = Expr.summon[Mirror.Of[T]] match {
case Some(mirror) => mirror
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/delegate-match-1/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import scala.quoted._
inline def f: Any = ${ fImpl }

private def fImpl(using qctx: QuoteContext): Expr[Unit] = {
import qctx.reflect._
import reflect._
Implicits.search(TypeRepr.of[A]) match {
case x: ImplicitSearchSuccess =>
'{}
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/delegate-match-2/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import scala.quoted._
inline def f: Any = ${ fImpl }

private def fImpl (using qctx: QuoteContext) : Expr[Unit] = {
import qctx.reflect._
import reflect._
Implicits.search(TypeRepr.of[A]) match {
case x: ImplicitSearchSuccess =>
'{}
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/delegate-match-3/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import scala.quoted._
inline def f: Any = ${ fImpl }

private def fImpl(using qctx: QuoteContext) : Expr[Unit] = {
import qctx.reflect._
import reflect._
Implicits.search(TypeRepr.of[A]) match {
case x: ImplicitSearchSuccess =>
'{}
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/i6432/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ object Macro {
extension (inline sc: StringContext) inline def foo(args: String*): Unit = ${ impl('sc) }

def impl(sc: Expr[StringContext])(using qctx: QuoteContext) : Expr[Unit] = {
import qctx.reflect._
import reflect._
sc match {
case '{ StringContext(${Varargs(parts)}: _*) } =>
for (part @ Const(s) <- parts)
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/i6432b/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ object Macro {
extension (inline sc: StringContext) inline def foo(args: String*): Unit = ${ impl('sc) }

def impl(sc: Expr[StringContext])(using qctx: QuoteContext) : Expr[Unit] = {
import qctx.reflect._
import reflect._
sc match {
case '{ StringContext(${Varargs(parts)}: _*) } =>
for (part @ Const(s) <- parts)
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/i7698.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ trait Show[T] {
}

def showInterpolatorImpl(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using qctx: QuoteContext): Expr[String] =
import qctx.reflect._
import reflect._
Term.of(argsExpr) match
case '{ $arg: $t } => // error
case '[ Int ] => // error
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/i7919.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import scala.quoted._

object Test {
def staged[T](using qctx: QuoteContext) = {
import qctx.reflect._
import reflect._
given typeT as Type[T] // error
val tt = TypeRepr.of[T]
'{ "in staged" }
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/i8871.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import scala.quoted._
object Macro {
def impl[A : Type](using qctx: QuoteContext): Unit = {
import qctx.reflect._
import reflect._
val tpe = TypeRepr.of[A].asType.asInstanceOf[Type[_ <: AnyRef]]
'{ (a: ${tpe}) => ???} // error
}
Expand Down
Loading