Skip to content

Commit 1b6e413

Browse files
committed
Refactor
1 parent 2aa27de commit 1b6e413

File tree

1 file changed

+43
-53
lines changed

1 file changed

+43
-53
lines changed

compiler/src/dotty/tools/dotc/staging/CrossStageSafety.scala

Lines changed: 43 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -51,19 +51,53 @@ class CrossStageSafety extends TreeMapWithStages {
5151
if (tree.source != ctx.source && tree.source.exists)
5252
transform(tree)(using ctx.withSource(tree.source))
5353
else tree match
54-
case tree @ Quote(quotedTree) =>
54+
case tree: Quote =>
5555
tree.cancelled match
56-
case Some(tree1) => transform(tree1)
57-
case None => transformQuote(quotedTree, tree)
58-
case tree @ Splice(splicedTree) =>
56+
case Some(tree1) =>
57+
transform(tree1)
58+
case None =>
59+
if (ctx.property(InAnnotation).isDefined)
60+
report.error("Cannot have a quote in an annotation", tree.srcPos)
61+
val body1 = transformQuoteBody(tree.body, tree.span)
62+
val stripAnnotationsDeep: TypeMap = new TypeMap:
63+
def apply(tp: Type): Type = mapOver(tp.stripAnnots)
64+
val bodyType1 = healType(tree.srcPos)(stripAnnotationsDeep(tree.bodyType))
65+
cpy.Quote(tree)(body1).withBodyType(bodyType1)
66+
67+
case tree: Splice =>
5968
tree.cancelled match
60-
case Some(tree1) => transform(tree1)
61-
case None => transformSplice(splicedTree, tree)
62-
case tree @ QuotedTypeOf(quotedTree) =>
63-
transformQuotedType(quotedTree, tree)
69+
case Some(tree1) =>
70+
transform(tree1)
71+
case None =>
72+
val body1 = transform(tree.expr)(using spliceContext)
73+
val tpe1 =
74+
if level == 0 then tree.tpe
75+
else healType(tree.srcPos)(tree.tpe.widenTermRefExpr)
76+
untpd.cpy.Splice(tree)(body1).withType(tpe1)
77+
78+
case tree @ QuotedTypeOf(body) =>
79+
if (ctx.property(InAnnotation).isDefined)
80+
report.error("Cannot have a quote in an annotation", tree.srcPos)
81+
body.tpe match
82+
case DirectTypeOf(termRef) =>
83+
// Optimization: `quoted.Type.of[x.Underlying](quotes)` --> `x`
84+
ref(termRef).withSpan(tree.span)
85+
case _ =>
86+
transformQuoteBody(body, tree.span) match
87+
case DirectTypeOf.Healed(termRef) =>
88+
// Optimization: `quoted.Type.of[@SplicedType type T = x.Underlying; T](quotes)` --> `x`
89+
ref(termRef).withSpan(tree.span)
90+
case transformedBody =>
91+
val quotes = transform(tree.args.head)
92+
// `quoted.Type.of[<body>](quotes)` --> `quoted.Type.of[<body2>](quotes)`
93+
val TypeApply(fun, _) = tree.fun: @unchecked
94+
if level != 0 then cpy.Apply(tree)(cpy.TypeApply(tree.fun)(fun, transformedBody :: Nil), quotes :: Nil)
95+
else tpd.Quote(transformedBody).select(nme.apply).appliedTo(quotes).withSpan(tree.span)
96+
6497
case _ if !inQuoteOrSpliceScope =>
65-
checkAnnotations(tree)
98+
checkAnnotations(tree) // Check quotes in annotations
6699
super.transform(tree)
100+
67101
case _: TypeTree =>
68102
val tp1 = transformTypeAnnotationSplices(tree.tpe)
69103
val healedType = healType(tree.srcPos)(tp1)
@@ -106,37 +140,6 @@ class CrossStageSafety extends TreeMapWithStages {
106140
super.transform(tree)
107141
end transform
108142

109-
/** Transform quoted trees while maintaining level correctness */
110-
private def transformQuote(body: Tree, quote: Quote)(using Context): Tree = {
111-
if (ctx.property(InAnnotation).isDefined)
112-
report.error("Cannot have a quote in an annotation", quote.srcPos)
113-
val transformedBody = transformQuoteBody(body, quote.span)
114-
val stripAnnotationsDeep: TypeMap = new TypeMap:
115-
def apply(tp: Type): Type = mapOver(tp.stripAnnots)
116-
val bodyType1 = healType(quote.srcPos)(stripAnnotationsDeep(quote.bodyType))
117-
cpy.Quote(quote)(transformedBody).withBodyType(bodyType1)
118-
}
119-
120-
private def transformQuotedType(body: Tree, quote: Apply)(using Context): Tree = {
121-
if (ctx.property(InAnnotation).isDefined)
122-
report.error("Cannot have a quote in an annotation", quote.srcPos)
123-
body.tpe match
124-
case DirectTypeOf(termRef) =>
125-
// Optimization: `quoted.Type.of[x.Underlying](quotes)` --> `x`
126-
ref(termRef).withSpan(quote.span)
127-
case _ =>
128-
transformQuoteBody(body, quote.span) match
129-
case DirectTypeOf.Healed(termRef) =>
130-
// Optimization: `quoted.Type.of[@SplicedType type T = x.Underlying; T](quotes)` --> `x`
131-
ref(termRef).withSpan(quote.span)
132-
case transformedBody =>
133-
val quotes = transform(quote.args.head)
134-
// `quoted.Type.of[<body>](quotes)` --> `quoted.Type.of[<body2>](quotes)`
135-
val TypeApply(fun, _) = quote.fun: @unchecked
136-
if level != 0 then cpy.Apply(quote)(cpy.TypeApply(quote.fun)(fun, transformedBody :: Nil), quotes :: Nil)
137-
else tpd.Quote(transformedBody).select(nme.apply).appliedTo(quotes).withSpan(quote.span)
138-
}
139-
140143
private def transformQuoteBody(body: Tree, span: Span)(using Context): Tree = {
141144
val taggedTypes = new QuoteTypeTags(span)
142145
val contextWithQuote =
@@ -148,19 +151,6 @@ class CrossStageSafety extends TreeMapWithStages {
148151
case tags => tpd.Block(tags, transformedBody).withSpan(body.span)
149152
}
150153

151-
/** Transform splice
152-
* - If inside a quote, transform the contents of the splice.
153-
* - If inside inlined code, expand the macro code.
154-
* - If inside of a macro definition, check the validity of the macro.
155-
*/
156-
private def transformSplice(body: Tree, splice: Splice)(using Context): Tree = {
157-
val body1 = transform(body)(using spliceContext)
158-
val tpe1 =
159-
if level == 0 then splice.tpe
160-
else healType(splice.srcPos)(splice.tpe.widenTermRefExpr)
161-
untpd.cpy.Splice(splice)(body1).withType(tpe1)
162-
}
163-
164154
def transformTypeAnnotationSplices(tp: Type)(using Context) = new TypeMap {
165155
def apply(tp: Type): Type = tp match
166156
case tp: AnnotatedType =>

0 commit comments

Comments
 (0)