Skip to content

Commit 6813913

Browse files
committed
Improve Expr.toString and Type.toString
We now capture the context in each `Expr` and `Type` instead of the `Scope`. This context can be used to compute the `Scope`.
1 parent 779a382 commit 6813913

File tree

14 files changed

+69
-29
lines changed

14 files changed

+69
-29
lines changed

compiler/src/dotty/tools/dotc/quoted/PickledQuotes.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -197,18 +197,18 @@ object PickledQuotes {
197197
}
198198

199199
def reifyTypeHoleArgs(args: List[Tree])(using Context): List[scala.quoted.Type[?]] =
200-
args.map(arg => new TypeImpl(arg, SpliceScope.getCurrent))
200+
args.map(arg => new TypeImpl(arg))
201201

202202
def reifyExprHoleV1Args(args: List[Tree])(using Context): List[ExprHole.ArgV1] =
203203
args.map { arg =>
204-
if arg.isTerm then (q: Quotes) ?=> new ExprImpl(arg, SpliceScope.getCurrent)
205-
else new TypeImpl(arg, SpliceScope.getCurrent)
204+
if arg.isTerm then (q: Quotes) ?=> new ExprImpl(arg)
205+
else new TypeImpl(arg)
206206
}
207207

208208
def reifyExprHoleV2Args(args: List[Tree])(using Context): List[ExprHole.ArgV2] =
209209
args.map { arg =>
210-
if arg.isTerm then new ExprImpl(arg, SpliceScope.getCurrent)
211-
else new TypeImpl(arg, SpliceScope.getCurrent)
210+
if arg.isTerm then new ExprImpl(arg)
211+
else new TypeImpl(arg)
212212
}
213213

214214
// TASTY picklingtests/pos/quoteTest.scala

compiler/src/dotty/tools/dotc/transform/Splicer.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -237,11 +237,11 @@ object Splicer {
237237
case Inlined(EmptyTree, _, quoted) => quoted
238238
case _ => quoted
239239
}
240-
new ExprImpl(Inlined(EmptyTree, Nil, QuoteUtils.changeOwnerOfTree(quoted1, ctx.owner)).withSpan(quoted1.span), SpliceScope.getCurrent)
240+
new ExprImpl(Inlined(EmptyTree, Nil, QuoteUtils.changeOwnerOfTree(quoted1, ctx.owner)).withSpan(quoted1.span))
241241

242242
// Interpret level -1 `Type.of[T]`
243243
case Apply(TypeApply(fn, quoted :: Nil), _) if fn.symbol == defn.QuotedTypeModule_of =>
244-
new TypeImpl(QuoteUtils.changeOwnerOfTree(quoted, ctx.owner), SpliceScope.getCurrent)
244+
new TypeImpl(QuoteUtils.changeOwnerOfTree(quoted, ctx.owner))
245245

246246
case _ =>
247247
super.interpretTree(tree)

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package scala.quoted
22
package runtime.impl
33

44
import dotty.tools.dotc.ast.tpd
5+
import dotty.tools.dotc.core.Contexts.Context
56

