Skip to content

Commit a3a157f

Browse files
committed
Rename reflect/reify and make them plain methods
Remove implicit conversion of the extension methods from the API
1 parent 0a1aed2 commit a3a157f

File tree

24 files changed

+79
-93
lines changed

24 files changed

+79
-93
lines changed

compiler/src/dotty/tools/dotc/tastyreflect/QuotedOpsImpl.scala

Lines changed: 29 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,43 +7,38 @@ import dotty.tools.dotc.reporting.diagnostic.MessageContainer
77

88
trait QuotedOpsImpl extends scala.tasty.reflect.QuotedOps with CoreImpl {
99

10-
def QuotedExprDeco[T](x: scala.quoted.Expr[T]): QuotedExprAPI = new QuotedExprAPI {
11-
def reflect(implicit ctx: Context): Term = PickledQuotes.quotedExprToTree(x)
12-
}
10+
def exprToTree[T](expr: scala.quoted.Expr[T])(implicit ctx: Context): Term =
11+
PickledQuotes.quotedExprToTree(expr)
1312

14-
def QuotedTypeDeco[T](x: scala.quoted.Type[T]): QuotedTypeAPI = new QuotedTypeAPI {
15-
def reflect(implicit ctx: Context): TypeTree = PickledQuotes.quotedTypeToTree(x)
16-
}
13+
def typeToTypeTree[T](tp: scala.quoted.Type[T])(implicit ctx: Context): TypeTree =
14+
PickledQuotes.quotedTypeToTree(tp)
1715

18-
def TermToQuoteDeco(term: Term): TermToQuotedAPI = new TermToQuotedAPI {
16+
def treeToExprOf[T: scala.quoted.Type](term: Term)(implicit ctx: Context): scala.quoted.Expr[T] =
17+
new scala.quoted.Exprs.TastyTreeExpr(typechecked[T](term)(ctx)).asInstanceOf[scala.quoted.Expr[T]]
1918

20-
def reify[T: scala.quoted.Type](implicit ctx: Context): scala.quoted.Expr[T] = {
21-
typecheck(ctx)
22-
new scala.quoted.Exprs.TastyTreeExpr(term).asInstanceOf[scala.quoted.Expr[T]]
23-
}
24-
25-
private def typecheck[T: scala.quoted.Type](ctx: Context): Unit = {
26-
implicit val ctx0: FreshContext = ctx.fresh
27-
ctx0.setTyperState(ctx0.typerState.fresh())
28-
ctx0.typerState.setReporter(new Reporter {
29-
def doReport(m: MessageContainer)(implicit ctx: Context): Unit = ()
30-
})
31-
val tp = QuotedTypeDeco(implicitly[scala.quoted.Type[T]]).reflect
32-
ctx0.typer.typed(term, tp.tpe)
33-
if (ctx0.reporter.hasErrors) {
34-
val stack = new Exception().getStackTrace
35-
def filter(elem: StackTraceElement) =
36-
elem.getClassName.startsWith("dotty.tools.dotc.tasty.ReflectionImpl") ||
37-
!elem.getClassName.startsWith("dotty.tools.dotc")
38-
throw new scala.tasty.TastyTypecheckError(
39-
s"""Error during tasty reflection while typing term
40-
|term: ${term.show}
41-
|with expected type: ${tp.tpe.show}
42-
|
43-
| ${stack.takeWhile(filter).mkString("\n ")}
44-
""".stripMargin
45-
)
46-
}
19+
private def typechecked[T: scala.quoted.Type](term: Term)(ctx: Context): term.type = {
20+
implicit val ctx0: FreshContext = ctx.fresh
21+
ctx0.setTyperState(ctx0.typerState.fresh())
22+
ctx0.typerState.setReporter(new Reporter {
23+
def doReport(m: MessageContainer)(implicit ctx: Context): Unit = ()
24+
})
25+
val tp = typeToTypeTree(implicitly[scala.quoted.Type[T]])
26+
ctx0.typer.typed(term, tp.tpe)
27+
if (ctx0.reporter.hasErrors) {
28+
val stack = new Exception().getStackTrace
29+
def filter(elem: StackTraceElement) =
30+
elem.getClassName.startsWith("dotty.tools.dotc.tasty.ReflectionImpl") ||
31+
!elem.getClassName.startsWith("dotty.tools.dotc")
32+
throw new scala.tasty.TastyTypecheckError(
33+
s"""Error during tasty reflection while typing term
34+
|term: ${term.show}
35+
|with expected type: ${tp.tpe.show}
36+
|
37+
| ${stack.takeWhile(filter).mkString("\n ")}
38+
""".stripMargin
39+
)
4740
}
41+
term
4842
}
43+
4944
}

library/src/scala/tasty/reflect/QuotedOps.scala

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,13 @@ package scala.tasty.reflect
33
/** Extension methods on scala.quoted.{Expr|Type} to convert to scala.tasty.Tasty objects */
44
trait QuotedOps extends Core {
55

6-
trait QuotedExprAPI {
7-
/** View this expression `Expr[T]` as a `Term` */
8-
def reflect(implicit ctx: Context): Term
9-
}
10-
implicit def QuotedExprDeco[T](expr: quoted.Expr[T]): QuotedExprAPI
6+
/** View this expression `scala.quoted.Expr[T]` as a `scala.tasty.Reflection.Term` tree. */
7+
def exprToTree[T](expr: scala.quoted.Expr[T])(implicit ctx: Context): Term
118

12-
trait QuotedTypeAPI {
13-
/** View this expression `Type[T]` as a `TypeTree` */
14-
def reflect(implicit ctx: Context): TypeTree
15-
}
16-
implicit def QuotedTypeDeco[T](tpe: quoted.Type[T]): QuotedTypeAPI
9+
/** View this expression `scala.quoted.Type[T]` as a `scala.tasty.Reflection.TypeTree` */
10+
def typeToTypeTree[T](tp: scala.quoted.Type[T])(implicit ctx: Context): TypeTree
1711

18-
trait TermToQuotedAPI {
19-
/** Convert `Term` to an `Expr[T]` and check that it conforms to `T` */
20-
def reify[T: scala.quoted.Type](implicit ctx: Context): scala.quoted.Expr[T]
21-
}
22-
implicit def TermToQuoteDeco(term: Term): TermToQuotedAPI
12+
/** Convert `scala.tasty.Reflection.Term` to an `scala.quoted.Expr[T]` and check that it conforms to `T` */
13+
def treeToExprOf[T: scala.quoted.Type](term: Term)(implicit ctx: Context): scala.quoted.Expr[T]
2314

2415
}

library/src/scala/tasty/util/ConstantExtractor.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,6 @@ class ConstantExtractor[R <: Reflection with Singleton](val reflect: Reflection)
2525
case Term.Inlined(_, Nil, e) => const(e)
2626
case _ => None
2727
}
28-
const(expr.reflect)
28+
const(exprToTree(expr))
2929
}
3030
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ object Asserts {
1717
def impl(cond: Expr[Boolean])(implicit reflect: Reflection): Expr[Unit] = {
1818
import reflect._
1919

20-
val tree = cond.reflect
20+
val tree = exprToTree(cond)
2121

2222
def isOps(tpe: TypeOrBounds): Boolean = tpe match {
2323
case Type.SymRef(IsDefSymbol(sym), _) => sym.name == "Ops" // TODO check that the parent is Asserts
@@ -34,7 +34,7 @@ object Asserts {
3434

3535
tree match {
3636
case Term.Inlined(_, Nil, Term.Apply(Term.Select(OpsTree(left), op, _), right :: Nil)) =>
37-
'(assertTrue(~left.reify[Boolean])) // Buggy code. To generate the errors
37+
'(assertTrue(~treeToExprOf[Boolean](left))) // Buggy code. To generate the errors
3838
case _ =>
3939
'(assertTrue(~cond))
4040
}

tests/run-custom-args/Yretain-trees/tasty-definitions-2/Macro_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ object Foo {
1313
case IsValSymbol(sym) => sym.tree.show.toExpr
1414
case IsBindSymbol(sym) => sym.tree.show.toExpr
1515
}
16-
x.reflect match {
16+
exprToTree(x) match {
1717
case Term.Inlined(None, Nil, arg) => definitionString(arg)
1818
case arg => definitionString(arg) // TODO should all by name parameters be in an inline node?
1919
}

tests/run-custom-args/Yretain-trees/tasty-definitions-3/Macro_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ object Foo {
1313
case IsValSymbol(sym) => sym.tree.show.toExpr
1414
case IsBindSymbol(sym) => sym.tree.show.toExpr
1515
}
16-
x.reflect match {
16+
exprToTree(x) match {
1717
case Term.Inlined(None, Nil, arg) => definitionString(arg)
1818
case arg => definitionString(arg) // TODO should all by name parameters be in an inline node?
1919
}

tests/run-custom-args/Yretain-trees/tasty-extractors-owners/quoted_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ object Macros {
4040
}
4141
}
4242

43-
val tree = x.reflect
43+
val tree = exprToTree(x)
4444
output.traverseTree(tree)
4545
'(print(~buff.result().toExpr))
4646
}

tests/run-custom-args/Yretain-trees/tasty-load-tree-1/quoted_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ object Foo {
1717
case _ => '("NO DEFINTION")
1818
}
1919

20-
x.reflect match {
20+
exprToTree(x) match {
2121
case Term.Inlined(None, Nil, arg) => definitionString(arg)
2222
case arg => definitionString(arg) // TODO should all by name parameters be in an inline node
2323
}

tests/run-custom-args/Yretain-trees/tasty-load-tree-2/quoted_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ object Foo {
1717
case _ => '("NO DEFINTION")
1818
}
1919

20-
x.reflect match {
20+
exprToTree(x) match {
2121
case Term.Inlined(None, Nil, arg) => definitionString(arg)
2222
case arg => definitionString(arg) // TODO should all by name parameters be in an inline node
2323
}

tests/run-separate-compilation/gestalt-type-toolbox-reflect/Macro_1.scala

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,31 +9,31 @@ object TypeToolbox {
99
inline def =:=[A, B]: Boolean = ~tpEqImpl('[A], '[B])
1010
private def tpEqImpl[A, B](a: Type[A], b: Type[B])(implicit reflect: Reflection): Expr[Boolean] = {
1111
import reflect._
12-
val res = a.reflect.tpe =:= b.reflect.tpe
12+
val res = typeToTypeTree(a).tpe =:= typeToTypeTree(b).tpe
1313
res.toExpr
1414
}
1515

1616
/** is `tp1` a subtype of `tp2` */
1717
inline def <:<[A, B]: Boolean = ~tpLEqImpl('[A], '[B])
1818
private def tpLEqImpl[A, B](a: Type[A], b: Type[B])(implicit reflect: Reflection): Expr[Boolean] = {
1919
import reflect._
20-
val res = a.reflect.tpe <:< b.reflect.tpe
20+
val res = typeToTypeTree(a).tpe <:< typeToTypeTree(b).tpe
2121
res.toExpr
2222
}
2323

2424
/** type associated with the tree */
2525
inline def typeOf[T, Expected](a: T): Boolean = ~typeOfImpl('(a), '[Expected])
2626
private def typeOfImpl(a: Expr[_], expected: Type[_])(implicit reflect: Reflection): Expr[Boolean] = {
2727
import reflect._
28-
val res = a.reflect.tpe =:= expected.reflect.tpe
28+
val res = exprToTree(a).tpe =:= typeToTypeTree(expected).tpe
2929
res.toExpr
3030
}
3131

3232
/** does the type refer to a case class? */
3333
inline def isCaseClass[A]: Boolean = ~isCaseClassImpl('[A])
3434
private def isCaseClassImpl(tp: Type[_])(implicit reflect: Reflection): Expr[Boolean] = {
3535
import reflect._
36-
val res = tp.reflect.symbol match {
36+
val res = typeToTypeTree(tp).symbol match {
3737
case IsClassSymbol(sym) => sym.flags.isCase
3838
case _ => false
3939
}
@@ -44,66 +44,66 @@ object TypeToolbox {
4444
inline def caseFields[T]: List[String] = ~caseFieldsImpl('[T])
4545
private def caseFieldsImpl(tp: Type[_])(implicit reflect: Reflection): Expr[List[String]] = {
4646
import reflect._
47-
val fields = tp.reflect.symbol.asClass.caseFields.map(_.name)
47+
val fields = typeToTypeTree(tp).symbol.asClass.caseFields.map(_.name)
4848
fields.toExpr
4949
}
5050

5151
inline def fieldIn[T](inline mem: String): String = ~fieldInImpl('[T], mem)
5252
private def fieldInImpl(t: Type[_], mem: String)(implicit reflect: Reflection): Expr[String] = {
5353
import reflect._
54-
val field = t.reflect.symbol.asClass.field(mem)
54+
val field = typeToTypeTree(t).symbol.asClass.field(mem)
5555
field.map(_.name).getOrElse("").toExpr
5656
}
5757

5858
inline def fieldsIn[T]: Seq[String] = ~fieldsInImpl('[T])
5959
private def fieldsInImpl(t: Type[_])(implicit reflect: Reflection): Expr[Seq[String]] = {
6060
import reflect._
61-
val fields = t.reflect.symbol.asClass.fields
61+
val fields = typeToTypeTree(t).symbol.asClass.fields
6262
fields.map(_.name).toList.toExpr
6363
}
6464

6565
inline def methodIn[T](inline mem: String): Seq[String] = ~methodInImpl('[T], mem)
6666
private def methodInImpl(t: Type[_], mem: String)(implicit reflect: Reflection): Expr[Seq[String]] = {
6767
import reflect._
68-
t.reflect.symbol.asClass.classMethod(mem).map(_.name).toExpr
68+
typeToTypeTree(t).symbol.asClass.classMethod(mem).map(_.name).toExpr
6969
}
7070

7171
inline def methodsIn[T]: Seq[String] = ~methodsInImpl('[T])
7272
private def methodsInImpl(t: Type[_])(implicit reflect: Reflection): Expr[Seq[String]] = {
7373
import reflect._
74-
t.reflect.symbol.asClass.classMethods.map(_.name).toExpr
74+
typeToTypeTree(t).symbol.asClass.classMethods.map(_.name).toExpr
7575
}
7676

7777
inline def method[T](inline mem: String): Seq[String] = ~methodImpl('[T], mem)
7878
private def methodImpl(t: Type[_], mem: String)(implicit reflect: Reflection): Expr[Seq[String]] = {
7979
import reflect._
80-
t.reflect.symbol.asClass.method(mem).map(_.name).toExpr
80+
typeToTypeTree(t).symbol.asClass.method(mem).map(_.name).toExpr
8181
}
8282

8383
inline def methods[T]: Seq[String] = ~methodsImpl('[T])
8484
private def methodsImpl(t: Type[_])(implicit reflect: Reflection): Expr[Seq[String]] = {
8585
import reflect._
86-
t.reflect.symbol.asClass.methods.map(_.name).toExpr
86+
typeToTypeTree(t).symbol.asClass.methods.map(_.name).toExpr
8787
}
8888

8989
inline def typeTag[T](x: T): String = ~typeTagImpl('[T])
9090
private def typeTagImpl(tp: Type[_])(implicit reflect: Reflection): Expr[String] = {
9191
import reflect._
92-
val res = tp.reflect.tpe.showCode
92+
val res = typeToTypeTree(tp).tpe.showCode
9393
res.toExpr
9494
}
9595

9696
inline def companion[T1, T2]: Boolean = ~companionImpl('[T1], '[T2])
9797
private def companionImpl(t1: Type[_], t2: Type[_])(implicit reflect: Reflection): Expr[Boolean] = {
9898
import reflect._
99-
val res = t1.reflect.symbol.asClass.companionModule.contains(t2.reflect.symbol)
99+
val res = typeToTypeTree(t1).symbol.asClass.companionModule.contains(typeToTypeTree(t2).symbol)
100100
res.toExpr
101101
}
102102

103103
inline def companionName[T1]: String = ~companionNameImpl('[T1])
104104
private def companionNameImpl(tp: Type[_])(implicit reflect: Reflection): Expr[String] = {
105105
import reflect._
106-
val companionClassOpt = tp.reflect.symbol match {
106+
val companionClassOpt = typeToTypeTree(tp).symbol match {
107107
case IsClassSymbol(sym) => sym.companionClass
108108
case IsValSymbol(sym) => sym.companionClass
109109
case _ => None

tests/run-separate-compilation/i5119/Macro_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@ object Macro {
88
implicit inline def XmlQuote(sc: => StringContext): StringContextOps = new StringContextOps(sc)
99
def impl(sc: Expr[StringContext], args: Expr[Seq[Any]])(implicit reflect: Reflection): Expr[String] = {
1010
import reflect._
11-
(sc.reflect.underlyingArgument.show + "\n" + args.reflect.underlyingArgument.show).toExpr
11+
(exprToTree(sc).underlyingArgument.show + "\n" + exprToTree(args).underlyingArgument.show).toExpr
1212
}
1313
}

tests/run-separate-compilation/i5119b/Macro_1.scala

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

88
def impl(arg1: Expr[Any], arg2: Expr[Any])(implicit reflect: Reflection): Expr[String] = {
99
import reflect._
10-
(arg1.reflect.underlyingArgument.show + "\n" + arg2.reflect.underlyingArgument.show).toExpr
10+
(exprToTree(arg1).underlyingArgument.show + "\n" + exprToTree(arg2).underlyingArgument.show).toExpr
1111
}
1212

1313
}

tests/run-separate-compilation/tasty-argument-tree-1/quoted_1.scala

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

88
def impl[T](x: Expr[T])(implicit reflect: Reflection): Expr[Unit] = {
99
import reflect._
10-
val tree = x.reflect
10+
val tree = exprToTree(x)
1111
'{
1212
println()
1313
println("tree: " + ~tree.show.toExpr)

tests/run-separate-compilation/tasty-custom-show/quoted_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ object Macros {
3333
}
3434
}
3535

36-
val tree = x.reflect
36+
val tree = exprToTree(x)
3737
output.traverseTree(tree)
3838
'(print(~buff.result().toExpr))
3939
}

tests/run-separate-compilation/tasty-eval/quoted_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ object Macros {
2121
override def value(e: Expr[Int])(implicit reflect: Reflection): Option[Int] = {
2222
import reflect._
2323

24-
e.reflect.tpe match {
24+
exprToTree(e).tpe match {
2525
case Type.SymRef(IsValSymbol(sym), pre) =>
2626
sym.tree.tpt.tpe match {
2727
case Type.ConstantType(Constant.Int(i)) => Some(i)

tests/run-separate-compilation/tasty-extractors-1/quoted_1.scala

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

13-
val tree = x.reflect
13+
val tree = exprToTree(x)
1414
val treeStr = tree.show
1515
val treeTpeStr = tree.tpe.show
1616

tests/run-separate-compilation/tasty-extractors-2/quoted_1.scala

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

13-
val tree = x.reflect
13+
val tree = exprToTree(x)
1414

1515
val treeStr = tree.show
1616
val treeTpeStr = tree.tpe.show

tests/run-separate-compilation/tasty-extractors-3/quoted_1.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ object Macros {
1919
}
2020
}
2121

22-
val tree = x.reflect
22+
val tree = exprToTree(x)
2323
traverser.traverseTree(tree)
2424
'(print(~buff.result().toExpr))
2525
}

tests/run-separate-compilation/tasty-extractors-types/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: Type[T])(implicit reflect: Reflection): Expr[Unit] = {
1010
import reflect._
1111

12-
val tree = x.reflect
12+
val tree = typeToTypeTree(x)
1313
'{
1414
println(~tree.show.toExpr)
1515
println(~tree.tpe.show.toExpr)

tests/run-separate-compilation/tasty-indexed-map/quoted_1.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,8 @@ object Index {
3838
case _ => Nil
3939
}
4040

41-
val key = name(k.reflect.tpe)
42-
val keys = name(h.reflect.tpe) :: names(t.reflect.tpe)
41+
val key = name(typeToTypeTree(k).tpe)
42+
val keys = name(typeToTypeTree(h).tpe) :: names(typeToTypeTree(t).tpe)
4343

4444
val index = keys.indexOf(key)
4545

tests/run-separate-compilation/tasty-macro-assert/quoted_1.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ object Asserts {
1717
def impl(cond: Expr[Boolean])(implicit reflect: Reflection): Expr[Unit] = {
1818
import reflect._
1919

20-
val tree = cond.reflect
20+
val tree = exprToTree(cond)
2121

2222
def isOps(tpe: TypeOrBounds): Boolean = tpe match {
2323
case Type.SymRef(IsDefSymbol(sym), _) => sym.name == "Ops"// TODO check that the parent is Asserts
@@ -35,8 +35,8 @@ object Asserts {
3535
tree match {
3636
case Term.Inlined(_, Nil, Term.Apply(Term.Select(OpsTree(left), op, _), right :: Nil)) =>
3737
op match {
38-
case "===" => '(assertEquals(~left.reify[Any], ~right.reify[Any]))
39-
case "!==" => '(assertNotEquals(~left.reify[Any], ~right.reify[Any]))
38+
case "===" => '(assertEquals(~treeToExprOf[Any](left), ~treeToExprOf[Any](right)))
39+
case "!==" => '(assertNotEquals(~treeToExprOf[Any](left), ~treeToExprOf[Any](right)))
4040
}
4141
case _ =>
4242
'(assertTrue(~cond))

0 commit comments

Comments
 (0)