Skip to content

Commit

Permalink
Update Hole syntax in RefinedPrinter and documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
nicolasstucki committed Apr 6, 2023
1 parent 67353f0 commit 738c3aa
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 32 deletions.
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/printing/RefinedPrinter.scala
Original file line number Diff line number Diff line change
Expand Up @@ -725,12 +725,12 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
case MacroTree(call) =>
keywordStr("macro ") ~ toTextGlobal(call)
case Hole(isTermHole, idx, targs, args, content, tpt) =>
val (prefix, postfix) = if isTermHole then ("{{{", "}}}") else ("[[[", "]]]")
val (prefix, postfix) = if isTermHole then ("${", "}") else ("$[", "]")
val targsText = ("[" ~ toTextGlobal(targs, ", ") ~ "]").provided(targs.nonEmpty)
val argsText = ("(" ~ toTextGlobal(args, ", ") ~ ")").provided(args.nonEmpty)
val tptText = toTextGlobal(tpt)
val contentText = ("|" ~~ toTextGlobal(content)).provided(content ne EmptyTree)
prefix ~~ idx.toString ~ targsText ~ argsText ~ ":" ~~ tptText ~~ contentText ~~ postfix
prefix ~~ "`" ~ idx.toString ~ "`" ~ targsText ~ argsText ~ ":" ~~ tptText ~~ contentText ~~ postfix
case CapturingTypeTree(refs, parent) =>
parent match
case ImpureByNameTypeTree(bntpt) =>
Expand Down
35 changes: 17 additions & 18 deletions compiler/src/dotty/tools/dotc/transform/PickleQuotes.scala
Original file line number Diff line number Diff line change
Expand Up @@ -28,43 +28,42 @@ import scala.annotation.constructorOnly
* Transforms top level quote
* ```
* '{ ...
* @TypeSplice type X0 = {{ 0 | .. | contentsTpe0 | .. }}
* @TypeSplice type X2 = {{ 1 | .. | contentsTpe1 | .. }}
* @TypeSplice type X0 = $[ `0`: ... | contentsTpe0 ]
* type X1
* val x1: U1 = ???
* val x2: U2 = ???
* ...
* {{{ 3 | x1 | contents0 | T0 }}} // hole
* ${ `2`(x1): T0 | contents0 } // Hole
* ...
* {{{ 4 | x2 | contents1 | T1 }}} // hole
* ${ `3`[X1](x2): T1 | contents1 } // Hole
* ...
* {{{ 5 | x1, x2 | contents2 | T2 }}} // hole
* ${ `4`(x1, x2): T2 | contents2 } // Hole
* ...
* }
* ```
* to
* ```
* unpickleExprV2(
* pickled = [[ // PICKLED TASTY
* @TypeSplice type X0 // with bounds that do not contain captured types
* @TypeSplice type X1 // with bounds that do not contain captured types
* pickled = tasty""" // PICKLED TASTY
* @TypeSplice type X0 // with bounds that do not contain captured types
* type X1
* val x1 = ???
* val x2 = ???
* ...
* {{{ 0 | x1 | | T0 }}} // hole
* ...
* {{{ 1 | x2 | | T1 }}} // hole
* ...
* {{{ 2 | x1, x2 | | T2 }}} // hole
* ${ `0`(x1): T0 } // Hole
* ...
* ${ `1`[X1](x2): T1 } // Hole
* ...
* ${ `2`(x1, x2): T2 } // Hole
* ...
* ]],
* """,
* typeHole = (idx: Int, args: List[Any]) => idx match {
* case 0 => contentsTpe0.apply(args(0).asInstanceOf[Type[?]]) // beta reduced
* case 1 => contentsTpe1.apply(args(0).asInstanceOf[Type[?]]) // beta reduced
* },
* termHole = (idx: Int, args: List[Any], quotes: Quotes) => idx match {
* case 3 => content0.apply(args(0).asInstanceOf[Expr[U1]]).apply(quotes) // beta reduced
* case 4 => content1.apply(args(0).asInstanceOf[Expr[U2]]).apply(quotes) // beta reduced
* case 5 => content2.apply(args(0).asInstanceOf[Expr[U1]], args(1).asInstanceOf[Expr[U2]]).apply(quotes) // beta reduced
* case 0 => content0.apply(args(0).asInstanceOf[Expr[U1]]).apply(quotes) // beta reduced
* case 1 => content1.apply(args(0).asInstanceOf[Expr[U2]]).apply(quotes) // beta reduced
* case 2 => content2.apply(args(0).asInstanceOf[Expr[U1]], args(1).asInstanceOf[Expr[U2]]).apply(quotes) // beta reduced
* },
* )
* ```
Expand Down
25 changes: 13 additions & 12 deletions compiler/src/dotty/tools/dotc/transform/Splicing.scala
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,19 @@ object Splicing:
*
* After this phase we have the invariant where all splices have the following shape
* ```
* {{{ <holeIdx> | <holeType> | <captures>* | (<capturedTerms>*) => <spliceContent> }}}
* ${ `<holeIdx>`[<typeCaptures>*](<termCaptures>*): <holeType> | (<capturesTypes>*, <capturedTerms>*) => <spliceContent> }
* ```
* where `<spliceContent>` does not contain any free references to quoted definitions and `<captures>*`
* where `<spliceContent>` does not contain any free references to quoted definitions and `<typeCaptures>*`/`<termCaptures>*`
* contains the quotes with references to all cross-quote references. There are some special rules
* for references in the LHS of assignments and cross-quote method references.
*
* In the following code example `x1` and `x2` are cross-quote references.
* In the following code example `x1`, `x2` and `U` are cross-quote references.
* ```
* '{ ...
* val x1: T1 = ???
* val x2: T2 = ???
* ${ (q: Quotes) ?=> f('{ g(x1, x2) }) }: T3
* type U <: T2
* val x2: U = ???
* ${ (q: Quotes) ?=> f('{ g[U](x1, x2) }) }: T3
* }
* ```
*
Expand All @@ -59,12 +60,12 @@ object Splicing:
* ```
* '{ ...
* val x1: T1 = ???
* val x2: T2 = ???
* {{{ 0 | T3 | x1, x2 |
* (x1$: Expr[T1], x2$: Expr[T2]) => // body of this lambda does not contain references to x1 or x2
* (q: Quotes) ?=> f('{ g(${x1$}, ${x2$}) })
*
* }}}
* type U <: T2
* val x2: U = ???
* ${ `0`[U](x1, x2): T3 |
* (U$2: Type[U], x1$: Expr[T], x2$: Expr[U]) => // body of this lambda does not contain references to x1 or x2
* (q: Quotes) ?=> f('{ @SplicedType type U$3 = $[ `0`: U | U$1 ]; g[U$3](${x1$}, ${x2$}) })
* }
* }
* ```
*
Expand Down Expand Up @@ -184,7 +185,7 @@ class Splicing extends MacroTransform:
* ```
* is transformed into
* ```scala
* {{{ <holeIdx++> | T2 | x, X | (x$1: Expr[T1], X$1: Type[X]) => (using Quotes) ?=> {... ${x$1} ... X$1.Underlying ...} }}}
* ${ `<holeIdx++>`[X](x): T2 | (X$1: Type[X], x$1: Expr[T1]) => (using Quotes) ?=> {... ${x$1} ... X$1.Underlying ...} }
* ```
*/
private class SpliceTransformer(spliceOwner: Symbol, isCaptured: Symbol => Boolean) extends Transformer:
Expand Down

0 comments on commit 738c3aa

Please sign in to comment.