[2.x] fix: support comma-separated imports in build.sbt (#8829)

Summary
- Fix `SbtParser.importsToLineRanges` to prepend `import` keyword when missing from Dotty's `Import` AST node source spans
- Add unit test for comma-separated import parsing
This commit is contained in:
Renzo 2026-03-01 02:12:38 +02:00 committed by GitHub
parent c1475da07c
commit 5271babfa5
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 78 additions and 1 deletions

View File

@ -283,6 +283,8 @@ private[sbt] case class SbtParser(path: VirtualFileRef, lines: Seq[String])
imports.map { tree =>
val pos = tree.sourcePos
val content = String(pos.source.content.slice(pos.start, pos.end)).trim
(content, tree.sourcePos.line)
// Dotty splits `import a, b` into separate Import trees; subsequent ones lack `import`
val importStr = if content.startsWith("import ") then content else s"import $content"
(importStr, tree.sourcePos.line)
}
end SbtParser

View File

@ -37,6 +37,68 @@ lazy val foo = project
.settings(x := y)""" -> LineRange(7, 8)))
}
test("comma separated imports") {
val ref = VirtualFileRef.of("vfile")
val code = """import scala.util, util.Random
def f = Random.nextInt()
"""
val p = SbtParser(ref, code.linesIterator.toList)
assert(p.imports.size == 2)
assert(p.imports(0)._1 == "import scala.util")
assert(p.imports(1)._1 == "import util.Random")
assert(p.settings.size == 1)
}
test("comma separated imports with three entries") {
val ref = VirtualFileRef.of("vfile")
val code = """import scala.util, util.Random, util.Properties
val x = 1
"""
val p = SbtParser(ref, code.linesIterator.toList)
assert(p.imports.size == 3)
assert(p.imports(0)._1 == "import scala.util")
assert(p.imports(1)._1 == "import util.Random")
assert(p.imports(2)._1 == "import util.Properties")
}
test("comma separated imports with wildcard") {
val ref = VirtualFileRef.of("vfile")
val code = """import scala.util, util.*
val x = 1
"""
val p = SbtParser(ref, code.linesIterator.toList)
assert(p.imports.size == 2)
assert(p.imports(0)._1 == "import scala.util")
assert(p.imports(1)._1 == "import util.*")
}
test("comma separated imports with rename") {
val ref = VirtualFileRef.of("vfile")
val code = """import scala.util, util.{Random => Rng}
val x = 1
"""
val p = SbtParser(ref, code.linesIterator.toList)
assert(p.imports.size == 2)
assert(p.imports(0)._1 == "import scala.util")
assert(p.imports(1)._1 == "import util.{Random => Rng}")
}
test("comma separated imports with multiple selectors") {
val ref = VirtualFileRef.of("vfile")
val code = """import scala.util, util.{Random, Properties}
val x = 1
"""
val p = SbtParser(ref, code.linesIterator.toList)
assert(p.imports.size == 2)
assert(p.imports(0)._1 == "import scala.util")
assert(p.imports(1)._1 == "import util.{Random, Properties}")
}
test("isIdentifier") {
assert(SbtParser.isIdentifier("1a") == false)
}

View File

@ -0,0 +1,11 @@
import scala.util, util.Random
import scala.collection.mutable, mutable.{ArrayBuffer, ListBuffer}
import scala.concurrent, concurrent.*
val check = taskKey[Unit]("check comma-separated import works")
check := {
val _ = Random.nextInt()
val _ = ArrayBuffer(1, 2, 3)
val _ = ListBuffer("a", "b")
val _ = Future.successful(1)
}

View File

@ -0,0 +1,2 @@
# Verify that comma-separated imports work in build.sbt
> check