Skip to content

Commit 279ac20

Browse files
Merge pull request #210 from alexarchambault/using-directives-errors
Report errors for using directives in console and via BSP
2 parents 388d18c + 850acbc commit 279ac20

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1053
-378
lines changed

build.sc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -367,8 +367,6 @@ trait CliIntegrationBase extends SbtModule with ScalaCliPublishModule with HasTe
367367
| def scala3 = "${Scala.scala3}"
368368
| def defaultScala = "${Scala.defaultUser}"
369369
| def bloopVersion = "${Deps.bloopConfig.dep.version}"
370-
| def oldBloopVersion = "${TestDeps.oldBloopConfig.dep.version}"
371-
| def newBloopVersion = "${TestDeps.newBloopConfig.dep.version}"
372370
| def pprintVersion = "${TestDeps.pprint.dep.version}"
373371
| def munitVersion = "${TestDeps.munit.dep.version}"
374372
| def dockerTestImage = "${Docker.testImage}"
@@ -504,6 +502,7 @@ class BloopRifle(val crossScalaVersion: String) extends CrossSbtModule with Scal
504502
|/** Build-time constants. Generated by mill. */
505503
|object Constants {
506504
| def bloopVersion = "${Deps.bloopConfig.dep.version}"
505+
| def bloopScalaVersion = "${Scala.scala212}"
507506
| def bspVersion = "${Deps.bsp4j.dep.version}"
508507
|}
509508
|""".stripMargin

modules/bloop-rifle/src/main/scala/scala/build/blooprifle/BloopRifle.scala

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -221,22 +221,20 @@ object BloopRifle {
221221
def shutdownBloopIfVersionIncompatible(
222222
config: BloopRifleConfig,
223223
logger: BloopRifleLogger,
224-
workdir: Path,
224+
workDir: Path,
225225
scheduler: ScheduledExecutorService
226226
): Boolean = {
227-
val currentBloopVersion = getCurrentBloopVersion(config, logger, workdir, scheduler)
228-
val bloopExitNeeded = config.acceptBloopVersion.exists { f =>
229-
currentBloopVersion.map(f).getOrElse(true)
227+
val currentBloopVersion = getCurrentBloopVersion(config, logger, workDir, scheduler)
228+
val isOk = config.acceptBloopVersion.forall { f =>
229+
currentBloopVersion.forall(f(_))
230230
}
231-
if (bloopExitNeeded) {
232-
logger.debug(
233-
s"Shutting down unsupported bloop v$currentBloopVersion."
234-
)
235-
val retCode = exit(config, workdir, logger)
236-
logger.debug(s"Bloop exit return code: $retCode")
231+
if (isOk)
232+
logger.debug("No need to restart Bloop")
233+
else {
234+
logger.debug(s"Shutting down unsupported Bloop $currentBloopVersion.")
235+
val retCode = exit(config, workDir, logger)
236+
logger.debug(s"Bloop exit code: $retCode")
237237
}
238-
else
239-
logger.debug("No need to reset bloop")
240-
bloopExitNeeded
238+
!isOk
241239
}
242240
}

modules/bloop-rifle/src/main/scala/scala/build/blooprifle/BloopRifleConfig.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@ object BloopRifleConfig {
6969
"ch.epfl.scala:bloop-frontend_2.12"
7070
def hardCodedDefaultVersion: String =
7171
Constants.bloopVersion
72+
def hardCodedDefaultScalaVersion: String =
73+
Constants.bloopScalaVersion
7274

7375
lazy val defaultModule: String = {
7476
val fromEnv = Option(System.getenv("BLOOP_MODULE")).map(_.trim).filter(_.nonEmpty)
@@ -84,6 +86,13 @@ object BloopRifleConfig {
8486
.orElse(fromProps)
8587
.getOrElse(hardCodedDefaultVersion)
8688
}
89+
lazy val defaultScalaVersion: String = {
90+
val fromEnv = Option(System.getenv("BLOOP_SCALA_VERSION")).filter(_.nonEmpty)
91+
def fromProps = sys.props.get("bloop.scala-version").filter(_.nonEmpty)
92+
fromEnv
93+
.orElse(fromProps)
94+
.getOrElse(hardCodedDefaultScalaVersion)
95+
}
8796

8897
def default(
8998
bloopClassPath: () => Either[Throwable, Seq[File]]

modules/build/src/main/scala/scala/build/Artifacts.scala

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -61,8 +61,8 @@ object Artifacts {
6161

6262
def apply(
6363
params: ScalaParameters,
64-
compilerPlugins: Seq[AnyDependency],
65-
dependencies: Seq[AnyDependency],
64+
compilerPlugins: Seq[Positioned[AnyDependency]],
65+
dependencies: Seq[Positioned[AnyDependency]],
6666
extraClassPath: Seq[Path],
6767
extraCompileOnlyJars: Seq[Path],
6868
extraSourceJars: Seq[Path],
@@ -119,19 +119,20 @@ object Artifacts {
119119

120120
val allExtraRepositories = maybeSnapshotRepo ++ extraRepositories
121121

122-
val updatedDependencies = dependencies ++
123-
jvmRunnerDependencies ++
124-
jvmTestRunnerDependencies ++
125-
jsTestBridgeDependencies ++
126-
jmhDependencies
122+
val updatedDependencies =
123+
dependencies ++
124+
jvmRunnerDependencies.map(Positioned.none(_)) ++
125+
jvmTestRunnerDependencies.map(Positioned.none(_)) ++
126+
jsTestBridgeDependencies.map(Positioned.none(_)) ++
127+
jmhDependencies.map(Positioned.none(_))
127128

128129
val compilerArtifacts = value {
129-
artifacts(compilerDependencies, allExtraRepositories, params, logger)
130+
artifacts(Positioned.none(compilerDependencies), allExtraRepositories, params, logger)
130131
}
131132

132133
val fetchRes = value {
133134
fetch(
134-
updatedDependencies,
135+
Positioned.sequence(updatedDependencies),
135136
allExtraRepositories,
136137
params,
137138
logger,
@@ -143,7 +144,7 @@ object Artifacts {
143144
if (addStubs)
144145
value {
145146
artifacts(
146-
Seq(dep"$stubsOrganization:$stubsModuleName:$stubsVersion"),
147+
Positioned.none(Seq(dep"$stubsOrganization:$stubsModuleName:$stubsVersion")),
147148
allExtraRepositories,
148149
params,
149150
logger
@@ -154,10 +155,11 @@ object Artifacts {
154155

155156
val compilerPlugins0 = value {
156157
compilerPlugins
157-
.map { dep =>
158-
val dep0 = dep.copy(userParams = dep.userParams + ("intransitive" -> None))
159-
artifacts(Seq(dep0), allExtraRepositories, params, logger)
160-
.map(_.map { case (url, path) => (dep0, url, path) })
158+
.map { posDep =>
159+
val posDep0 =
160+
posDep.map(dep => dep.copy(userParams = dep.userParams + ("intransitive" -> None)))
161+
artifacts(posDep0.map(Seq(_)), allExtraRepositories, params, logger)
162+
.map(_.map { case (url, path) => (posDep0.value, url, path) })
161163
}
162164
.sequence
163165
.left.map(CompositeBuildException(_))
@@ -168,7 +170,7 @@ object Artifacts {
168170
compilerDependencies,
169171
compilerArtifacts,
170172
compilerPlugins0,
171-
updatedDependencies,
173+
updatedDependencies.map(_.value),
172174
fetchRes.fullDetailedArtifacts.collect { case (d, p, a, Some(f)) => (d, p, a, f.toPath) },
173175
extraClassPath ++ extraStubsJars,
174176
extraCompileOnlyJars,
@@ -178,7 +180,7 @@ object Artifacts {
178180
}
179181

180182
private[build] def artifacts(
181-
dependencies: Seq[AnyDependency],
183+
dependencies: Positioned[Seq[AnyDependency]],
182184
extraRepositories: Seq[String],
183185
params: ScalaParameters,
184186
logger: Logger,
@@ -199,14 +201,14 @@ object Artifacts {
199201
}
200202

201203
private[build] def fetch(
202-
dependencies: Seq[AnyDependency],
204+
dependencies: Positioned[Seq[AnyDependency]],
203205
extraRepositories: Seq[String],
204206
params: ScalaParameters,
205207
logger: Logger,
206208
classifiersOpt: Option[Set[String]]
207209
): Either[BuildException, Fetch.Result] = either {
208210
logger.debug {
209-
s"Fetching $dependencies" +
211+
s"Fetching ${dependencies.value}" +
210212
(if (extraRepositories.isEmpty) "" else s", adding $extraRepositories")
211213
}
212214

@@ -222,7 +224,7 @@ object Artifacts {
222224
var fetcher = coursier.Fetch()
223225
.withCache(cache)
224226
.addRepositories(extraRepositories0: _*)
225-
.addDependencies(dependencies.map(_.toCs(params)): _*)
227+
.addDependencies(dependencies.value.map(_.toCs(params)): _*)
226228
for (classifiers <- classifiersOpt) {
227229
if (classifiers("_"))
228230
fetcher = fetcher.withMainArtifacts()
@@ -232,7 +234,7 @@ object Artifacts {
232234

233235
value {
234236
fetcher.eitherResult()
235-
.left.map(ex => new FetchingDependenciesError(ex))
237+
.left.map(ex => new FetchingDependenciesError(ex, dependencies.positions))
236238
}
237239
}
238240

modules/build/src/main/scala/scala/build/Bloop.scala

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import scala.build.blooprifle.BloopRifleConfig
1111
import scala.build.errors.{BuildException, ModuleFormatError}
1212
import scala.concurrent.duration.FiniteDuration
1313
import scala.jdk.CollectionConverters._
14-
import scala.util.Properties
1514

1615
object Bloop {
1716

@@ -49,18 +48,24 @@ object Bloop {
4948
logger: Logger
5049
): Either[BuildException, Seq[File]] =
5150
either {
52-
value(Artifacts.artifacts(Seq(dep), Nil, params, logger))
51+
value(Artifacts.artifacts(Positioned.none(Seq(dep)), Nil, params, logger))
5352
.map(_._2.toFile)
5453
}
5554

56-
def bloopClassPath(logger: Logger): Either[BuildException, Seq[File]] = either {
55+
def bloopClassPath(logger: Logger): Either[BuildException, Seq[File]] =
56+
bloopClassPath(logger, BloopRifleConfig.defaultVersion)
57+
58+
def bloopClassPath(
59+
logger: Logger,
60+
bloopVersion: String
61+
): Either[BuildException, Seq[File]] = either {
5762
val moduleStr = BloopRifleConfig.defaultModule
5863
val mod = value {
5964
ModuleParser.parse(moduleStr)
6065
.left.map(err => new ModuleFormatError(moduleStr, err, Some("Bloop")))
6166
}
62-
val dep = DependencyLike(mod, BloopRifleConfig.defaultVersion)
63-
val sv = Properties.versionNumberString
67+
val dep = DependencyLike(mod, bloopVersion)
68+
val sv = BloopRifleConfig.defaultScalaVersion
6469
val sbv = ScalaVersion.binary(sv)
6570
val params = ScalaParameters(sv, sbv)
6671
value(bloopClassPath(dep, params, logger))

modules/build/src/main/scala/scala/build/ConsoleBloopBuildClient.scala

Lines changed: 61 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -67,42 +67,6 @@ class ConsoleBloopBuildClient(
6767
(originalPath, updatedDiag)
6868
}
6969

70-
private def printDiagnostic(path: Either[String, os.Path], diag: bsp4j.Diagnostic): Unit = {
71-
val isWarningOrError = diag.getSeverity == bsp4j.DiagnosticSeverity.ERROR ||
72-
diag.getSeverity == bsp4j.DiagnosticSeverity.WARNING
73-
if (isWarningOrError) {
74-
val red = Console.RED
75-
val yellow = Console.YELLOW
76-
val reset = Console.RESET
77-
val prefix =
78-
if (diag.getSeverity == bsp4j.DiagnosticSeverity.ERROR) s"[${red}error$reset] "
79-
else s"[${yellow}warn$reset] "
80-
81-
val line = (diag.getRange.getStart.getLine + 1).toString + ":"
82-
val col = (diag.getRange.getStart.getCharacter + 1).toString + ":"
83-
val msgIt = diag.getMessage.linesIterator
84-
85-
val path0 = path match {
86-
case Left(source) => source
87-
case Right(p) if p.startsWith(Os.pwd) =>
88-
"." + File.separator + p.relativeTo(Os.pwd).toString
89-
case Right(p) => p.toString
90-
}
91-
out.println(s"$prefix$path0:$line$col" + (if (msgIt.hasNext) " " + msgIt.next() else ""))
92-
for (line <- msgIt)
93-
out.println(prefix + line)
94-
for (code <- Option(diag.getCode))
95-
code.linesIterator.map(prefix + _).foreach(out.println(_))
96-
val canPrintUnderline = diag.getRange.getStart.getLine == diag.getRange.getEnd.getLine &&
97-
diag.getRange.getStart.getCharacter != null &&
98-
diag.getRange.getEnd.getCharacter != null
99-
if (canPrintUnderline)
100-
out.println(
101-
prefix + " " * diag.getRange.getStart.getCharacter + "^" * (diag.getRange.getEnd.getCharacter - diag.getRange.getStart.getCharacter + 1)
102-
)
103-
}
104-
}
105-
10670
override def onBuildPublishDiagnostics(params: bsp4j.PublishDiagnosticsParams): Unit = {
10771
logger.debug("Received onBuildPublishDiagnostics from bloop: " + params)
10872
for (diag <- params.getDiagnostics.asScala) {
@@ -121,7 +85,7 @@ class ConsoleBloopBuildClient(
12185
.getOrElse((Right(path), diag))
12286
if (keepDiagnostics)
12387
diagnostics0 += updatedPath -> updatedDiag
124-
printDiagnostic(updatedPath, updatedDiag)
88+
ConsoleBloopBuildClient.printDiagnostic(out, updatedPath, updatedDiag)
12589
}
12690
}
12791

@@ -181,3 +145,63 @@ class ConsoleBloopBuildClient(
181145
printedStart = false
182146
}
183147
}
148+
149+
object ConsoleBloopBuildClient {
150+
151+
def printDiagnostic(
152+
out: PrintStream,
153+
path: Either[String, os.Path],
154+
diag: bsp4j.Diagnostic
155+
): Unit = {
156+
val isWarningOrError = diag.getSeverity == bsp4j.DiagnosticSeverity.ERROR ||
157+
diag.getSeverity == bsp4j.DiagnosticSeverity.WARNING
158+
if (isWarningOrError) {
159+
val red = Console.RED
160+
val yellow = Console.YELLOW
161+
val reset = Console.RESET
162+
val prefix =
163+
if (diag.getSeverity == bsp4j.DiagnosticSeverity.ERROR) s"[${red}error$reset] "
164+
else s"[${yellow}warn$reset] "
165+
166+
val line = (diag.getRange.getStart.getLine + 1).toString + ":"
167+
val col = (diag.getRange.getStart.getCharacter + 1).toString + ":"
168+
val msgIt = diag.getMessage.linesIterator
169+
170+
val path0 = path match {
171+
case Left(source) => source
172+
case Right(p) if p.startsWith(Os.pwd) =>
173+
"." + File.separator + p.relativeTo(Os.pwd).toString
174+
case Right(p) => p.toString
175+
}
176+
out.println(s"$prefix$path0:$line$col" + (if (msgIt.hasNext) " " + msgIt.next() else ""))
177+
for (line <- msgIt)
178+
out.println(prefix + line)
179+
val codeOpt = Option(diag.getCode).orElse {
180+
val lineOpt =
181+
if (diag.getRange.getStart.getLine == diag.getRange.getEnd.getLine)
182+
Option(diag.getRange.getStart.getLine)
183+
else None
184+
for {
185+
line <- lineOpt
186+
p <- path.toOption
187+
lines = os.read.lines(p)
188+
line <- if (line < lines.length) Some(lines(line)) else None
189+
} yield line
190+
}
191+
for (code <- codeOpt)
192+
code.linesIterator.map(prefix + _).foreach(out.println(_))
193+
val canPrintUnderline = diag.getRange.getStart.getLine == diag.getRange.getEnd.getLine &&
194+
diag.getRange.getStart.getCharacter != null &&
195+
diag.getRange.getEnd.getCharacter != null &&
196+
codeOpt.nonEmpty
197+
if (canPrintUnderline) {
198+
val len =
199+
math.max(1, diag.getRange.getEnd.getCharacter - diag.getRange.getStart.getCharacter)
200+
out.println(
201+
prefix + " " * diag.getRange.getStart.getCharacter + "^" * len
202+
)
203+
}
204+
}
205+
}
206+
207+
}

0 commit comments

Comments
 (0)