From 59750cea86ac5bcae5396256e63cfba1fedb2212 Mon Sep 17 00:00:00 2001 From: kasiaMarek Date: Thu, 9 Jan 2025 13:06:00 +0100 Subject: [PATCH] fix: skip using directives for auto import position when missing newline --- .../pc/ScriptFirstImportPosition.scala | 53 +++++++++++++++---- .../tests/scalacli/ScalaCliActionsSuite.scala | 21 ++++++++ 2 files changed, 65 insertions(+), 9 deletions(-) diff --git a/mtags/src/main/scala/scala/meta/internal/pc/ScriptFirstImportPosition.scala b/mtags/src/main/scala/scala/meta/internal/pc/ScriptFirstImportPosition.scala index ef28628bb86..fd4cdcc627a 100644 --- a/mtags/src/main/scala/scala/meta/internal/pc/ScriptFirstImportPosition.scala +++ b/mtags/src/main/scala/scala/meta/internal/pc/ScriptFirstImportPosition.scala @@ -1,6 +1,7 @@ package scala.meta.internal.pc import scala.annotation.tailrec +import scala.util.matching.Regex import scala.meta._ import scala.meta.internal.mtags.MtagsEnrichments._ @@ -85,17 +86,20 @@ object ScriptFirstImportPosition { beforeComment: Int, lastOffset: Int, newLines: Int, - foundShebang: Boolean + foundShebang: Boolean, + foundCommentThatIsNotUsingDirective: Boolean = false ): Int = { if (it.hasNext) { - it.next match { + val n = it.next() + n match { case t: Token.Comment if t.value.startsWith(shebang) => skipComments( it, beforeComment, t.pos.end, newLines = 0, - foundShebang = true + foundShebang = true, + foundCommentThatIsNotUsingDirective ) case t: Token.Comment if newLines > 1 => skipComments( @@ -103,7 +107,11 @@ object ScriptFirstImportPosition { lastOffset, t.pos.end, newLines = 0, - foundShebang + foundShebang, + foundCommentThatIsNotUsingDirective = + foundCommentThatIsNotUsingDirective || !isScalaCliUsingDirectiveComment( + t + ) ) case t: Token.Comment => skipComments( @@ -111,7 +119,11 @@ object ScriptFirstImportPosition { beforeComment, t.pos.end, newLines = 0, - foundShebang + foundShebang, + foundCommentThatIsNotUsingDirective = + foundCommentThatIsNotUsingDirective || !isScalaCliUsingDirectiveComment( + t + ) ) case t: Token.AtEOL => skipComments( @@ -119,16 +131,31 @@ object ScriptFirstImportPosition { beforeComment, lastOffset, newLines + t.newlines, - foundShebang + foundShebang, + foundCommentThatIsNotUsingDirective ) case _: Token.Whitespace => - skipComments(it, beforeComment, lastOffset, newLines, foundShebang) + skipComments( + it, + beforeComment, + lastOffset, + newLines, + foundShebang, + foundCommentThatIsNotUsingDirective + ) case _: Token.BOF => - skipComments(it, beforeComment, lastOffset, newLines, foundShebang) + skipComments( + it, + beforeComment, + lastOffset, + newLines, + foundShebang, + foundCommentThatIsNotUsingDirective + ) case _ => // There is an empty line between the comment and the code, so its not a doc val maybeOffset = - if (newLines > 1) lastOffset + if (newLines > 1 || !foundCommentThatIsNotUsingDirective) lastOffset else beforeComment if (foundShebang) maybeOffset - 2 else maybeOffset @@ -136,4 +163,12 @@ object ScriptFirstImportPosition { } else lastOffset } + val scalaCliUsingDirectiveRegex: Regex = """//>\s*using.*"""".r + + private def isScalaCliUsingDirectiveComment(t: Token.Comment): Boolean = + t.text match { + case scalaCliUsingDirectiveRegex() => true + case _ => false + } + } diff --git a/tests/slow/src/test/scala/tests/scalacli/ScalaCliActionsSuite.scala b/tests/slow/src/test/scala/tests/scalacli/ScalaCliActionsSuite.scala index e7c1c3b7814..634400c9e3d 100644 --- a/tests/slow/src/test/scala/tests/scalacli/ScalaCliActionsSuite.scala +++ b/tests/slow/src/test/scala/tests/scalacli/ScalaCliActionsSuite.scala @@ -174,6 +174,27 @@ class ScalaCliActionsSuite fileName = "A.sc", ) + checkScalaCLI( + "i7071", + s"""|//> using scala "${BuildInfo.scala213}" + |object X { + | <> + |} + |""".stripMargin, + s"""|${ImportMissingSymbol.title("FiniteDuration", "scala.concurrent.duration")} + |${CreateNewSymbol.title("FiniteDuration")} + |""".stripMargin, + s"""|//> using scala "${BuildInfo.scala213}" + |import scala.concurrent.duration.FiniteDuration + |object X { + | FiniteDuration + |} + |""".stripMargin, + scalaCliOptions = List("--actions", "-S", scalaVersion), + expectNoDiagnostics = false, + fileName = "A.scala", + ) + checkScalaCLI( "script-organize-imports", s"""|//> using scala "${BuildInfo.scala213}"