67
/** An Expr backed by a tree. Only the current compiler trees are allowed.
78
*
@@ -10,7 +11,10 @@ import dotty.tools.dotc.ast.tpd
1011
*
1112
* May contain references to code defined outside this Expr instance.
1213
*/
13-
final class ExprImpl(val tree: tpd.Tree, val scope: Scope) extends Expr[Any] {
14+
final class ExprImpl(val tree: tpd.Tree)(using val ctx: Context) extends Expr[Any]:
15+
16+
def scope: Scope = SpliceScope.getCurrent
17+
1418
override def equals(that: Any): Boolean = that match {
1519
case that: ExprImpl =>
1620
// Expr are wrappers around trees, therefore they are equals if their trees are equal.
@@ -21,5 +25,4 @@ final class ExprImpl(val tree: tpd.Tree, val scope: Scope) extends Expr[Any] {
2125

2226
override def hashCode(): Int = tree.hashCode()
2327

24-
override def toString: String = "'{ ... }"
25-
}
28+
override def toString(): String = QuotesImpl.showDecompiledTree(tree)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ object QuoteMatcher {
462462
val matched: Matching = Some(Tuple())
463463

464464
def matched(tree: Tree)(using Context): Matching =
465-
Some(Tuple1(new ExprImpl(tree, SpliceScope.getCurrent)))
465+
Some(Tuple1(new ExprImpl(tree)))
466466

467467
extension (self: Matching)
468468
def asOptionOfTuple: Option[Tuple] = self

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
105105
case _ => false
106106
def asExpr: scala.quoted.Expr[Any] =
107107
if self.isExpr then
108-
new ExprImpl(self, SpliceScope.getCurrent)
108+
new ExprImpl(self)
109109
else self match
110110
case TermTypeTest(self) => throw new Exception("Expected an expression. This is a partially applied Term. Try eta-expanding the term first.")
111111
case _ => throw new Exception("Expected a Term but was: " + Printer.TreeStructure.show(self))
@@ -377,11 +377,11 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
377377
given TermMethods: TermMethods with
378378
extension (self: Term)
379379
def seal: scala.quoted.Expr[Any] =
380-
if self.isExpr then new ExprImpl(self, SpliceScope.getCurrent)
380+
if self.isExpr then new ExprImpl(self)
381381
else throw new Exception("Cannot seal a partially applied Term. Try eta-expanding the term first.")
382382

383383
def sealOpt: Option[scala.quoted.Expr[Any]] =
384-
if self.isExpr then Some(new ExprImpl(self, SpliceScope.getCurrent))
384+
if self.isExpr then Some(new ExprImpl(self))
385385
else None
386386

387387
def tpe: TypeRepr = self.tpe.widenSkolem
@@ -1722,7 +1722,7 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
17221722
def seal: scala.quoted.Type[_] = self.asType
17231723

17241724
def asType: scala.quoted.Type[?] =
1725-
new TypeImpl(Inferred(self), SpliceScope.getCurrent)
1725+
new TypeImpl(Inferred(self))
17261726

17271727
def =:=(that: TypeRepr): Boolean = self =:= that
17281728
def <:<(that: TypeRepr): Boolean = self <:< that
@@ -3048,19 +3048,19 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
30483048

30493049
def unpickleExpr[T](pickled: String | List[String], typeHole: (Int, Seq[Any]) => scala.quoted.Type[?], termHole: (Int, Seq[Any], scala.quoted.Quotes) => scala.quoted.Expr[?]): scala.quoted.Expr[T] =
30503050
val tree = PickledQuotes.unpickleTerm(pickled, PickledQuotes.TypeHole.V1(typeHole), PickledQuotes.ExprHole.V1(termHole))
3051-
new ExprImpl(tree, SpliceScope.getCurrent).asInstanceOf[scala.quoted.Expr[T]]
3051+
new ExprImpl(tree).asInstanceOf[scala.quoted.Expr[T]]
30523052

30533053
def unpickleExprV2[T](pickled: String | List[String], types: Seq[Type[?]], termHole: Null | ((Int, Seq[Type[?] | Expr[Any]], Quotes) => Expr[?])): scala.quoted.Expr[T] =
30543054
val tree = PickledQuotes.unpickleTerm(pickled, PickledQuotes.TypeHole.V2(types), PickledQuotes.ExprHole.V2(termHole))
3055-
new ExprImpl(tree, SpliceScope.getCurrent).asInstanceOf[scala.quoted.Expr[T]]
3055+
new ExprImpl(tree).asInstanceOf[scala.quoted.Expr[T]]
30563056

30573057
def unpickleType[T <: AnyKind](pickled: String | List[String], typeHole: (Int, Seq[Any]) => scala.quoted.Type[?], termHole: (Int, Seq[Any], scala.quoted.Quotes) => scala.quoted.Expr[?]): scala.quoted.Type[T] =
30583058
val tree = PickledQuotes.unpickleTypeTree(pickled, PickledQuotes.TypeHole.V1(typeHole))
3059-
new TypeImpl(tree, SpliceScope.getCurrent).asInstanceOf[scala.quoted.Type[T]]
3059+
new TypeImpl(tree).asInstanceOf[scala.quoted.Type[T]]
30603060

30613061
def unpickleTypeV2[T <: AnyKind](pickled: String | List[String], types: Seq[Type[?]]): scala.quoted.Type[T] =
30623062
val tree = PickledQuotes.unpickleTypeTree(pickled, PickledQuotes.TypeHole.V2(types))
3063-
new TypeImpl(tree, SpliceScope.getCurrent).asInstanceOf[scala.quoted.Type[T]]
3063+
new TypeImpl(tree).asInstanceOf[scala.quoted.Type[T]]
30643064

30653065
object ExprMatch extends ExprMatchModule:
30663066
def unapply[TypeBindings <: Tuple, Tup <: Tuple](scrutinee: scala.quoted.Expr[Any])(using pattern: scala.quoted.Expr[Any]): Option[Tup] =

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

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,13 @@ package scala.quoted
22
package runtime.impl
33

44
import dotty.tools.dotc.ast.tpd
5+
import dotty.tools.dotc.core.Contexts.Context
56

67
/** Quoted type (or kind) `T` backed by a tree */
7-
final class TypeImpl(val typeTree: tpd.Tree, val scope: Scope) extends Type[?] {
8+
final class TypeImpl(val typeTree: tpd.Tree)(using val ctx: Context) extends Type[?]:
9+
10+
def scope: Scope = SpliceScope.getCurrent
11+
812
override def equals(that: Any): Boolean = that match {
913
case that: TypeImpl => typeTree ==
1014
// TastyTreeExpr are wrappers around trees, therefore they are equals if their trees are equal.
@@ -15,5 +19,4 @@ final class TypeImpl(val typeTree: tpd.Tree, val scope: Scope) extends Type[?] {
1519

1620
override def hashCode(): Int = typeTree.hashCode()
1721

18-
override def toString: String = "Type.of[...]"
19-
}
22+
override def toString: String = QuotesImpl.showDecompiledTree(typeTree)

tests/pos-with-compiler-cc/dotc/quoted/PickledQuotes.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -196,18 +196,18 @@ object PickledQuotes {
196196
}
197197

198198
def reifyTypeHoleArgs(args: List[Tree])(using Context): List[scala.quoted.Type[?]] =
199-
args.map(arg => new TypeImpl(arg, SpliceScope.getCurrent))
199+
args.map(arg => new TypeImpl(arg)(using ctx.detach))
200200

201201
def reifyExprHoleV1Args(args: List[Tree])(using Context): List[ExprHole.ArgV1] =
202202
args.map { arg =>
203-
if arg.isTerm then (q: Quotes) ?=> new ExprImpl(arg, SpliceScope.getCurrent)
204-
else new TypeImpl(arg, SpliceScope.getCurrent)
203+
if arg.isTerm then (q: Quotes) ?=> new ExprImpl(arg)(using ctx.detach)
204+
else new TypeImpl(arg)(using ctx.detach)
205205
}
206206

207207
def reifyExprHoleV2Args(args: List[Tree])(using Context): List[ExprHole.ArgV2] =
208208
args.map { arg =>
209-
if arg.isTerm then new ExprImpl(arg, SpliceScope.getCurrent)
210-
else new TypeImpl(arg, SpliceScope.getCurrent)
209+
if arg.isTerm then new ExprImpl(arg)(using ctx.detach)
210+
else new TypeImpl(arg)(using ctx.detach)
211211
}
212212

213213
// TASTY picklingtests/pos/quoteTest.scala

tests/pos-with-compiler-cc/dotc/transform/Splicer.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,11 @@ object Splicer {
241241
case Inlined(EmptyTree, _, quoted) => quoted
242242
case _ => quoted
243243
}
244-
new ExprImpl(Inlined(EmptyTree, Nil, QuoteUtils.changeOwnerOfTree(quoted1, ctx.owner)).withSpan(quoted1.span), SpliceScope.getCurrent)
244+
new ExprImpl(Inlined(EmptyTree, Nil, QuoteUtils.changeOwnerOfTree(quoted1, ctx.owner)).withSpan(quoted1.span))(using ctx.detach)
245245

246246
// Interpret level -1 `Type.of[T]`
247247
case Apply(TypeApply(fn, quoted :: Nil), _) if fn.symbol == defn.QuotedTypeModule_of =>
248-
new TypeImpl(QuoteUtils.changeOwnerOfTree(quoted, ctx.owner), SpliceScope.getCurrent)
248+
new TypeImpl(QuoteUtils.changeOwnerOfTree(quoted, ctx.owner))(using ctx.detach)
249249

250250
case _ =>
251251
super.interpretTree(tree)

tests/run-macros/Expr-toString.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
1
2+
"abc"
3+
scala.Predef.println("abc")
4+
while (true) ()
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import scala.quoted.*
2+
3+
inline def showToString(inline x: Any): String = ${ macroImpl('x) }
4+
5+
private def macroImpl(x: Expr[Any])(using Quotes): Expr[String] =
6+
Expr(x.toString)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@main def Test() =
2+
println(showToString(1))
3+
println(showToString("abc"))
4+
println(showToString(println("abc")))
5+
println(showToString { while true do () } )

tests/run-macros/Type-toString.check

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
1
2+
"abc"
3+
scala.Int
4+
scala.collection.immutable.List[scala.Int]
5+
java.lang.Object {
6+
def foo: scala.Int
7+
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import scala.quoted.*
2+
3+
inline def showToString[T]: String = ${ macroImpl[T] }
4+
5+
private def macroImpl[T: Type](using Quotes): Expr[String] =
6+
Expr(Type.of[T].toString)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@main def Test() =
2+
println(showToString[1])
3+
println(showToString["abc"])
4+
println(showToString[Int])
5+
println(showToString[List[Int]])
6+
println(showToString[Object { def foo: Int }])

0 commit comments

Comments
 (0)