From b866e87a5aed9ece79ca7a3992e7e384aa9ac369 Mon Sep 17 00:00:00 2001 From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com> Date: Thu, 21 Mar 2024 08:13:16 -0700 Subject: [PATCH 1/2] Add another test for comma before nested outdents --- .../dotty/SignificantIndentationSuite.scala | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/tests/shared/src/test/scala/scala/meta/tests/parsers/dotty/SignificantIndentationSuite.scala b/tests/shared/src/test/scala/scala/meta/tests/parsers/dotty/SignificantIndentationSuite.scala index 34ba09d6c0..9fbccd6fb7 100644 --- a/tests/shared/src/test/scala/scala/meta/tests/parsers/dotty/SignificantIndentationSuite.scala +++ b/tests/shared/src/test/scala/scala/meta/tests/parsers/dotty/SignificantIndentationSuite.scala @@ -1675,6 +1675,22 @@ class SignificantIndentationSuite extends BaseDottySuite { runTestAssert[Stat](code, layout)(tree) } + test("#3542 apply with optional braces in intermediate arg, with multiple outdents") { + val code = + """|A( + | foo = x => + | x match + | case baz => baz, + | bar = bar + |) + |""".stripMargin + val error = + """|:4: error: `;` expected but `,` found + | case baz => baz, + | ^""".stripMargin + runTestError[Stat](code, error) + } + test("indented-double-apply") { runTestAssert[Stat]( """|def method = From 83a6e86c49701ecc094423ef7ea38cf5be3dbb39 Mon Sep 17 00:00:00 2001 From: Albert Meltzer <7529386+kitbellew@users.noreply.github.com> Date: Fri, 22 Mar 2024 00:38:17 -0700 Subject: [PATCH 2/2] ScannerTokens: keep multiple outdents to swap `,` `nextToken` ignored the `.next` field and tried to recompute the next token; instead, we should not do that if that field is already set. --- .../internal/parsers/LazyTokenIterator.scala | 6 ++--- .../meta/internal/parsers/ScannerTokens.scala | 13 +++++----- .../dotty/SignificantIndentationSuite.scala | 24 +++++++++++++++---- 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/scalameta/parsers/shared/src/main/scala/scala/meta/internal/parsers/LazyTokenIterator.scala b/scalameta/parsers/shared/src/main/scala/scala/meta/internal/parsers/LazyTokenIterator.scala index c3f7780253..7bbcd23dd5 100644 --- a/scalameta/parsers/shared/src/main/scala/scala/meta/internal/parsers/LazyTokenIterator.scala +++ b/scalameta/parsers/shared/src/main/scala/scala/meta/internal/parsers/LazyTokenIterator.scala @@ -21,9 +21,9 @@ private[parsers] class LazyTokenIterator private ( import scannerTokens._ - private def getNextTokenRef(): TokenRef = { - if (curr.next eq null) nextToken(curr) else curr.next - } + @inline + private def getNextTokenRef(): TokenRef = + nextToken(curr) override def next(): Unit = { prev = curr diff --git a/scalameta/parsers/shared/src/main/scala/scala/meta/internal/parsers/ScannerTokens.scala b/scalameta/parsers/shared/src/main/scala/scala/meta/internal/parsers/ScannerTokens.scala index ff1e5797b7..ae020322d4 100644 --- a/scalameta/parsers/shared/src/main/scala/scala/meta/internal/parsers/ScannerTokens.scala +++ b/scalameta/parsers/shared/src/main/scala/scala/meta/internal/parsers/ScannerTokens.scala @@ -325,15 +325,16 @@ final class ScannerTokens(val tokens: Tokens)(implicit dialect: Dialect) { } } - @inline - private[parsers] def nextToken(ref: TokenRef): TokenRef = { - val next = nextToken(ref.token, ref.pos, ref.nextPos, ref.regions) - ref.next = next - next + private[parsers] def nextToken(ref: TokenRef): TokenRef = ref.next match { + case null => + val next = nextToken(ref.token, ref.pos, ref.nextPos, ref.regions) + ref.next = next + next + case nref => nref } @tailrec - private[parsers] def nextToken( + private def nextToken( prevToken: Token, prevPos: Int, currPos: Int, diff --git a/tests/shared/src/test/scala/scala/meta/tests/parsers/dotty/SignificantIndentationSuite.scala b/tests/shared/src/test/scala/scala/meta/tests/parsers/dotty/SignificantIndentationSuite.scala index 9fbccd6fb7..80ed02935a 100644 --- a/tests/shared/src/test/scala/scala/meta/tests/parsers/dotty/SignificantIndentationSuite.scala +++ b/tests/shared/src/test/scala/scala/meta/tests/parsers/dotty/SignificantIndentationSuite.scala @@ -1684,11 +1684,25 @@ class SignificantIndentationSuite extends BaseDottySuite { | bar = bar |) |""".stripMargin - val error = - """|:4: error: `;` expected but `,` found - | case baz => baz, - | ^""".stripMargin - runTestError[Stat](code, error) + val layout = + """|A(foo = x => x match { + | case baz => baz + |}, bar = bar) + |""".stripMargin + val tree = Term.Apply( + tname("A"), + List( + Term.Assign( + tname("foo"), + Term.Function( + List(tparam("x")), + Term.Match(tname("x"), List(Case(Pat.Var(tname("baz")), None, tname("baz"))), Nil) + ) + ), + Term.Assign(tname("bar"), tname("bar")) + ) + ) + runTestAssert[Stat](code, layout)(tree) } test("indented-double-apply") {