Skip to content

Commit 826eb7e

Browse files
committed
Refactor
1 parent 1329e3a commit 826eb7e

File tree

2 files changed

+52
-50
lines changed

2 files changed

+52
-50
lines changed

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

Lines changed: 50 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
4848
super.transform(tree)
4949
else tree match {
5050

51-
// Type tress
51+
// Type trees
5252

5353
case _: TypTree =>
5454
if needsHealing(tree.tpe) then TypeTree(healType(tree.sourcePos)(tree.tpe)).withSpan(tree.span)
@@ -82,6 +82,54 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
8282
super.transform(tree)
8383
}
8484

85+
/** Transform quoted trees while maintaining phase correctness */
86+
override protected def transformQuotation(body: Tree, quote: Tree)(implicit ctx: Context): Tree = {
87+
val taggedTypes = new PCPCheckAndHeal.QuoteTypeTags(quote.span)(using ctx)
88+
if (ctx.property(InAnnotation).isDefined)
89+
ctx.error("Cannot have a quote in an annotation", quote.sourcePos)
90+
91+
val contextWithQuote =
92+
if level == 0 then contextWithQuoteTypeTags(taggedTypes)(quoteContext)
93+
else quoteContext
94+
val inQuoteOrSpliceOld = inQuoteOrSplice
95+
inQuoteOrSplice = true
96+
val body1 = transform(body)(contextWithQuote)
97+
inQuoteOrSplice = inQuoteOrSpliceOld
98+
val body2 =
99+
taggedTypes.getTypeTags match
100+
case Nil => body1
101+
case tags => tpd.Block(tags, body1).withSpan(body.span)
102+
103+
super.transformQuotation(body2, quote)
104+
}
105+
106+
/** Transform splice
107+
* - If inside a quote, transform the contents of the splice.
108+
* - If inside inlined code, expand the macro code.
109+
* - If inside of a macro definition, check the validity of the macro.
110+
*/
111+
protected def transformSplice(body: Tree, splice: Tree)(implicit ctx: Context): Tree = {
112+
val inQuoteOrSpliceOld = inQuoteOrSplice
113+
inQuoteOrSplice = true
114+
val body1 = transform(body)(spliceContext)
115+
inQuoteOrSplice = inQuoteOrSpliceOld
116+
splice match {
117+
case Apply(fun @ TypeApply(_, _ :: Nil), _) if splice.isTerm =>
118+
// Type of the splice itsel must also be healed
119+
// internal.Quoted.expr[F[T]](... T ...) --> internal.Quoted.expr[F[$t]](... T ...)
120+
val tp = healType(splice.sourcePos)(splice.tpe.widenTermRefExpr)
121+
cpy.Apply(splice)(cpy.TypeApply(fun)(fun.fun, tpd.TypeTree(tp) :: Nil), body1 :: Nil)
122+
case Apply(f @ Apply(fun @ TypeApply(_, _), qctx :: Nil), _) if splice.isTerm =>
123+
// Type of the splice itsel must also be healed
124+
// internal.Quoted.expr[F[T]](... T ...) --> internal.Quoted.expr[F[$t]](... T ...)
125+
val tp = healType(splice.sourcePos)(splice.tpe.widenTermRefExpr)
126+
cpy.Apply(splice)(cpy.Apply(f)(cpy.TypeApply(fun)(fun.fun, tpd.TypeTree(tp) :: Nil), qctx :: Nil), body1 :: Nil)
127+
case splice: Select =>
128+
val tagRef = getQuoteTypeTags.getTagRef(splice.qualifier.tpe.asInstanceOf[TermRef])
129+
ref(tagRef).withSpan(splice.span)
130+
}
131+
}
132+
85133
/** Check that annotations do not contain quotes and and that splices are valid */
86134
private def checkAnnotations(tree: Tree)(using Context): Unit =
87135
tree match
@@ -158,6 +206,7 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
158206
tree
159207
}
160208

