Skip to content

Commit bbb5209

Browse files
committed
Add Expr.asTerm
* Add `Expr.asTerm` under `reflect` * Deprecate `Tree.of` and `Term.of` for simpler migration from M2 to M3 This change make the intent of the operation clearer. We call `asTerm` to see the expression as a `Term` just like we call `asExpr` make the `Term` and `Expr[Any]`. t It will simplify code that needs to acceess the trees. As these are extension methods, they can also be accessed explicilty using `reflect.asTerm(expr)` which can be useful in some situations. Remove asTree
1 parent a1434a8 commit bbb5209

File tree

95 files changed

+195
-190
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

95 files changed

+195
-190
lines changed

community-build/src/scala/dotty/communitybuild/FieldsImpl.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ object FieldsImpl:
1111
val retType = TypeTree.of[T].tpe
1212
def isProjectField(s: Symbol) =
1313
s.isValDef && s.tree.asInstanceOf[ValDef].tpt.tpe <:< retType
14-
val projectsTree = Term.of(from)
14+
val projectsTree = from.asTerm
1515
val symbols = TypeTree.of[V].symbol.memberMethods.filter(isProjectField)
1616
val selects = symbols.map(Select(projectsTree, _).asExprOf[T])
1717
'{ println(${Expr(retType.show)}); ${Varargs(selects)} }

compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -48,17 +48,17 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
4848

4949
extension [T](self: scala.quoted.Expr[T]):
5050
def show: String =
51-
reflect.Printer.TreeCode.show(reflect.Term.of(self))
51+
reflect.Printer.TreeCode.show(reflect.asTerm(self))
5252

5353
def matches(that: scala.quoted.Expr[Any]): Boolean =
54-
treeMatch(reflect.Term.of(self), reflect.Term.of(that)).nonEmpty
54+
treeMatch(reflect.asTerm(self), reflect.asTerm(that)).nonEmpty
5555

5656
end extension
5757

5858
extension [X](self: scala.quoted.Expr[Any]):
5959
/** Checks is the `quoted.Expr[?]` is valid expression of type `X` */
6060
def isExprOf(using scala.quoted.Type[X]): Boolean =
61-
reflect.TypeReprMethods.<:<(reflect.Term.of(self).tpe)(reflect.TypeRepr.of[X])
61+
reflect.TypeReprMethods.<:<(reflect.asTerm(self).tpe)(reflect.TypeRepr.of[X])
6262

