Skip to content

Commit e2cf7ec

Browse files
committed
Add QuoteScope
1 parent d463a9e commit e2cf7ec

File tree

2 files changed

+99
-19
lines changed

2 files changed

+99
-19
lines changed

library/src-bootstrapped/scala/quoted/QuoteContext.scala

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,30 +10,19 @@ import scala.quoted.show.SyntaxHighlight
1010
*
1111
* @param tasty Typed AST API. Usage: `def f(qctx: QuoteContext) = { import qctx.tasty._; ... }`.
1212
*/
13-
trait QuoteContext { self =>
13+
trait QuoteContext extends QuoteScope { self =>
1414

15-
/** Low-level Typed AST API `tasty` meta-programming API.
16-
* This API does not have the static type guarantiees that `Expr` and `Type` provide.
17-
*/
18-
val tasty: scala.tasty.Reflection
15+
/** Quoted of type `T` */
16+
type Expr[+T] = scala.quoted.Expr[T]
17+
18+
/** Quoted type (or kind) `T` */
19+
type Type[T <: AnyKind] = scala.quoted.Type[T]
1920

20-
/** Type of a QuoteContext provided by a splice within a quote that took this context.
21-
* It is only required if working with the reflection API.
22-
*
23-
* Usually it is infered by the quotes an splices typing. But sometimes it is necessary
24-
* to explicitly state that a context is nested as in the following example:
25-
*
26-
* ```scala
27-
* def run(using qctx: QuoteContext)(tree: qctx.tasty.Tree): Unit =
28-
* def nested()(using qctx.Nested): Expr[Int] = '{ ${ makeExpr(tree) } + 1 }
29-
* '{ ${ nested() } + 2 }
30-
* def makeExpr(using qctx: QuoteContext)(tree: qctx.tasty.Tree): Expr[Int] = ???
31-
* ```
32-
*/
3321
type Nested = QuoteContext {
22+
type Expr[+T] >: self.Expr[T]
23+
type Type[T <: AnyKind] >: self.Type[T]
3424
val tasty: self.tasty.type
3525
}
36-
3726
}
3827

3928
object QuoteContext {
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package scala.quoted
2+
3+
import scala.quoted.show.SyntaxHighlight
4+
5+
/** Quotation context provided by a macro expansion or in the scope of `scala.quoted.run`.
6+
* Used to perform all operations on quoted `Expr` or `Type`.
7+
*
8+
* It contains the low-level Typed AST API `tasty` meta-programming API.
9+
* This API does not have the static type guarantiees that `Expr` and `Type` provide.
10+
*
11+
* @param tasty Typed AST API. Usage: `def f(qctx: QuoteContext) = { import qctx.tasty._; ... }`.
12+
*/
13+
trait QuoteScope { self =>
14+
15+
/** Quoted expression of type `T` */
16+
type Expr[+T]
17+
18+
object Expr {
19+
20+
// /** Show a source code like representation of this expression without syntax highlight */
21+
// def [T](expr: Expr[T]).show(using QuoteScope): String =
22+
// expr.unseal.showWith(SyntaxHighlight.plain)
23+
24+
// /** Show a source code like representation of this expression */
25+
// def show(syntaxHighlight: SyntaxHighlight)(using qctx: QuoteContext): String =
26+
// expr.unseal.showWith(syntaxHighlight)
27+
28+
// /** Return the unlifted value of this expression.
29+
// *
30+
// * Returns `None` if the expression does not contain a value or contains side effects.
31+
// * Otherwise returns the `Some` of the value.
32+
// */
33+
// final def unlift[U >: T](using qctx: QuoteContext, unlift: Unliftable[U]): Option[U] =
34+
// unlift(expr)
35+
36+
// /** Return the unlifted value of this expression.
37+
// *
38+
// * Emits an error and throws if the expression does not contain a value or contains side effects.
39+
// * Otherwise returns the value.
40+
// */
41+
// final def unliftOrError[U >: T](using qctx: QuoteContext, unlift: Unliftable[U]): U =
42+
// unlift(expr).getOrElse(Reporting.throwError(s"Expected a known value. \n\nThe value of: ${expr.show}\ncould not be unlifted using $unlift", this))
43+
44+
// /** Pattern matches `this` against `that`. Effectively performing a deep equality check.
45+
// * It does the equivalent of
46+
// * ```
47+
// * this match
48+
// * case '{...} => true // where the contents of the pattern are the contents of `that`
49+
// * case _ => false
50+
// * ```
51+
// */
52+
// final def matches(that: Expr[Any])(using qctx: QuoteContext): Boolean =
53+
// !scala.internal.quoted.Expr.unapply[Unit, Unit](expr)(using that, false, qctx).isEmpty
54+
55+
// /** Checked cast to a `quoted.Expr[U]` */
56+
// def cast[U](using tp: scala.quoted.Type[U])(using qctx: QuoteContext): scala.quoted.Expr[U] =
57+
// qctx.tasty.internal.QuotedExpr_cast[U](expr)(using tp, qctx.tasty.rootContext)
58+
59+
/** View this expression `Expr[T]` as a `Term` */
60+
def [T](expr: Expr[T]).unseal: self.tasty.Term =
61+
self.tasty.internal.QuotedExpr_unseal(expr.asInstanceOf[scala.quoted.Expr[T]])(using self.tasty.rootContext)
62+
}
63+
64+
/** Quoted type (or kind) `T` */
65+
type Type[T <: AnyKind]
66+
67+
/** Low-level Typed AST API `tasty` meta-programming API.
68+
* This API does not have the static type guarantiees that `Expr` and `Type` provide.
69+
*/
70+
val tasty: scala.tasty.Reflection
71+
72+
/** Type of a QuoteContext provided by a splice within a quote that took this context.
73+
* It is only required if working with the reflection API.
74+
*
75+
* Usually it is infered by the quotes an splices typing. But sometimes it is necessary
76+
* to explicitly state that a context is nested as in the following example:
77+
*
78+
* ```scala
79+
* def run(using qctx: QuoteContext)(tree: qctx.tasty.Tree): Unit =
80+
* def nested()(using qctx.Nested): Expr[Int] = '{ ${ makeExpr(tree) } + 1 }
81+
* '{ ${ nested() } + 2 }
82+
* def makeExpr(using qctx: QuoteContext)(tree: qctx.tasty.Tree): Expr[Int] = ???
83+
* ```
84+
*/
85+
type Nested <: QuoteScope {
86+
type Expr[+T] >: self.Expr[T]
87+
type Type[T <: AnyKind] >: self.Type[T]
88+
val tasty: self.tasty.type
89+
}
90+
91+
}

0 commit comments

Comments
 (0)