209+
// TODO return new type or else old?
161210
protected def tryHeal(sym: Symbol, tp: TypeRef, pos: SourcePosition)(implicit ctx: Context): Option[TypeRef] = {
162211
val reqType = defn.QuotedTypeClass.typeRef.appliedTo(tp)
163212
val tag = ctx.typer.inferImplicitArg(reqType, pos.span)
@@ -190,53 +239,6 @@ class PCPCheckAndHeal(@constructorOnly ictx: Context) extends TreeMapWithStages(
190239
None
191240
}
192241

193-
/** Transform quoted trees while maintaining phase correctness */
194-
override protected def transformQuotation(body: Tree, quote: Tree)(implicit ctx: Context): Tree = {
195-
val taggedTypes = new PCPCheckAndHeal.QuoteTypeTags(quote.span)(using ctx)
196-
if (ctx.property(InAnnotation).isDefined)
197-
ctx.error("Cannot have a quote in an annotation", quote.sourcePos)
198-
199-
val contextWithQuote =
200-
if level == 0 then contextWithQuoteTypeTags(taggedTypes)(quoteContext)
201-
else quoteContext
202-
val inQuoteOrSpliceOld = inQuoteOrSplice
203-
inQuoteOrSplice = true
204-
val body1 = transform(body)(contextWithQuote)
205-
inQuoteOrSplice = inQuoteOrSpliceOld
206-
val body2 =
207-
taggedTypes.getTypeTags match
208-
case Nil => body1
209-
case tags => tpd.Block(tags, body1).withSpan(body.span)
210-
211-
super.transformQuotation(body2, quote)
212-
}
213-
214-
/** Transform splice
215-
* - If inside a quote, transform the contents of the splice.
216-
* - If inside inlined code, expand the macro code.
217-
* - If inside of a macro definition, check the validity of the macro.
218-
*/
219-
protected def transformSplice(body: Tree, splice: Tree)(implicit ctx: Context): Tree = {
220-
val inQuoteOrSpliceOld = inQuoteOrSplice
221-
inQuoteOrSplice = true
222-
val body1 = transform(body)(spliceContext)
223-
inQuoteOrSplice = inQuoteOrSpliceOld
224-
splice match {
225-
case Apply(fun @ TypeApply(_, _ :: Nil), _) if splice.isTerm =>
226-
// Type of the splice itsel must also be healed
227-
// internal.Quoted.expr[F[T]](... T ...) --> internal.Quoted.expr[F[$t]](... T ...)
228-
val tp = healType(splice.sourcePos)(splice.tpe.widenTermRefExpr)
229-
cpy.Apply(splice)(cpy.TypeApply(fun)(fun.fun, tpd.TypeTree(tp) :: Nil), body1 :: Nil)
230-
case Apply(f @ Apply(fun @ TypeApply(_, _), qctx :: Nil), _) if splice.isTerm =>
231-
// Type of the splice itsel must also be healed
232-
// internal.Quoted.expr[F[T]](... T ...) --> internal.Quoted.expr[F[$t]](... T ...)
233-
val tp = healType(splice.sourcePos)(splice.tpe.widenTermRefExpr)
234-
cpy.Apply(splice)(cpy.Apply(f)(cpy.TypeApply(fun)(fun.fun, tpd.TypeTree(tp) :: Nil), qctx :: Nil), body1 :: Nil)
235-
case splice: Select =>
236-
val tagRef = getQuoteTypeTags.getTagRef(splice.qualifier.tpe.asInstanceOf[TermRef])
237-
ref(tagRef).withSpan(splice.span)
238-
}
239-
}
240242
}
241243

242244
object PCPCheckAndHeal {

tests/neg-macros/quote-this.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ class Foo {
55
def f(using QuoteContext): Unit = '{
66
def bar[T](x: T): T = x
77
bar[
8-
this.type // error
8+
this.type // error
99
] {
10-
this // error
10+
this // error
1111
}
1212
}
1313

0 commit comments

Comments
 (0)