6363
/** Convert this to an `quoted.Expr[X]` if this expression is a valid expression of type `X` or throws */
6464
def asExprOf(using scala.quoted.Type[X]): scala.quoted.Expr[X] = {
@@ -67,7 +67,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
6767
else
6868
throw Exception(
6969
s"""Expr cast exception: ${self.show}
70-
|of type: ${reflect.Printer.TypeReprCode.show(reflect.Term.of(self).tpe)}
70+
|of type: ${reflect.Printer.TypeReprCode.show(reflect.asTerm(self).tpe)}
7171
|did not conform to type: ${reflect.Printer.TypeReprCode.show(reflect.TypeRepr.of[X])}
7272
|""".stripMargin
7373
)
@@ -76,11 +76,16 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
7676

7777
object reflect extends reflectModule:
7878

79+
extension (expr: Expr[Any]):
80+
def asTerm: Term =
81+
val exprImpl = expr.asInstanceOf[ExprImpl]
82+
exprImpl.checkScopeId(QuotesImpl.this.hashCode)
83+
exprImpl.tree
84+
end extension
85+
7986
type Tree = tpd.Tree
8087

81-
object Tree extends TreeModule:
82-
def of(expr: Expr[Any]): Tree = Term.of(expr)
83-
end Tree
88+
object Tree extends TreeModule
8489

8590
given TreeMethods: TreeMethods with
8691
extension (self: Tree):
@@ -340,11 +345,6 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
340345
end TermTypeTest
341346

342347
object Term extends TermModule:
343-
def of(expr: Expr[Any]): Term =
344-
val exprImpl = expr.asInstanceOf[ExprImpl]
345-
exprImpl.checkScopeId(QuotesImpl.this.hashCode)
346-
exprImpl.tree
347-
348348
def betaReduce(tree: Term): Option[Term] =
349349
tree match
350350
case app @ tpd.Apply(tpd.Select(fn, nme.apply), args) if dotc.core.Symbols.defn.isFunctionType(fn.tpe) =>
@@ -2588,7 +2588,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
25882588
dotc.report.error(msg, Position.ofMacroExpansion)
25892589

25902590
def error(msg: String, expr: Expr[Any]): Unit =
2591-
dotc.report.error(msg, Term.of(expr).pos)
2591+
dotc.report.error(msg, asTerm(expr).pos)
25922592

25932593
def error(msg: String, pos: Position): Unit =
25942594
dotc.report.error(msg, pos)
@@ -2609,7 +2609,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
26092609
dotc.report.warning(msg, Position.ofMacroExpansion)
26102610

26112611
def warning(msg: String, expr: Expr[Any]): Unit =
2612-
dotc.report.warning(msg, Term.of(expr).pos)
2612+
dotc.report.warning(msg, asTerm(expr).pos)
26132613

26142614
def warning(msg: String, pos: Position): Unit =
26152615
dotc.report.warning(msg, pos)
@@ -2716,8 +2716,8 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
27162716

27172717
object ExprMatch extends ExprMatchModule:
27182718
def unapply[TypeBindings <: Tuple, Tup <: Tuple](scrutinee: scala.quoted.Expr[Any])(using pattern: scala.quoted.Expr[Any]): Option[Tup] =
2719-
val scrutineeTree = reflect.Term.of(scrutinee)
2720-
val patternTree = reflect.Term.of(pattern)
2719+
val scrutineeTree = reflect.asTerm(scrutinee)
2720+
val patternTree = reflect.asTerm(pattern)
27212721
treeMatch(scrutineeTree, patternTree).asInstanceOf[Option[Tup]]
27222722
end ExprMatch
27232723

docs/docs/reference/metaprogramming/tasty-reflect.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ trees. For example the `Literal(_)` extractor used below.
4242
```scala
4343
def natConstImpl(x: Expr[Int])(using Quotes): Expr[Int] = {
4444
import quotes.reflect._
45-
val xTree: Term = Term.of(x)
45+
val xTree: Term = x.asTerm
4646
xTree match {
4747
case Inlined(_, _, Literal(Constant(n: Int))) =>
4848
if (n <= 0) {

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ object Expr {
1919
*/
2020
def betaReduce[T](expr: Expr[T])(using Quotes): Expr[T] =
2121
import quotes.reflect._
22-
Term.betaReduce(Term.of(expr)) match
22+
Term.betaReduce(expr.asTerm) match
2323
case Some(expr1) => expr1.asExpr.asInstanceOf[Expr[T]]
2424
case _ => expr
2525

@@ -29,7 +29,7 @@ object Expr {
2929
*/
3030
def block[T](statements: List[Expr[Any]], expr: Expr[T])(using Quotes): Expr[T] = {
3131
import quotes.reflect._
32-
Block(statements.map(Term.of), Term.of(expr)).asExpr.asInstanceOf[Expr[T]]
32+
Block(statements.map(asTerm), expr.asTerm).asExpr.asInstanceOf[Expr[T]]
3333
}
3434

3535
/** Creates an expression that will construct the value `x` */

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ object FromExpr {
9090
case Inlined(_, Nil, e) => rec(e)
9191
case _ => None
9292
}
93-
rec(Term.of(expr))
93+
rec(expr.asTerm)
9494
}
9595

9696
/** Default implementation of `FromExpr[Option]`

library/src/scala/quoted/Const.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ object Const {
3434
case Inlined(_, Nil, e) => rec(e)
3535
case _ => None
3636
}
37-
rec(Term.of(expr))
37+
rec(expr.asTerm)
3838
}
3939

4040
}

library/src/scala/quoted/ExprMap.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -100,13 +100,13 @@ trait ExprMap:
100100
transformTermChildren(tree, tpe)(owner)
101101
case _ if tree.isExpr =>
102102
// WARNING: Never do a cast like this in user code (accepable within the stdlib).
103-
// In theory we should use `tree.asExpr match { case '{ $expr: t } => Term.of(transform(expr)) }`
103+
// In theory we should use `tree.asExpr match { case '{ $expr: t } => transform(expr).asTerm }`
104104
// This is to avoid conflicts when re-boostrapping the library.
105105
type X
106106
val expr = tree.asExpr.asInstanceOf[Expr[X]]
107107
val t = tpe.asType.asInstanceOf[Type[X]]
108108
val transformedExpr = transform(expr)(using t)
109-
Term.of(transformedExpr)
109+
transformedExpr.asTerm
110110
case _ =>
111111
transformTermChildren(tree, tpe)(owner)
112112

@@ -145,7 +145,7 @@ trait ExprMap:
145145
trees.mapConserve(x => transformTypeCaseDef(x)(owner))
146146

147147
}
148-
new MapChildren().transformTermChildren(Term.of(e), TypeRepr.of[T])(Symbol.spliceOwner).asExprOf[T]
148+
new MapChildren().transformTermChildren(e.asTerm, TypeRepr.of[T])(Symbol.spliceOwner).asExprOf[T]
149149
}
150150

