Skip to content

Simplify import of tasty unseal #8441

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

Merged
Merged
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
2 changes: 1 addition & 1 deletion community-build/community-projects/scalatest
4 changes: 2 additions & 2 deletions docs/docs/reference/contextual/derivation-macro.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ from the signature. The body of the `derived` method is shown below:

```scala
given derived[T: Type](using qctx: QuoteContext) as Expr[Eq[T]] = {
import qctx.tasty.{_, given _}
import qctx.tasty._

val ev: Expr[Mirror.Of[T]] = summonExpr(using '[Mirror.Of[T]]).get

Expand Down Expand Up @@ -176,7 +176,7 @@ object Eq {
}

given derived[T: Type](using qctx: QuoteContext) as Expr[Eq[T]] = {
import qctx.tasty.{_, given _}
import qctx.tasty._

val ev: Expr[Mirror.Of[T]] = summonExpr(using '[Mirror.Of[T]]).get

Expand Down
17 changes: 7 additions & 10 deletions docs/docs/reference/metaprogramming/tasty-reflect.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,19 @@ import scala.quoted._
inline def natConst(x: => Int): Int = ${natConstImpl('{x})}

def natConstImpl(x: Expr[Int])(using qctx: QuoteContext): Expr[Int] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
...
}
```

### Sealing and Unsealing
### Extractors

`import qctx.tasty.{_, given _}` will provide an `unseal` extension method on `quoted.Expr`
and `quoted.Type` which returns a `qctx.tasty.Term` that represents the tree of
the expression and `qctx.tasty.TypeTree` that represents the tree of the type
respectively. It will also import all extractors and methods on TASTy Reflect
`import qctx.tasty._` will provide all extractors and methods on TASTy Reflect
trees. For example the `Literal(_)` extractor used below.

```scala
def natConstImpl(x: Expr[Int])(using qctx: QuoteContext): Expr[Int] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
val xTree: Term = x.unseal
xTree match {
case Inlined(_, _, Literal(Constant(n: Int))) =>
Expand All @@ -64,7 +61,7 @@ def natConstImpl(x: Expr[Int])(using qctx: QuoteContext): Expr[Int] = {
To easily know which extractors are needed, the `showExtractors` method on a
`qctx.tasty.Term` returns the string representation of the extractors.

The method `qctx.tasty.Term.seal[T]` provides a way to go back to a
The method `qctx.tasty.Term.seal` provides a way to go back to a
`quoted.Expr[Any]`. Note that the type is `Expr[Any]`. Consequently, the type
must be set explicitly with a checked `cast` call. If the type does not conform
to it an exception will be thrown. In the code above, we could have replaced
Expand All @@ -81,7 +78,7 @@ operation expression passed while calling the `macro` below.
inline def macro(param: => Boolean): Unit = ${ macroImpl('param) }

def macroImpl(param: Expr[Boolean])(using qctx: QuoteContext): Expr[Unit] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
import util._

param.unseal.underlyingArgument match {
Expand All @@ -103,7 +100,7 @@ point.

```scala
def macroImpl()(qctx: QuoteContext): Expr[Unit] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
val pos = rootPosition

val path = pos.sourceFile.jpath.toString
Expand Down
10 changes: 9 additions & 1 deletion library/src/scala/quoted/Expr.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,14 @@ class Expr[+T] private[scala] {
final def matches(that: Expr[Any])(using qctx: QuoteContext): Boolean =
!scala.internal.quoted.Expr.unapply[Unit, Unit](this)(using that, false, qctx).isEmpty

/** Checked cast to a `quoted.Expr[U]` */
def cast[U](using tp: scala.quoted.Type[U])(using qctx: QuoteContext): scala.quoted.Expr[U] =
qctx.tasty.internal.QuotedExpr_cast[U](this)(using tp, qctx.tasty.rootContext)

/** View this expression `quoted.Expr[T]` as a `Term` */
def unseal(using qctx: QuoteContext): qctx.tasty.Term =
qctx.tasty.internal.QuotedExpr_unseal(this)(using qctx.tasty.rootContext)

}

