Skip to content

Commit def3c4e

Browse files
committed
Move tasty.Reflection in QuoteContext
1 parent c22eb4b commit def3c4e

File tree

116 files changed

+357
-329
lines changed

Some content is hidden

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

116 files changed

+357
-329
lines changed

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -762,6 +762,12 @@ class Definitions {
762762
@threadUnsafe lazy val QuotedExprType: TypeRef = ctx.requiredClassRef("scala.quoted.Expr")
763763
def QuotedExprClass(implicit ctx: Context): ClassSymbol = QuotedExprType.symbol.asClass
764764

765+
@threadUnsafe lazy val QuoteContextType: TypeRef = ctx.requiredClassRef("scala.quoted.QuoteContext")
766+
def QuoteContextClass(implicit ctx: Context): ClassSymbol = QuoteContextType.symbol.asClass
767+
768+
@threadUnsafe lazy val QuoteContextModule: TermSymbol = ctx.requiredModule("scala.quoted.QuoteContext")
769+
@threadUnsafe lazy val QuoteContext_macroContext: TermSymbol = QuoteContextModule.requiredMethod("macroContext")
770+
765771
@threadUnsafe lazy val InternalQuotedModuleRef: TermRef = ctx.requiredModuleRef("scala.internal.Quoted")
766772
def InternalQuotedModule: Symbol = InternalQuotedModuleRef.symbol
767773
@threadUnsafe lazy val InternalQuoted_exprQuoteR: TermRef = InternalQuotedModule.requiredMethodRef("exprQuote")

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
166166
l == level ||
167167
level == -1 && (
168168
sym == defn.TastyReflection_macroContext ||
169+
sym == defn.QuoteContext_macroContext ||
169170
// here we assume that Splicer.canBeSpliced was true before going to level -1,
170171
// this implies that all non-inline arguments are quoted and that the following two cases are checked
171172
// on inline parameters or type parameters.

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,8 @@ object Splicer {
114114
args.toSeq
115115

116116
protected def interpretTastyContext()(implicit env: Env): Object = ReflectionImpl(ctx, pos)
117+
protected def interpretQuoteContext()(implicit env: Env): Object =
118+
new scala.quoted.QuoteContext(ReflectionImpl(ctx, pos))
117119

118120
protected def interpretStaticMethodCall(moduleClass: Symbol, fn: Symbol, args: => List[Object])(implicit env: Env): Object = {
119121
val (inst, clazz) =
@@ -308,6 +310,7 @@ object Splicer {
308310
protected def interpretLiteral(value: Any)(implicit env: Env): Result
309311
protected def interpretVarargs(args: List[Result])(implicit env: Env): Result
310312
protected def interpretTastyContext()(implicit env: Env): Result
313+
protected def interpretQuoteContext()(implicit env: Env): Result
311314
protected def interpretStaticMethodCall(module: Symbol, fn: Symbol, args: => List[Result])(implicit env: Env): Result
312315
protected def interpretModuleAccess(fn: Symbol)(implicit env: Env): Result
313316
protected def interpretNew(fn: Symbol, args: => List[Result])(implicit env: Env): Result
@@ -333,6 +336,9 @@ object Splicer {
333336
case _ if tree.symbol == defn.TastyReflection_macroContext =>
334337
interpretTastyContext()
335338

339+
case _ if tree.symbol == defn.QuoteContext_macroContext =>
340+
interpretQuoteContext()
341+
336342
case Call(fn, args) =>
337343
if (fn.symbol.isConstructor && fn.symbol.owner.owner.is(Package)) {
338344
interpretNew(fn.symbol, args.map(interpretTree))

compiler/src/dotty/tools/dotc/typer/Implicits.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,11 @@ trait Implicits { self: Typer =>
707707
if (ctx.inInlineMethod || enclosingInlineds.nonEmpty) ref(defn.TastyReflection_macroContext)
708708
else EmptyTree
709709

710+
lazy val synthesizedQuoteContext: SpecialHandler =
711+
(formal, span) => implicit ctx =>
712+
if (ctx.inInlineMethod || enclosingInlineds.nonEmpty) ref(defn.QuoteContext_macroContext)
713+
else EmptyTree
714+
710715
lazy val synthesizedTupleFunction: SpecialHandler =
711716
(formal, span) => implicit ctx => formal match {
712717
case AppliedType(_, funArgs @ fun :: tupled :: Nil) =>
@@ -1033,9 +1038,10 @@ trait Implicits { self: Typer =>
10331038
mySpecialHandlers = List(
10341039
defn.ClassTagClass -> synthesizedClassTag,
10351040
defn.QuotedTypeClass -> synthesizedTypeTag,
1041+
defn.QuoteContextClass -> synthesizedQuoteContext,
10361042
defn.TastyReflectionClass -> synthesizedTastyContext,
10371043
defn.EqlClass -> synthesizedEq,
1038-
defn.TupledFunctionClass -> synthesizedTupleFunction,
1044+
defn.TupledFunctionClass -> synthesizedTupleFunction,
10391045
defn.ValueOfClass -> synthesizedValueOf,
10401046
defn.Mirror_ProductClass -> synthesizedProductMirror,
10411047
defn.Mirror_SumClass -> synthesizedSumMirror,

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1982,7 +1982,7 @@ class Typer extends Namer
19821982
fun = ref(defn.InternalQuotedMatcher_unapplyR).appliedToType(patType),
19831983
implicits =
19841984
ref(defn.InternalQuoted_exprQuoteR).appliedToType(shape.tpe).appliedTo(shape) ::
1985-
implicitArgTree(defn.TastyReflectionType, tree.span) :: Nil,
1985+
implicitArgTree(defn.QuoteContextType, tree.span) :: Nil,
19861986
patterns = splicePat :: Nil,
19871987
proto = pt)
19881988
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ the following way.
1818
```scala
1919
class Consumer extends TastyConsumer {
2020
final def apply(reflect: Reflection)(root: reflect.Tree): Unit = {
21-
import reflect._
21+
import qctx.tasty._
2222
// Do something with the tree
2323
}
2424
}

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

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,23 +29,23 @@ import scala.tasty._
2929

3030
inline def natConst(x: => Int): Int = ${natConstImpl('{x})}
3131

32-
def natConstImpl(x: Expr[Int])(implicit reflection: Reflection): Expr[Int] = {
33-
import reflection._
32+
def natConstImpl(x: Expr[Int]) given (qctx: QuoteContext): Expr[Int] = {
33+
import qctx.tasty._
3434
...
3535
}
3636
```
3737

3838
### Sealing and Unsealing
3939

40-
`import reflection._` will provide an `unseal` extension method on `quoted.Expr`
40+
`import qctx.tasty._` will provide an `unseal` extension method on `quoted.Expr`
4141
and `quoted.Type` which returns a `reflection.Term` that represents the tree of
4242
the expression and `reflection.TypeTree` that represents the tree of the type
4343
respectively. It will also import all extractors and methods on TASTy Reflect
4444
trees. For example the `Literal(_)` extractor used below.
4545

4646
```scala
47-
def natConstImpl(x: Expr[Int])(implicit reflection: Reflection): Expr[Int] = {
48-
import reflection._
47+
def natConstImpl(x: Expr[Int]) given (qctx: QuoteContext): Expr[Int] = {
48+
import qctx.tasty._
4949
val xTree: Term = x.unseal
5050
xTree match {
5151
case Term.Literal(Constant.Int(n)) =>
@@ -77,8 +77,8 @@ operation expression passed while calling the `macro` below.
7777
```scala
7878
inline def macro(param: => Boolean): Unit = ${ macroImpl('param) }
7979

80-
def macroImpl(param: Expr[Boolean])(implicit refl: Reflection): Expr[Unit] = {
81-
import refl._
80+
def macroImpl(param: Expr[Boolean]) given (qctx: QuoteContext): Expr[Unit] = {
81+
import qctx.tasty._
8282
import util._
8383

8484
param.unseal.underlyingArgument match {

library/src-3.x/scala/internal/quoted/Matcher.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import scala.annotation.internal.sharable
44

55
import scala.quoted._
66
import scala.quoted.matching.Bind
7-
import scala.tasty._
87

98
object Matcher {
109

@@ -27,12 +26,11 @@ object Matcher {
2726
*
2827
* @param scrutineeExpr `Expr[_]` on which we are pattern matching
2928
* @param patternExpr `Expr[_]` containing the pattern tree
30-
* @param reflection instance of the reflection API (implicitly provided by the macro)
29+
* @param qctx the current QuoteContext
3130
* @return None if it did not match, `Some(tup)` if it matched where `tup` contains `Expr[Ti]``
3231
*/
33-
def unapply[Tup <: Tuple](scrutineeExpr: Expr[_])(implicit patternExpr: Expr[_], reflection: Reflection): Option[Tup] = {
34-
// TODO improve performance
35-
import reflection.{Bind => BindPattern, _}
32+
def unapply[Tup <: Tuple](scrutineeExpr: Expr[_])(implicit patternExpr: Expr[_], qctx: QuoteContext): Option[Tup] = {
33+
import qctx.tasty.{Bind => BindPattern, _}
3634
import Matching._
3735

3836
type Env = Set[(Symbol, Symbol)]

library/src-3.x/scala/quoted/matching/Bind.scala

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package scala.quoted
22
package matching
33

4-
import scala.tasty.Reflection // TODO do not depend on reflection directly
5-
64
/** Bind of an Expr[T] used to know if some Expr[T] is a reference to the binding
75
*
86
* @param name string name of this binding
@@ -21,8 +19,8 @@ class Bind[T <: AnyKind] private[scala](val name: String, private[Bind] val id:
2119

2220
object Bind {
2321

24-
def unapply[T](expr: Expr[T])(implicit reflect: Reflection): Option[Bind[T]] = {
25-
import reflect.{Bind => BindPattern, _}
22+
def unapply[T](expr: Expr[T]) given (qctx: QuoteContext): Option[Bind[T]] = {
23+
import qctx.tasty.{Bind => BindPattern, _}
2624
expr.unseal match {
2725
case IsIdent(ref) =>
2826
val sym = ref.symbol

library/src-3.x/scala/quoted/matching/Const.scala

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
1-
package scala.quoted.matching
2-
3-
import scala.quoted.Expr
4-
5-
import scala.tasty.Reflection // TODO do not depend on reflection directly
1+
package scala.quoted
2+
package matching
63

74
/** Matches expressions containing literal constant values and extracts the value.
85
* It may match expressions of type Boolean, Byte, Short, Int, Long,
@@ -17,8 +14,8 @@ import scala.tasty.Reflection // TODO do not depend on reflection directly
1714
*/
1815
object Const {
1916

20-
def unapply[T](expr: Expr[T])(implicit reflect: Reflection): Option[T] = {
21-
import reflect._
17+
def unapply[T](expr: Expr[T]) given (qctx: QuoteContext): Option[T] = {
18+
import qctx.tasty._
2219
def rec(tree: Term): Option[T] = tree match {
2320
case Literal(c) => Some(c.value.asInstanceOf[T])
2421
case Block(Nil, e) => rec(e)

library/src-3.x/scala/quoted/matching/ConstSeq.scala

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
1-
package scala.quoted.matching
2-
3-
import scala.quoted.Expr
4-
5-
import scala.tasty.Reflection // TODO do not depend on reflection directly
1+
package scala.quoted
2+
package matching
63

74
/** Literal sequence of literal constant value expressions */
85
object ConstSeq {
96

107
/** Matches literal sequence of literal constant value expressions */
11-
def unapply[T](expr: Expr[Seq[T]]) given Reflection: Option[Seq[T]] = expr match {
8+
def unapply[T](expr: Expr[Seq[T]]) given (qctx: QuoteContext): Option[Seq[T]] = expr match {
129
case ExprSeq(elems) =>
1310
elems.foldRight(Option(List.empty[T])) { (elem, acc) =>
1411
(elem, acc) match {

library/src-3.x/scala/quoted/matching/ExprSeq.scala

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
1-
package scala.quoted.matching
2-
3-
import scala.quoted.Expr
4-
5-
import scala.tasty.Reflection // TODO do not depend on reflection directly
1+
package scala.quoted
2+
package matching
63

74
/** Literal sequence of expressions */
85
object ExprSeq {
96

107
/** Matches a literal sequence of expressions */
11-
def unapply[T](expr: Expr[Seq[T]])(implicit reflect: Reflection): Option[Seq[Expr[T]]] = {
12-
import reflect._
8+
def unapply[T](expr: Expr[Seq[T]]) given (qctx: QuoteContext): Option[Seq[Expr[T]]] = {
9+
import qctx.tasty._
1310
def rec(tree: Term): Option[Seq[Expr[T]]] = tree match {
1411
case Typed(Repeated(elems, _), _) => Some(elems.map(x => x.seal.asInstanceOf[Expr[T]]))
1512
case Block(Nil, e) => rec(e)

library/src-3.x/dotty/internal/StringContextMacro.scala renamed to library/src-bootstrapped/dotty/internal/StringContextMacro.scala

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,9 @@
1+
// ALWAYS KEEP THIS FILE IN src-bootstrapped, DO NOT MOVE TO src
2+
13
package dotty.internal
24

35
import scala.quoted._
46
import scala.quoted.matching._
5-
import scala.tasty.Reflection
67
import reflect._
78

89
object StringContextMacro {
@@ -58,7 +59,7 @@ object StringContextMacro {
5859
* @return the String contained in the given Expr
5960
* quotes an error if the given Expr does not contain a String
6061
*/
61-
private def literalToString(expression : Expr[String])(implicit reflect: Reflection) : String = expression match {
62+
private def literalToString(expression : Expr[String]) given (ctx: QuoteContext) : String = expression match {
6263
case Const(string : String) => string
6364
case _ => QuoteError("Expected statically known literal", expression)
6465
}
@@ -69,8 +70,7 @@ object StringContextMacro {
6970
* @return a list of Expr containing Strings, each corresponding to one parts of the given StringContext
7071
* quotes an error if the given Expr does not correspond to a StringContext
7172
*/
72-
def getPartsExprs(strCtxExpr : Expr[scala.StringContext])(implicit reflect : Reflection): List[Expr[String]] = {
73-
import reflect._
73+
def getPartsExprs(strCtxExpr : Expr[scala.StringContext]) given QuoteContext: List[Expr[String]] = {
7474
strCtxExpr match {
7575
case '{ StringContext(${ExprSeq(parts)}: _*) } => parts.toList
7676
case '{ new StringContext(${ExprSeq(parts)}: _*) } => parts.toList
@@ -84,8 +84,8 @@ object StringContextMacro {
8484
* @return a list of Expr containing arguments
8585
* quotes an error if the given Expr does not contain a list of arguments
8686
*/
87-
def getArgsExprs(argsExpr: Expr[Seq[Any]])(implicit reflect: Reflection): List[Expr[Any]] = {
88-
import reflect._
87+
def getArgsExprs(argsExpr: Expr[Seq[Any]]) given (qctx: QuoteContext): List[Expr[Any]] = {
88+
import qctx.tasty._
8989
argsExpr.unseal.underlyingArgument match {
9090
case Typed(Repeated(args, _), _) => args.map(_.seal)
9191
case tree => QuoteError("Expected statically known argument list", argsExpr)
@@ -98,8 +98,8 @@ object StringContextMacro {
9898
* @param args the Expr that holds the sequence of arguments to interpolate to the String in the correct format
9999
* @return the Expr containing the formatted and interpolated String or an error/warning if the parameters are not correct
100100
*/
101-
private def interpolate(strCtxExpr: Expr[StringContext], argsExpr: Expr[Seq[Any]])(implicit reflect: Reflection): Expr[String] = {
102-
import reflect._
101+
private def interpolate(strCtxExpr: Expr[StringContext], argsExpr: Expr[Seq[Any]]) given (qctx: QuoteContext): Expr[String] = {
102+
import qctx.tasty._
103103
val sourceFile = strCtxExpr.unseal.pos.sourceFile
104104

105105
val partsExpr = getPartsExprs(strCtxExpr)
@@ -111,27 +111,27 @@ object StringContextMacro {
111111
def partError(message : String, index : Int, offset : Int) : Unit = {
112112
reported = true
113113
val positionStart = partsExpr(index).unseal.pos.start + offset
114-
reflect.error(message, sourceFile, positionStart, positionStart)
114+
error(message, sourceFile, positionStart, positionStart)
115115
}
116116
def partWarning(message : String, index : Int, offset : Int) : Unit = {
117117
reported = true
118118
val positionStart = partsExpr(index).unseal.pos.start + offset
119-
reflect.warning(message, sourceFile, positionStart, positionStart)
119+
warning(message, sourceFile, positionStart, positionStart)
120120
}
121121

122122
def argError(message : String, index : Int) : Unit = {
123123
reported = true
124-
reflect.error(message, args(index).unseal.pos)
124+
error(message, args(index).unseal.pos)
125125
}
126126

127127
def strCtxError(message : String) : Unit = {
128128
reported = true
129129
val positionStart = strCtxExpr.unseal.pos.start
130-
reflect.error(message, sourceFile, positionStart, positionStart)
130+
error(message, sourceFile, positionStart, positionStart)
131131
}
132132
def argsError(message : String) : Unit = {
133133
reported = true
134-
reflect.error(message, argsExpr.unseal.pos)
134+
error(message, argsExpr.unseal.pos)
135135
}
136136

137137
def hasReported() : Boolean = {
@@ -158,8 +158,8 @@ object StringContextMacro {
158158
* @param reporter the reporter to return any error/warning when a problem is encountered
159159
* @return the Expr containing the formatted and interpolated String or an error/warning report if the parameters are not correct
160160
*/
161-
def interpolate(partsExpr : List[Expr[String]], args : List[Expr[Any]], argsExpr: Expr[Seq[Any]], reporter : Reporter)(implicit reflect: Reflection) : Expr[String] = {
162-
import reflect._
161+
def interpolate(partsExpr : List[Expr[String]], args : List[Expr[Any]], argsExpr: Expr[Seq[Any]], reporter : Reporter) given (qctx: QuoteContext) : Expr[String] = {
162+
import qctx.tasty._
163163

164164
/** Checks if the number of arguments are the same as the number of formatting strings
165165
*
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package scala.testing
2+
3+
import scala.quoted._
4+
5+
inline def typeChecks(inline code: String): Boolean = ${ typeChecksImpl(code) }
6+
7+
private def typeChecksImpl(code: String) given (qctx: QuoteContext): Expr[Boolean] = {
8+
import qctx.tasty._
9+
typing.typeChecks(code).toExpr
10+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// ALWAYS KEEP THIS FILE IN src-non-bootstrapped
2+
3+
package dotty.internal
4+
5+
import scala.quoted._
6+
import scala.quoted.matching._
7+
import scala.tasty.Reflection
8+
import reflect._
9+
10+
object StringContextMacro {
11+
12+
/** Implementation of scala.StringContext.f used in Dotty */
13+
inline def f(sc: => StringContext)(args: Any*): String =
14+
scala.compiletime.error("Cannot expand f interpolator while bootstrapping the compiler")
15+
16+
}

library/src-3.x/scala/testing/typeChecks.scala renamed to library/src-non-bootstrapped/scala/testing/typeChecks.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,3 @@ private def typeChecksImpl(code: String)(implicit reflect: Reflection): Expr[Boo
99
import reflect._
1010
typing.typeChecks(code).toExpr
1111
}
12-

library/src/scala/quoted/QuoteContext.scala

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,20 @@ package scala.quoted
22

33
import scala.quoted.show.SyntaxHighlight
44

5-
class QuoteContext(reflection: tasty.Reflection) {
5+
class QuoteContext(val tasty: scala.tasty.Reflection) {
66

77
def show[T](expr: Expr[T], syntaxHighlight: SyntaxHighlight): String = {
8-
import reflection._
8+
import tasty._
99
expr.unseal.show(syntaxHighlight)
1010
}
1111

1212
def show[T](tpe: Type[T], syntaxHighlight: SyntaxHighlight): String = {
13-
import reflection._
13+
import tasty._
1414
tpe.unseal.show(syntaxHighlight)
1515
}
1616

1717
}
18+
19+
object QuoteContext {
20+
def macroContext: QuoteContext = throw new Exception("Not in inline macro.")
21+
}

0 commit comments

Comments
 (0)