151151
end ExprMap

library/src/scala/quoted/Quotes.scala

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
7676
* import scala.quoted._
7777
* def f(expr: Expr[Int])(using Quotes) =
7878
* import quotes.reflect._
79-
* val tree: Tree = Term.of(expr)
79+
* val ast: Term = expr.asTerm
8080
* ...
8181
* ```
8282
*
@@ -201,11 +201,14 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
201201
*/
202202
trait reflectModule { self: reflect.type =>
203203

204+
/** Returns the `Term` representation this expression */
205+
extension (expr: Expr[Any])
206+
def asTerm: Term
207+
204208
///////////////
205209
// TREES //
206210
///////////////
207211

208-
209212
/** Tree representing code written in the source */
210213
type Tree <: AnyRef
211214

@@ -215,7 +218,8 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
215218
/** Methods of the module object `val Tree` */
216219
trait TreeModule { this: Tree.type =>
217220
/** Returns the Term representation this expression */
218-
def of(expr: Expr[Any]): Tree
221+
@deprecated("Use `expr.asTerm` instead (must `import quotes.reflect._`). This will be removed in 3.0.0-RC1", "3.0.0-M3")
222+
def of(expr: Expr[Any]): Tree = expr.asTerm
219223
}
220224

221225
/** Makes extension methods on `Tree` available without any imports */
@@ -509,7 +513,8 @@ trait Quotes { self: runtime.QuoteUnpickler & runtime.QuoteMatching =>
509513
trait TermModule { this: Term.type =>
510514

511515
/** Returns the Term representation this expression */
512-
def of(expr: Expr[Any]): Term
516+
@deprecated("Use `expr.asTerm` instead (must `import quotes.reflect._`). This will be removed in 3.0.0-RC1", "3.0.0-M3")
517+
def of(expr: Expr[Any]): Term = expr.asTerm
513518

514519
/** Returns a term that is functionally equivalent to `t`,
515520
* however if `t` is of the form `((y1, ..., yn) => e2)(e1, ..., en)`

library/src/scala/quoted/Varargs.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ object Varargs {
2121
*/
2222
def apply[T](xs: Seq[Expr[T]])(using Type[T])(using Quotes): Expr[Seq[T]] = {
2323
import quotes.reflect._
24-
Repeated(xs.map(Term.of).toList, TypeTree.of[T]).asExpr.asInstanceOf[Expr[Seq[T]]]
24+
Repeated(xs.map(_.asTerm).toList, TypeTree.of[T]).asExpr.asInstanceOf[Expr[Seq[T]]]
2525
}
2626

2727
/** Matches a literal sequence of expressions and return a sequence of expressions.
@@ -44,7 +44,7 @@ object Varargs {
4444
case Inlined(_, Nil, e) => rec(e)
4545
case _ => None
4646
}
47-
rec(Term.of(expr))
47+
rec(expr.asTerm)
4848
}
4949

5050
}

tests/neg-macros/i6432/Macro_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ object Macro {
1010
sc match {
1111
case '{ StringContext(${Varargs(parts)}: _*) } =>
1212
for (part @ Const(s) <- parts)
13-
report.error(s, Term.of(part).pos)
13+
report.error(s, part.asTerm.pos)
1414
}
1515
'{}
1616
}

0 commit comments

Comments
 (0)