diff --git a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala index addd54df9d69..f7618b623541 100644 --- a/compiler/src/dotty/tools/dotc/parsing/Parsers.scala +++ b/compiler/src/dotty/tools/dotc/parsing/Parsers.scala @@ -814,6 +814,8 @@ object Parsers { * 6. the opening brace does not follow a `=>`. The reason for this condition is that * rewriting back to braces does not work after `=>` (since in most cases braces are omitted * after a `=>` it would be annoying if braces were inserted). + * 7. not a code block being the input to a direct symbolic function call `inst method {\n expr \n}` cannot + * become `inst method :\n expr` for a fully symbolic method */ def bracesToIndented[T](body: => T, rewriteWithColon: Boolean): T = { val underColonSyntax = possibleColonOffset == in.lastOffset @@ -827,10 +829,28 @@ object Parsers { } var canRewrite = allBraces(in.currentRegion) && // test (1) !testChars(in.lastOffset - 3, " =>") // test(6) + + def isStartOfSymbolicFunction: Boolean = + opStack.headOption.exists { x => + val bq = x.operator.isBackquoted + val op = x.operator.name.toSimpleName.decode.forall { + Chars.isOperatorPart + } + val loc = startOpening < x.offset && x.offset < endOpening + val res = !bq && op && loc + res + } val t = enclosed(LBRACE, { canRewrite &= in.isAfterLineEnd // test (2) val curOffset = in.offset - try body + try { + val bodyResolved = body + bodyResolved match + case x:(Match | Block) => + canRewrite &= !isStartOfSymbolicFunction // test (7) + case _ => + bodyResolved + } finally { canRewrite &= in.isAfterLineEnd && in.offset != curOffset // test (3)(4) } diff --git a/compiler/test/dotty/tools/dotc/CompilationTests.scala b/compiler/test/dotty/tools/dotc/CompilationTests.scala index a96a4ea09102..52b058032fdc 100644 --- a/compiler/test/dotty/tools/dotc/CompilationTests.scala +++ b/compiler/test/dotty/tools/dotc/CompilationTests.scala @@ -75,6 +75,7 @@ class CompilationTests { compileFile("tests/rewrites/i12340.scala", unindentOptions.and("-rewrite")), compileFile("tests/rewrites/i17187.scala", unindentOptions.and("-rewrite")), compileFile("tests/rewrites/i17399.scala", unindentOptions.and("-rewrite")), + compileFile("tests/rewrites/i20002.scala", defaultOptions.and("-indent", "-rewrite")), ).checkRewrites() } diff --git a/tests/rewrites/i20002.check b/tests/rewrites/i20002.check new file mode 100644 index 000000000000..70c9411eb4b2 --- /dev/null +++ b/tests/rewrites/i20002.check @@ -0,0 +1,51 @@ +object Reactions: + def main: Unit = + Reactions += { + case 0 => + case 1 => + } + + Reactions run: + case 0 => + case 1 => + + Reactions run_+ : + case 0 => + case 1 => + + Reactions `+=`: + case 0 => + case 1 => + + def bar: Int = ??? + + bar match + case 0 => + case 1 => + + def partPartial(i: Int): PartialFunction[Int, Unit] = + case `i` => + + Reactions += { + val pp1 = partPartial(1) + val pp2 = partPartial(2) + def codeBlock = + ??? + ??? + pp1 orElse pp2 + } + + val partialFunction = partPartial(1) orElse partPartial(2) + Reactions += { + partialFunction + } + + def +=(f: PartialFunction[Int, Unit]) = + ??? + + def run (f: PartialFunction[Int, Unit]) = + ??? + + def run_+ (f: PartialFunction[Int, Unit]) = + ??? + diff --git a/tests/rewrites/i20002.scala b/tests/rewrites/i20002.scala new file mode 100644 index 000000000000..56ea023b63b0 --- /dev/null +++ b/tests/rewrites/i20002.scala @@ -0,0 +1,62 @@ +object Reactions { + def main: Unit = { + Reactions += { + case 0 => + case 1 => + } + + Reactions run { + case 0 => + case 1 => + } + + Reactions run_+ { + case 0 => + case 1 => + } + + Reactions `+=` { + case 0 => + case 1 => + } + + def bar: Int = ??? + + bar match { + case 0 => + case 1 => + } + + def partPartial(i: Int): PartialFunction[Int, Unit] = { + case `i` => + } + + Reactions += { + val pp1 = partPartial(1) + val pp2 = partPartial(2) + def codeBlock = { + ??? + ??? + } + pp1 orElse pp2 + } + + val partialFunction = partPartial(1) orElse partPartial(2) + Reactions += { + partialFunction + } + } + + def +=(f: PartialFunction[Int, Unit]) = { + ??? + } + + def run (f: PartialFunction[Int, Unit]) = { + ??? + } + + def run_+ (f: PartialFunction[Int, Unit]) = { + ??? + } + +}