Skip to content

Commit 7adb69d

Browse files
Merge pull request #10694 from dotty-staging/add-Expr-asTerm-and-asTree
Add `Expr.asTerm`
2 parents 71b68b7 + 257716e commit 7adb69d

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.fields.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
}

tests/neg-macros/i6432b/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
}

tests/neg-macros/i6976/Macro_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,6 @@ object macros {
77

88
def mcrImpl(body: Expr[Any])(using ctx: Quotes) : Expr[Any] = {
99
import ctx.reflect._
10-
Term.of(body) match { case Block(_, _) => '{2} }
10+
body.asTerm match { case Block(_, _) => '{2} }
1111
}
1212
}

tests/neg-macros/i7698.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ trait Show[T] {
66

77
def showInterpolatorImpl(sc: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using Quotes): Expr[String] =
88
import quotes.reflect._
9-
Term.of(argsExpr) match
9+
argsExpr.asTerm match
1010
case '{ $arg: $t } => // error
1111
case '[ Int ] => // error
1212
???

tests/neg-macros/i9801/Macro_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,6 @@ def impl(prog: Expr[Double])(using Quotes) : Expr[Double] =
1616
triggerStackOverflow(0)
1717
} catch {
1818
case e =>
19-
quotes.reflect.report.error(e.getMessage, Term.of(prog).pos)
19+
quotes.reflect.report.error(e.getMessage, prog.asTerm.pos)
2020
'{ 42.0 }
2121
}

tests/neg-macros/tasty-macro-assert-1/quoted_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ object Asserts {
1515
def impl(cond: Expr[Boolean])(using Quotes) : Expr[Unit] = {
1616
import quotes.reflect._
1717

18-
val tree = Term.of(cond)
18+
val tree = cond.asTerm
1919

2020
def isOps(tpe: TypeRepr): Boolean = tpe match {
2121
case tpe: TermRef => tpe.termSymbol.isDefDef && tpe.name == "Ops"// TODO check that the parent is Asserts

tests/neg-macros/tasty-macro-assert-2/quoted_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ object Asserts {
1515
def impl(cond: Expr[Boolean])(using Quotes) : Expr[Unit] = {
1616
import quotes.reflect._
1717

18-
val tree = Term.of(cond)
18+
val tree = cond.asTerm
1919

2020
def isOps(tpe: TypeRepr): Boolean = tpe match {
2121
case tpe: TermRef => tpe.termSymbol.isDefDef && tpe.name == "Ops"// TODO check that the parent is Asserts

tests/neg-macros/tasty-macro-error/quoted_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ object Macros {
66

77
def impl(x: Expr[Any])(using Quotes) : Expr[Unit] = {
88
import quotes.reflect._
9-
report.error("here is the the argument is " + Term.of(x).underlyingArgument.show, Term.of(x).underlyingArgument.pos)
9+
report.error("here is the the argument is " + x.asTerm.underlyingArgument.show, x.asTerm.underlyingArgument.pos)
1010
'{}
1111
}
1212

tests/neg-macros/tasty-macro-positions/quoted_1.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ object Macros {
66

77
def impl(x: Expr[Any])(using Quotes) : Expr[Unit] = {
88
import quotes.reflect._
9-
val pos = Term.of(x).underlyingArgument.pos
10-
report.error("here is the the argument is " + Term.of(x).underlyingArgument.show, pos)
11-
report.error("here (+5) is the the argument is " + Term.of(x).underlyingArgument.show, Position(pos.sourceFile, pos.start + 5, pos.end + 5))
9+
val pos = x.asTerm.underlyingArgument.pos
10+
report.error("here is the the argument is " + x.asTerm.underlyingArgument.show, pos)
11+
report.error("here (+5) is the the argument is " + x.asTerm.underlyingArgument.show, Position(pos.sourceFile, pos.start + 5, pos.end + 5))
1212
'{}
1313
}
1414

tests/neg-macros/tasty-string-interpolator-position-a/Macro_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ object FIntepolator {
1111

1212
def apply(strCtxExpr: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using Quotes) : Expr[String] = {
1313
import quotes.reflect._
14-
report.error("there are no parts", Term.of(strCtxExpr).underlyingArgument.pos)
14+
report.error("there are no parts", strCtxExpr.asTerm.underlyingArgument.pos)
1515
'{ ($strCtxExpr).s($argsExpr: _*) }
1616
}
1717

tests/neg-macros/tasty-string-interpolator-position-b/Macro_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ object Macro {
1010
object FIntepolator {
1111
def apply(strCtxExpr: Expr[StringContext], argsExpr: Expr[Seq[Any]])(using Quotes) : Expr[String] = {
1212
import quotes.reflect._
13-
report.error("there are no args", Term.of(argsExpr).underlyingArgument.pos)
13+
report.error("there are no args", argsExpr.asTerm.underlyingArgument.pos)
1414
'{ ($strCtxExpr).s($argsExpr: _*) }
1515
}
1616

tests/neg-staging/i5941/macro_1.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ object Lens {
1717
import util._
1818
// obj.copy(field = value)
1919
def setterBody(obj: Expr[S], value: Expr[T], field: String): Expr[S] =
20-
Select.overloaded(Term.of(obj), "copy", Nil, NamedArg(field, Term.of(value)) :: Nil, TypeBounds.empty).asExprOf[S]
20+
Select.overloaded(obj.asTerm, "copy", Nil, NamedArg(field, value.asTerm) :: Nil, TypeBounds.empty).asExprOf[S]
2121

2222
// exception: Term.of(getter).underlyingArgument
23-
Term.of(getter) match {
23+
getter.asTerm match {
2424
case Inlined(
2525
None, Nil,
2626
Block(

tests/pending/run/tasty-comments/quoted_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ object Macros {
99
def impl[T](x: Expr[T])(using Quotes) : Expr[Unit] = {
1010
import quotes.reflect._
1111

12-
val tree = Term.of(x)
12+
val tree = x.asTerm
1313
tree.symbol.comment.map(_.raw) match {
1414
case Some(str) => '{ println(${str}) }
1515
case None => '{ println() }

tests/pos-macros/i10151/Macro_1.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ object X:
6060
case l@Literal(x) =>
6161
l.asExpr match
6262
case '{ $l: lit } =>
63-
Term.of('{ CBM.pure(${term.asExprOf[lit]}) })
63+
'{ CBM.pure(${term.asExprOf[lit]}) }.asTerm
6464
case other =>
6565
throw RuntimeException(s"Not supported $other")
6666

@@ -89,5 +89,5 @@ object X:
8989
}
9090
changes.transformTerm(body)(Symbol.spliceOwner)
9191

92-
val r = transform(Term.of(f)).asExprOf[CB[T]]
92+
val r = transform(f.asTerm).asExprOf[CB[T]]
9393
r

tests/pos-macros/i10211/Macro_1.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,11 @@ object X:
6767
val tb = transform(b).asExprOf[CB[Int]]
6868
val mt = MethodType(List("p"))(_ => List(b.tpe.widen), _ => TypeRepr.of[Boolean])
6969
val mapLambda = Lambda(Symbol.spliceOwner, mt, (_, x) => Select.overloaded(obj,"==",List(),List(x.head.asInstanceOf[Term]))).asExprOf[Int=>Boolean]
70-
Term.of('{ CBM.map($tb)($mapLambda) })
70+
'{ CBM.map($tb)($mapLambda) }.asTerm
7171
case Block(stats, last) => Block(stats, transform(last))
7272
case Inlined(x,List(),body) => transform(body)
7373
case l@Literal(x) =>
74-
Term.of('{ CBM.pure(${term.asExpr}) })
74+
'{ CBM.pure(${term.asExpr}) }.asTerm
7575
case other =>
7676
throw RuntimeException(s"Not supported $other")
7777

@@ -99,4 +99,4 @@ object X:
9999
}
100100
changes.transformTerm(body)(Symbol.spliceOwner)
101101

102-
transform(Term.of(f)).asExprOf[CB[T]]
102+
transform(f.asTerm).asExprOf[CB[T]]

0 commit comments

Comments
 (0)