object Expr {
Expand Down Expand Up @@ -108,7 +116,7 @@ object Expr {
*/
def ofSeq[T](xs: Seq[Expr[T]])(using tp: Type[T], qctx: QuoteContext): Expr[Seq[T]] = {
import qctx.tasty.{_, given _}
Repeated(xs.map(_.unseal).toList, tp.unseal).seal.asInstanceOf[Expr[Seq[T]]]
Repeated(xs.map[Term](_.unseal).toList, tp.unseal).seal.asInstanceOf[Expr[Seq[T]]]
}


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 @@ -32,13 +32,13 @@ class QuoteContext(val tasty: scala.tasty.Reflection) { self =>
/** Show the fully elaborated source code representation of an expression */
def show(expr: Expr[_], syntaxHighlight: SyntaxHighlight): String = {
import tasty.{_, given _}
expr.unseal.showWith(syntaxHighlight)
expr.unseal(using this).showWith(syntaxHighlight)
}

/** Show the fully elaborated source code representation of a type */
def show(tpe: Type[_], syntaxHighlight: SyntaxHighlight): String = {
import tasty.{_, given _}
tpe.unseal.showWith(syntaxHighlight)
tpe.unseal(using this).showWith(syntaxHighlight)
}

/** Report an error at the position of the macro expansion */
Expand All @@ -50,7 +50,7 @@ class QuoteContext(val tasty: scala.tasty.Reflection) { self =>
/** Report an error at the on the position of `expr` */
def error(msg: => String, expr: Expr[Any]): Unit = {
import tasty.{_, given _}
tasty.error(msg, expr.unseal.pos)
tasty.error(msg, expr.unseal(using this).pos)
}

/** Report an error at the position of the macro expansion and throws a StopQuotedContext */
Expand All @@ -73,7 +73,7 @@ class QuoteContext(val tasty: scala.tasty.Reflection) { self =>
/** Report a warning at the on the position of `expr` */
def warning(msg: => String, expr: Expr[_]): Unit = {
import tasty.{_, given _}
tasty.warning(msg, expr.unseal.pos)
tasty.warning(msg, expr.unseal(using this).pos)
}

}
4 changes: 4 additions & 0 deletions library/src/scala/quoted/Type.scala
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ class Type[T <: AnyKind] private[scala] {
/** Show a source code like representation of this type */
def show(syntaxHighlight: SyntaxHighlight)(using qctx: QuoteContext): String = qctx.show(this, syntaxHighlight)

/** View this expression `quoted.Type[T]` as a `TypeTree` */
def unseal(using qctx: QuoteContext): qctx.tasty.TypeTree =
qctx.tasty.internal.QuotedType_unseal(this)(using qctx.tasty.rootContext)

}

/** Some basic type tags, currently incomplete */
Expand Down
23 changes: 2 additions & 21 deletions library/src/scala/tasty/Reflection.scala
Original file line number Diff line number Diff line change
Expand Up @@ -415,26 +415,6 @@ class Reflection(private[scala] val internal: CompilerInterface) { self =>
type AmbiguousImplicits = internal.AmbiguousImplicits


////////////////
// QUOTES //
////////////////

extension QuotedExprOps on (expr: scala.quoted.Expr[?]) {
/** View this expression `quoted.Expr[T]` as a `Term` */
def unseal(using ctx: Context): Term =
internal.QuotedExpr_unseal(expr)

/** Checked cast to a `quoted.Expr[U]` */
def cast[U](using tp: scala.quoted.Type[U], ctx: Context): scala.quoted.Expr[U] =
internal.QuotedExpr_cast[U](expr)
}

extension QuotedTypeOps on [T <: AnyKind](tpe: scala.quoted.Type[T]) {
/** View this expression `quoted.Type[T]` as a `TypeTree` */
def unseal(using ctx: Context): TypeTree =
internal.QuotedType_unseal(tpe)
}

//////////////
// CONTEXTS //
//////////////
Expand Down Expand Up @@ -1592,7 +1572,8 @@ class Reflection(private[scala] val internal: CompilerInterface) { self =>
///////////////

/** Returns the type (Type) of T */
def typeOf[T](using qtype: scala.quoted.Type[T], ctx: Context): Type = qtype.unseal.tpe
def typeOf[T](using qtype: scala.quoted.Type[T], ctx: Context): Type =
internal.QuotedType_unseal(qtype).tpe

/** Members of `TypeOrBounds` */
extension TypeOrBoundsOps on (tpe: TypeOrBounds) {
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.matching._
inline def f: Any = ${ fImpl }

private def fImpl(using qctx: QuoteContext): Expr[Unit] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
searchImplicit(('[A]).unseal.tpe) 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.matching._
inline def f: Any = ${ fImpl }

private def fImpl (using qctx: QuoteContext) : Expr[Unit] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
searchImplicit(('[A]).unseal.tpe) 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.matching._
inline def f: Any = ${ fImpl }

private def fImpl(using qctx: QuoteContext) : Expr[Unit] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
searchImplicit(('[A]).unseal.tpe) 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 @@ -7,7 +7,7 @@ object Macro {
inline def (sc: => StringContext).foo(args: String*): Unit = ${ impl('sc) }

def impl(sc: Expr[StringContext])(using qctx: QuoteContext) : Expr[Unit] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
sc match {
case '{ StringContext(${ExprSeq(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 @@ -7,7 +7,7 @@ object Macro {
inline def (sc: => StringContext).foo(args: String*): Unit = ${ impl('sc) }

def impl(sc: Expr[StringContext])(using qctx: QuoteContext) : Expr[Unit] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
sc match {
case '{ StringContext(${ExprSeq(parts)}: _*) } =>
for (part @ Const(s) <- parts)
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/tasty-macro-assert-1/quoted_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ object Asserts {
${impl('cond)}

def impl(cond: Expr[Boolean])(using qctx: QuoteContext) : Expr[Unit] = {
import qctx.tasty.{_, given _}
import qctx.tasty._

val tree = cond.unseal

Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/tasty-macro-assert-2/quoted_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ object Asserts {
${ impl('cond) }

def impl(cond: Expr[Boolean])(using qctx: QuoteContext) : Expr[Unit] = {
import qctx.tasty.{_, given _}
import qctx.tasty._

val tree = cond.unseal

Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/tasty-macro-error/quoted_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ object Macros {
inline def fun(x: Any): Unit = ${ impl('x) }

def impl(x: Expr[Any])(using qctx: QuoteContext) : Expr[Unit] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
error("here is the the argument is " + x.unseal.underlyingArgument.show, x.unseal.underlyingArgument.pos)
'{}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-macros/tasty-macro-positions/quoted_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ object Macros {
inline def fun(x: Any): Unit = ${ impl('x) }

def impl(x: Expr[Any])(using qctx: QuoteContext) : Expr[Unit] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
val pos = x.unseal.underlyingArgument.pos
error("here is the the argument is " + x.unseal.underlyingArgument.show, pos)
error("here (+5) is the the argument is " + x.unseal.underlyingArgument.show, pos.sourceFile, pos.start + 5, pos.end + 5)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object Macro {
object FIntepolator {

def apply(strCtxExpr: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using qctx: QuoteContext) : Expr[String] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
error("there are no parts", strCtxExpr.unseal.underlyingArgument.pos)
'{ ($strCtxExpr).s($argsExpr: _*) }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ object Macro {

object FIntepolator {
def apply(strCtxExpr: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using qctx: QuoteContext) : Expr[String] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
error("there are no args", argsExpr.unseal.underlyingArgument.pos)
'{ ($strCtxExpr).s($argsExpr: _*) }
}
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-staging/i5941/macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ object Lens {

def impl[S: Type, T: Type](getter: Expr[S => T])(using qctx: QuoteContext): Expr[Lens[S, T]] = {
implicit val toolbox: scala.quoted.staging.Toolbox = scala.quoted.staging.Toolbox.make(this.getClass.getClassLoader)
import qctx.tasty.{_, given _}
import qctx.tasty._
import util._
// obj.copy(field = value)
def setterBody(obj: Expr[S], value: Expr[T], field: String): Expr[S] =
Expand Down
2 changes: 1 addition & 1 deletion tests/neg/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.tasty.{_, given _}
import qctx.tasty._
given typeT as quoted.Type[T] // error
val tTypeTree = typeT.unseal
val tt = typeOf[T]
Expand Down
2 changes: 1 addition & 1 deletion tests/pending/run/tasty-comments/quoted_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ object Macros {
${ impl('t) }

def impl[T](x: Expr[T])(using qctx: QuoteContext) : Expr[Unit] = {
import qctx.tasty.{_, given _}
import qctx.tasty._

val tree = x.unseal
tree.symbol.comment.map(_.raw) match {
Expand Down
2 changes: 1 addition & 1 deletion tests/pos-macros/i6171/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ object scalatest {
inline def assert(x: => Any): Unit = ${ assertImpl('x) }

def assertImpl(x: Expr[Any])(using qctx: QuoteContext) : Expr[Unit] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
x.unseal.underlyingArgument
'{ () }
}
Expand Down
2 changes: 1 addition & 1 deletion tests/pos-macros/i6535/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ object scalatest {
inline def assert(condition: => Boolean): Unit = ${ assertImpl('condition) }

def assertImpl(cond: Expr[Boolean])(using qctx: QuoteContext) : Expr[Unit] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
import util._

cond.unseal.underlyingArgument match {
Expand Down
2 changes: 1 addition & 1 deletion tests/pos-macros/i6803b/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ object AsObject {
def unsafe(i: Int): LineNo = new LineNo(i)
inline given x as LineNo = ${impl}
private def impl(using qctx: QuoteContext) : Expr[LineNo] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
'{unsafe(${rootPosition.startLine})}
}
}
Expand Down
2 changes: 1 addition & 1 deletion tests/pos-macros/tasty-constant-type/Macro_1.scala
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ object Macro {
inline def ff[A <: Int, B <: Int]() <: AddInt[A, B] = ${ impl('[A], '[B]) }

def impl[A <: Int : Type, B <: Int : Type](a: Type[A], b: Type[B])(using qctx: QuoteContext) : Expr[AddInt[A, B]] = {
import qctx.tasty.{_, given _}
import qctx.tasty._

val ConstantType(Constant(v1: Int)) = a.unseal.tpe
val ConstantType(Constant(v2: Int)) = b.unseal.tpe
Expand Down
2 changes: 1 addition & 1 deletion tests/pos/i7204.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import scala.quoted._

object Foo {
def impl(using qctx: QuoteContext) : Unit = {
import qctx.tasty.{_, given _}
import qctx.tasty._
val Select(_, _) = (??? : Term)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ object Foo {
${ inspectBodyImpl('i) }

def inspectBodyImpl(x: Expr[Int])(using qctx: QuoteContext) : Expr[String] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
x.unseal match {
case Inlined(None, Nil, arg) => arg.symbol.tree.showExtractors
case arg => arg.symbol.tree.showExtractors // TODO should all by name parameters be in an inline node?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ object Foo {
${ inspectBodyImpl('i) }

def inspectBodyImpl(x: Expr[Int])(using qctx: QuoteContext) : Expr[String] = {
import qctx.tasty.{_, given _}
import qctx.tasty._
x.unseal match {
case Inlined(None, Nil, arg) => arg.symbol.tree.showExtractors
case arg => arg.symbol.tree.showExtractors // TODO should all by name parameters be in an inline node?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ object Macros {
${ impl('x) }

def impl[T](x: Expr[T])(using qctx: QuoteContext) : Expr[Unit] = {
import qctx.tasty.{_, given _}
import qctx.tasty._

val buff = new StringBuilder

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ object Foo {
${ inspectBodyImpl('i) }

def inspectBodyImpl(x: Expr[Int])(using qctx: QuoteContext) : Expr[String] = {
import qctx.tasty.{_, given _}
import qctx.tasty._

def definitionString(sym: Symbol): Expr[String] =
if sym.isClassDef || sym.isDefDef || sym.isValDef then Expr(sym.tree.showExtractors)
Expand Down
Loading