Skip to content

Commit d6e018d

Browse files
committed
WIP
1 parent 24efbf5 commit d6e018d

File tree

4 files changed

+113
-112
lines changed

4 files changed

+113
-112
lines changed

compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,7 +700,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
700700
case MacroTree(call) =>
701701
keywordStr("macro ") ~ toTextGlobal(call)
702702
case Hole(isTerm, idx, args, content, tpt) =>
703-
val (prefix, postfix) = if isTerm then ("{{{ ", " }}}") else ("[[[ ", " ]]]")
703+
val (prefix, postfix) = if isTerm then ("{{{", "}}}") else ("[[[", "]]]")
704704
val argsText = toTextGlobal(args, ", ")
705705
val contentText = toTextGlobal(content)
706706
val tptText = toTextGlobal(tpt)

compiler/src/dotty/tools/dotc/transform/PickleQuotes2.scala renamed to compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -158,18 +158,8 @@ class PickleQuotes extends MacroTransform {
158158
val hole = Hole(true, idx, args, EmptyTree, TypeTree(holeType)).withSpan(content.span).withType(holeType).asInstanceOf[Hole]
159159
Inlined(EmptyTree, Nil, hole).withSpan(tree.span)
160160

161-
// case Apply(fn, List(splicedCode)) if fn.symbol == defn.QuotedRuntime_exprNestedSplice =>
162-
// val Apply(Select(spliceFn, _), args) = splicedCode
163-
// splices += spliceFn
164-
// val holeArgs = args.map {
165-
// case Apply(Select(Apply(_, code :: Nil), _), _) => code
166-
// case Apply(TypeApply(_, List(code)), _) => code
167-
// }
168-
// idx += 1
169-
// val holeType = getTermHoleType(tree.tpe)
170-
// val hole = Hole(true, idx, holeArgs, EmptyTree, TypeTree(holeType)).withSpan(splicedCode.span).withType(holeType).asInstanceOf[Hole]
171-
// Inlined(EmptyTree, Nil, hole).withSpan(tree.span)
172161
case Select(tp, _) if tree.symbol == defn.QuotedType_splice =>
162+
// TODO move to Splicing phase
173163
def makeTypeHole =
174164
splices += ref(tp.symbol)
175165
idx += 1

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

Lines changed: 103 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,17 @@ class Splicing extends MacroTransform {
9999
end MyTransformer
100100

101101
class QuoteTransformer extends Transformer:
102-
private val localDefs = mutable.Set.empty[Symbol]
102+
private val quotedDefs = mutable.Set.empty[Symbol]
103+
private var holeIdx = -1
103104
override def transform(tree: tpd.Tree)(using Context): tpd.Tree =
104105
tree match
105106
case Apply(fn, List(splicedCode)) if fn.symbol == defn.QuotedRuntime_exprNestedSplice =>
106-
val spliceTransformer = new SpliceTransformer(localDefs.toSet, ctx.owner)
107+
val spliceTransformer = new SpliceTransformer(ctx.owner)
107108
val newSplicedCode1 = spliceTransformer.transformSplice(splicedCode, tree.tpe)
108109
val newSplicedCode2 = MyTransformer.transform(newSplicedCode1)
109110
newSplicedCode2
110111
case tree: DefTree =>
111-
localDefs += tree.symbol
112+
quotedDefs += tree.symbol
112113
transformAnnotations(tree)
113114
super.transform(tree)
114115
case _ =>
@@ -130,115 +131,117 @@ class Splicing extends MacroTransform {
130131
}
131132
}
132133

133-
end QuoteTransformer
134-
135-
class SpliceTransformer(quoteDefs: Set[Symbol], spliceOwner: Symbol) extends Transformer:
136-
private var refBindingMap = mutable.Map.empty[Symbol, (Tree, Symbol)]
137-
private var level = 0
138-
private var quotes: Tree = null
134+
class SpliceTransformer(spliceOwner: Symbol) extends Transformer:
135+
private var refBindingMap = mutable.Map.empty[Symbol, (Tree, Symbol)]
136+
private var level = 0
137+
private var quotes: Tree = null
139138

140-
def transformSplice(tree: tpd.Tree, tpe: Type)(using Context): tpd.Tree =
141-
val newTree = transform(tree)
142-
val (refs, bindings) = refBindingMap.values.toList.unzip
143-
val bindingsTypes = bindings.map(_.termRef.widenTermRefExpr)
144-
val methType = MethodType(bindingsTypes, newTree.tpe)
145-
val meth = newSymbol(spliceOwner, nme.ANON_FUN, Synthetic | Method, methType)
146-
val ddef = DefDef(meth, List(bindings), newTree.tpe, newTree.changeOwner(ctx.owner, meth))
147-
val fnType = defn.FunctionType(bindings.size, isContextual = false).appliedTo(bindingsTypes :+ newTree.tpe)
148-
val closure = Block(ddef :: Nil, Closure(Nil, ref(meth), TypeTree(fnType)))
149-
Hole(true, -1, refs, closure, TypeTree(tpe)).withType(tpe)
139+
def transformSplice(tree: tpd.Tree, tpe: Type)(using Context): tpd.Tree =
140+
val newTree = transform(tree)
141+
val (refs, bindings) = refBindingMap.values.toList.unzip
142+
val bindingsTypes = bindings.map(_.termRef.widenTermRefExpr)
143+
val methType = MethodType(bindingsTypes, newTree.tpe)
144+
val meth = newSymbol(spliceOwner, nme.ANON_FUN, Synthetic | Method, methType)
145+
val ddef = DefDef(meth, List(bindings), newTree.tpe, newTree.changeOwner(ctx.owner, meth))
146+
val fnType = defn.FunctionType(bindings.size, isContextual = false).appliedTo(bindingsTypes :+ newTree.tpe)
147+
val closure = Block(ddef :: Nil, Closure(Nil, ref(meth), TypeTree(fnType)))
148+
holeIdx += 1
149+
Hole(true, holeIdx, refs, closure, TypeTree(tpe)).withType(tpe)
150150

151-
override def transform(tree: tpd.Tree)(using Context): tpd.Tree =
152-
tree match
153-
case tree: RefTree =>
154-
if tree.isTerm then
155-
if quoteDefs.contains(tree.symbol) then
156-
val tree1 = splicedTerm(tree)
157-
val tpe = tree.tpe.widenTermRefExpr match {
158-
case tpw: MethodicType => tpw.toFunctionType(isJava = false)
159-
case tpw => tpw
160-
}
161-
tree1.spliced(tpe)
162-
else super.transform(tree)
163-
else // tree.isType then
151+
override def transform(tree: tpd.Tree)(using Context): tpd.Tree =
152+
tree match
153+
case tree: RefTree =>
154+
if tree.isTerm then
155+
if quotedDefs.contains(tree.symbol) then
156+
val tree1 = splicedTerm(tree)
157+
val tpe = tree.tpe.widenTermRefExpr match {
158+
case tpw: MethodicType => tpw.toFunctionType(isJava = false)
159+
case tpw => tpw
160+
}
161+
tree1.spliced(tpe)
162+
else super.transform(tree)
163+
else // tree.isType then
164+
if containsCapturedType(tree.tpe) then
165+
splicedType(tree).select(defn.QuotedType_splice)
166+
else super.transform(tree)
167+
case tree: TypeTree =>
164168
if containsCapturedType(tree.tpe) then
165169
splicedType(tree).select(defn.QuotedType_splice)
170+
else tree
171+
case Assign(lhs: RefTree, rhs) =>
172+
if quotedDefs.contains(lhs.symbol) then transformSplicedAssign(lhs, rhs, tree.tpe)
166173
else super.transform(tree)
167-
case tree: TypeTree =>
168-
if containsCapturedType(tree.tpe) then
169-
splicedType(tree).select(defn.QuotedType_splice)
170-
else tree
171-
case Assign(lhs: RefTree, rhs) =>
172-
if quoteDefs.contains(lhs.symbol) then transformSplicedAssign(lhs, rhs, tree.tpe)
173-
else super.transform(tree)
174-
case Apply(fn, args) if fn.symbol == defn.QuotedRuntime_exprNestedSplice =>
175-
level -= 1
176-
val newArgs = args.mapConserve(transform)
177-
level += 1
178-
cpy.Apply(tree)(fn, newArgs)
179-
case Apply(sel @ Select(app @ Apply(fn, args),nme.apply), quotesArgs)
180-
if fn.symbol == defn.QuotedRuntime_exprQuote =>
181-
args match
182-
case List(tree: RefTree) if quoteDefs.contains(tree.symbol) =>
183-
splicedTerm(tree)
184-
case _ =>
185-
val oldQuotes = quotes
186-
if level == 0 then quotes = quotesArgs.head
187-
level += 1
188-
val newArgs = args.mapConserve(transform)
174+
case Apply(fn, args) if fn.symbol == defn.QuotedRuntime_exprNestedSplice =>
189175
level -= 1
190-
quotes = oldQuotes
191-
cpy.Apply(tree)(cpy.Select(sel)(cpy.Apply(app)(fn, newArgs), nme.apply), quotesArgs)
192-
case Apply(TypeApply(_, List(tpt: Ident)), List(quotes))
193-
if tree.symbol == defn.QuotedTypeModule_of && quoteDefs.contains(tpt.symbol) =>
194-
splicedType(tpt)
195-
case _ =>
196-
super.transform(tree)
176+
val newArgs = args.mapConserve(transform)
177+
level += 1
178+
cpy.Apply(tree)(fn, newArgs)
179+
case Apply(sel @ Select(app @ Apply(fn, args),nme.apply), quotesArgs)
180+
if fn.symbol == defn.QuotedRuntime_exprQuote =>
181+
args match
182+
case List(tree: RefTree) if quotedDefs.contains(tree.symbol) =>
183+
splicedTerm(tree)
184+
case _ =>
185+
val oldQuotes = quotes
186+
if level == 0 then quotes = quotesArgs.head
187+
level += 1
188+
val newArgs = args.mapConserve(transform)
189+
level -= 1
190+
quotes = oldQuotes
191+
cpy.Apply(tree)(cpy.Select(sel)(cpy.Apply(app)(fn, newArgs), nme.apply), quotesArgs)
192+
case Apply(TypeApply(_, List(tpt: Ident)), List(quotes))
193+
if tree.symbol == defn.QuotedTypeModule_of && quotedDefs.contains(tpt.symbol) =>
194+
splicedType(tpt)
195+
case _ =>
196+
super.transform(tree)
197197

198-
private def containsCapturedType(tpe: Type)(using Context): Boolean =
199-
tpe match
200-
case tpe @ TypeRef(prefix, _) => quoteDefs.contains(tpe.symbol) || containsCapturedType(prefix)
201-
case tpe @ TermRef(prefix, _) => quoteDefs.contains(tpe.symbol) || containsCapturedType(prefix)
202-
case AppliedType(tycon, args) => containsCapturedType(tycon) || args.exists(containsCapturedType)
203-
case _ => false
198+
private def containsCapturedType(tpe: Type)(using Context): Boolean =
199+
tpe match
200+
case tpe @ TypeRef(prefix, _) => quotedDefs.contains(tpe.symbol) || containsCapturedType(prefix)
201+
case tpe @ TermRef(prefix, _) => quotedDefs.contains(tpe.symbol) || containsCapturedType(prefix)
202+
case AppliedType(tycon, args) => containsCapturedType(tycon) || args.exists(containsCapturedType)
203+
case _ => false
204204

205-
private def transformSplicedAssign(lhs: RefTree, rhs: Tree, tpe: Type)(using Context): Tree =
206-
// Make `(x: T) => rhs = x`
207-
val methTpe = MethodType(List(lhs.tpe.widenTermRefExpr), tpe)
208-
val meth = newSymbol(spliceOwner, nme.ANON_FUN, Synthetic | Method, methTpe)
209-
val closure = Closure(meth, args => Assign(lhs, args.head.head))
205+
private def transformSplicedAssign(lhs: RefTree, rhs: Tree, tpe: Type)(using Context): Tree =
206+
// Make `(x: T) => rhs = x`
207+
val methTpe = MethodType(List(lhs.tpe.widenTermRefExpr), tpe)
208+
val meth = newSymbol(spliceOwner, nme.ANON_FUN, Synthetic | Method, methTpe)
209+
val closure = Closure(meth, args => Assign(lhs, args.head.head))
210210

211-
val binding = splicedTerm(closure)
212-
// TODO: `${Expr.betaReduce('{$rhsFn.apply(lhs)})}` ?
213-
// Make `$rhsFn.apply(lhs)`
214-
binding.spliced(methTpe.toFunctionType(isJava = false)).select(nme.apply).appliedTo(transform(rhs))
211+
val binding = splicedTerm(closure)
212+
// TODO: `${Expr.betaReduce('{$rhsFn.apply(lhs)})}` ?
213+
// Make `$rhsFn.apply(lhs)`
214+
binding.spliced(methTpe.toFunctionType(isJava = false)).select(nme.apply).appliedTo(transform(rhs))
215215

216-
private def splicedTerm(tree: Tree)(using Context): Tree =
217-
val tpe = tree.tpe.widenTermRefExpr match {
218-
case tpw: MethodicType => tpw.toFunctionType(isJava = false)
219-
case tpw => tpw
220-
}
221-
def newBinding = newSymbol(
222-
spliceOwner,
223-
UniqueName.fresh(tree.symbol.name.toTermName).toTermName,
224-
Param,
225-
tpe.exprType,
226-
)
227-
val (_, bindingSym) = refBindingMap.getOrElseUpdate(tree.symbol, (tree, newBinding))
228-
ref(bindingSym)
216+
private def splicedTerm(tree: Tree)(using Context): Tree =
217+
val tpe = tree.tpe.widenTermRefExpr match {
218+
case tpw: MethodicType => tpw.toFunctionType(isJava = false)
219+
case tpw => tpw
220+
}
221+
def newBinding = newSymbol(
222+
spliceOwner,
223+
UniqueName.fresh(tree.symbol.name.toTermName).toTermName,
224+
Param,
225+
tpe.exprType,
226+
)
227+
val (_, bindingSym) = refBindingMap.getOrElseUpdate(tree.symbol, (tree, newBinding))
228+
ref(bindingSym)
229229

230-
private def splicedType(tree: Tree)(using Context): Tree =
231-
val tpe = tree.tpe.widenTermRefExpr
232-
def newBinding = newSymbol(
233-
spliceOwner,
234-
UniqueName.fresh(nme.Type).toTermName,
235-
Param,
236-
defn.QuotedTypeClass.typeRef.appliedTo(tpe),
237-
)
238-
val (_, bindingSym) = refBindingMap.getOrElseUpdate(tree.symbol, (TypeTree(tree.tpe), newBinding))
239-
ref(bindingSym)
230+
private def splicedType(tree: Tree)(using Context): Tree =
231+
val tpe = tree.tpe.widenTermRefExpr
232+
def newBinding = newSymbol(
233+
spliceOwner,
234+
UniqueName.fresh(nme.Type).toTermName,
235+
Param,
236+
defn.QuotedTypeClass.typeRef.appliedTo(tpe),
237+
)
238+
val (_, bindingSym) = refBindingMap.getOrElseUpdate(tree.symbol, (TypeTree(tree.tpe), newBinding))
239+
ref(bindingSym)
240+
241+
end SpliceTransformer
242+
243+
end QuoteTransformer
240244

241-
end SpliceTransformer
242245

243246
}
244247

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,14 @@ class Staging extends MacroTransform {
5858

5959
tp
6060
}
61+
// override def transform(tree: Tree)(using Context): Tree = tree match
62+
// case Hole(_, _, args, content, tpt) =>
63+
// // check levels within holes
64+
// args.map(transform)
65+
// transform(content)(using spliceContext)
66+
// transform(tpt)
67+
// tree
68+
// case _ => super.transform(tree)
6169
}
6270
checker.transform(tree)
6371
case _ =>

0 commit comments

Comments
 (0)