Skip to content

Commit 32c0e10

Browse files
committed
Undo patch of double-block apply
If `f{}{}` is candidate for rewrite, unpatch it. We don't know exact spans, so just check endpoints to remove.
1 parent 04ebb28 commit 32c0e10

File tree

4 files changed

+32
-2
lines changed

4 files changed

+32
-2
lines changed

compiler/src/dotty/tools/dotc/parsing/Parsers.scala

+7-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import ScriptParsers.*
2727
import Decorators.*
2828
import util.Chars
2929
import scala.annotation.tailrec
30-
import rewrites.Rewrites.{patch, overlapsPatch}
30+
import rewrites.Rewrites.{overlapsPatch, patch, unpatch}
3131
import reporting.*
3232
import config.Feature
3333
import config.Feature.{sourceVersion, migrateTo3}
@@ -2741,6 +2741,12 @@ object Parsers {
27412741
simpleExprRest(tapp, location, canApply = true)
27422742
case LPAREN | LBRACE | INDENT if canApply =>
27432743
val app = atSpan(startOffset(t), in.offset) { mkApply(t, argumentExprs()) }
2744+
if in.rewriteToIndent then
2745+
app match
2746+
case Apply(Apply(_, List(Block(_, _))), List(blk @ Block(_, _))) =>
2747+
unpatch(blk.srcPos.sourcePos.source, Span(blk.span.start, blk.span.start + 1))
2748+
unpatch(blk.srcPos.sourcePos.source, Span(blk.span.end, blk.span.end + 1))
2749+
case _ =>
27442750
simpleExprRest(app, location, canApply = true)
27452751
case USCORE =>
27462752
atSpan(startOffset(t), in.skipToken()) { PostfixOp(t, Ident(nme.WILDCARD)) }

compiler/src/dotty/tools/dotc/rewrites/Rewrites.scala

+16-1
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,16 @@ object Rewrites {
3232
case class ActionPatch(srcPos: SourcePosition, replacement: String)
3333

3434
private class Patches(source: SourceFile) {
35-
private[Rewrites] val pbuf = new mutable.ListBuffer[Patch]()
35+
private[Rewrites] val pbuf = mutable.ListBuffer.empty[Patch]
3636

3737
def addPatch(span: Span, replacement: String): Unit =
3838
pbuf += Patch(span, replacement)
3939

40+
// remove patches which match either end point
41+
def removePatch(span: Span): Unit =
42+
def p(other: Span): Boolean = span.start == other.start || span.end == other.end
43+
pbuf.filterInPlace(x => !p(x.span))
44+
4045
def apply(cs: Array[Char]): Array[Char] = {
4146
val delta = pbuf.map(_.delta).sum
4247
val patches = pbuf.toList.sortBy(_.span.start)
@@ -87,6 +92,16 @@ object Rewrites {
8792
def patch(span: Span, replacement: String)(using Context): Unit =
8893
patch(ctx.compilationUnit.source, span, replacement)
8994

95+
/** Delete patches matching the given span,
96+
* where a match has the same start or end offset.
97+
*/
98+
def unpatch(source: SourceFile, span: Span)(using Context): Unit =
99+
if ctx.reporter != Reporter.NoReporter // NoReporter is used for syntax highlighting
100+
then ctx.settings.rewrite.value.foreach: rewrites =>
101+
rewrites.patched
102+
.get(source)
103+
.foreach(_.removePatch(span))
104+
90105
/** Does `span` overlap with a patch region of `source`? */
91106
def overlapsPatch(source: SourceFile, span: Span)(using Context): Boolean =
92107
ctx.settings.rewrite.value.exists(rewrites =>

compiler/test/dotty/tools/dotc/CompilationTests.scala

+1
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class CompilationTests {
7777
compileFile("tests/rewrites/i17399.scala", unindentOptions.and("-rewrite")),
7878
compileFile("tests/rewrites/i20002.scala", defaultOptions.and("-indent", "-rewrite")),
7979
compileDir("tests/rewrites/annotation-named-pararamters", defaultOptions.and("-rewrite", "-source:3.6-migration")),
80+
compileFile("tests/rewrites/i21382.scala", defaultOptions.and("-indent", "-rewrite")),
8081
).checkRewrites()
8182
}
8283

tests/rewrites/i21382.scala

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
def check(element: Any)(expected: String): Unit = ???
2+
3+
def test =
4+
check {
5+
???
6+
}{
7+
42.toString
8+
}

0 commit comments

Comments
 (0)