Skip to content

Commit d0a9370

Browse files
authored
Merge pull request #234 from romanowski/postprocessor-fixes
Post processors can now report warning.
2 parents 185d8bf + a322491 commit d0a9370

File tree

9 files changed

+117
-52
lines changed

9 files changed

+117
-52
lines changed

modules/build/src/main/scala/scala/build/Build.scala

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -616,8 +616,9 @@ object Build {
616616
logger,
617617
inputs.workspace,
618618
updateSemanticDbs = true,
619-
updateTasty = project.scalaCompiler.scalaVersion.startsWith("3.")
619+
scalaVersion = project.scalaCompiler.scalaVersion
620620
)
621+
.left.foreach(_.foreach(logger.message(_)))
621622

622623
Successful(
623624
inputs,
@@ -650,8 +651,8 @@ object Build {
650651
logger: Logger,
651652
workspace: os.Path,
652653
updateSemanticDbs: Boolean,
653-
updateTasty: Boolean
654-
): Unit = {
654+
scalaVersion: String
655+
): Either[Seq[String], Unit] = {
655656

656657
// TODO Write classes to a separate directory during post-processing
657658
logger.debug("Post-processing class files of pre-processed sources")
@@ -668,10 +669,13 @@ object Build {
668669
val postProcessors =
669670
Seq(ByteCodePostProcessor) ++
670671
(if (updateSemanticDbs) Seq(SemanticDbPostProcessor) else Nil) ++
671-
(if (updateTasty) Seq(TastyPostProcessor) else Nil)
672+
Seq(TastyPostProcessor)
672673

673-
for (p <- postProcessors)
674-
p.postProcess(generatedSources, mappings, workspace, classesDir, logger)
674+
val failures = postProcessors.flatMap(
675+
_.postProcess(generatedSources, mappings, workspace, classesDir, logger, scalaVersion)
676+
.fold(e => Seq(e), _ => Nil)
677+
)
678+
if (failures.isEmpty) Right(()) else Left(failures)
675679
}
676680

677681
def onChangeBufferedObserver(onEvent: PathWatchers.Event => Unit): Observer[PathWatchers.Event] =

modules/build/src/main/scala/scala/build/bsp/BspImpl.scala

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,18 @@ final class BspImpl(
138138
client.resetBuildExceptionDiagnostics(targetId)
139139
}
140140

141+
private val shownGlobalMessages =
142+
new java.util.concurrent.ConcurrentHashMap[String, Unit]()
143+
144+
private def showGlobalWarningOnce(msg: String) =
145+
shownGlobalMessages.computeIfAbsent(
146+
msg,
147+
_ => {
148+
val params = new b.ShowMessageParams(b.MessageType.WARNING, msg)
149+
actualLocalClient.onBuildShowMessage(params)
150+
}
151+
)
152+
141153
def compile(
142154
actualLocalServer: BspServer,
143155
executor: Executor,
@@ -185,8 +197,8 @@ final class BspImpl(
185197
logger,
186198
inputs.workspace,
187199
updateSemanticDbs = true,
188-
updateTasty = true
189-
)
200+
scalaVersion = project.scalaCompiler.scalaVersion
201+
).left.foreach(_.foreach(showGlobalWarningOnce))
190202
res
191203
},
192204
executor
Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
package scala.build.postprocessing
22

33
import scala.build.{GeneratedSource, Logger}
4+
import scala.util.{Either, Right}
45

56
case object ByteCodePostProcessor extends PostProcessor {
67
def postProcess(
78
generatedSources: Seq[GeneratedSource],
89
mappings: Map[String, (String, Int)],
910
workspace: os.Path,
1011
output: os.Path,
11-
logger: Logger
12-
): Unit =
13-
AsmPositionUpdater.postProcess(mappings, output, logger)
12+
logger: Logger,
13+
scalaVersion: String
14+
): Either[String, Unit] =
15+
Right(AsmPositionUpdater.postProcess(mappings, output, logger))
1416
}

modules/build/src/main/scala/scala/build/postprocessing/PostProcessor.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ trait PostProcessor {
88
mappings: Map[String, (String, Int)],
99
workspace: os.Path,
1010
output: os.Path,
11-
logger: Logger
12-
): Unit
11+
logger: Logger,
12+
scalaVersion: String
13+
): Either[String, Unit]
1314
}

modules/build/src/main/scala/scala/build/postprocessing/SemanticDbPostProcessor.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,16 @@ import java.nio.file.FileSystemException
44

55
import scala.annotation.tailrec
66
import scala.build.{GeneratedSource, Logger}
7-
7+
import scala.util.{Either, Right}
88
case object SemanticDbPostProcessor extends PostProcessor {
99
def postProcess(
1010
generatedSources: Seq[GeneratedSource],
1111
mappings: Map[String, (String, Int)],
1212
workspace: os.Path,
1313
output: os.Path,
14-
logger: Logger
15-
): Unit = {
14+
logger: Logger,
15+
scalaVersion: String
16+
): Either[String, Unit] = Right {
1617
logger.debug("Moving semantic DBs around")
1718
val semDbRoot = output / "META-INF" / "semanticdb"
1819
for (source <- generatedSources; originalSource <- source.reportingPath) {
Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
package scala.build.postprocessing
22

3-
import scala.build.tastylib.TastyData
3+
import scala.build.internal.Constants
4+
import scala.build.tastylib.{TastyData, TastyVersions}
45
import scala.build.{GeneratedSource, Logger}
56

67
case object TastyPostProcessor extends PostProcessor {
8+
79
def postProcess(
810
generatedSources: Seq[GeneratedSource],
911
mappings: Map[String, (String, Int)],
1012
workspace: os.Path,
1113
output: os.Path,
12-
logger: Logger
13-
): Unit = {
14+
logger: Logger,
15+
scalaVersion: String
16+
): Either[String, Unit] = {
1417

15-
val updatedPaths = generatedSources
18+
def updatedPaths = generatedSources
1619
.flatMap { source =>
1720
source.reportingPath.toOption.toSeq.map { originalSource =>
1821
val fromSourceRoot = source.generated.relativeTo(workspace)
@@ -22,32 +25,45 @@ case object TastyPostProcessor extends PostProcessor {
2225
}
2326
.toMap
2427

25-
if (updatedPaths.nonEmpty)
26-
os.walk(output)
27-
.filter(os.isFile(_))
28-
.filter(_.last.endsWith(".tasty")) // make that case-insensitive just in case?
29-
.foreach { f =>
30-
logger.debug(s"Reading TASTy file $f")
31-
val content = os.read.bytes(f)
32-
val data = TastyData.read(content)
33-
logger.debug(s"Parsed TASTy file $f")
34-
var updatedOne = false
35-
val updatedData = data.mapNames { n =>
36-
updatedPaths.get(n) match {
37-
case Some(newName) =>
38-
updatedOne = true
39-
newName
40-
case None =>
41-
n
42-
}
43-
}
44-
if (updatedOne) {
45-
logger.debug(
46-
s"Overwriting ${if (f.startsWith(os.pwd)) f.relativeTo(os.pwd) else f}"
47-
)
48-
val updatedContent = TastyData.write(updatedData)
49-
os.write.over(f, updatedContent)
50-
}
51-
}
28+
TastyVersions.shouldRunPreprocessor(scalaVersion, Constants.version) match {
29+
case Right(false) => Right(())
30+
case Left(msg) => if (updatedPaths.isEmpty) Right(()) else Left(msg)
31+
case Right(true) =>
32+
val paths = updatedPaths
33+
if (paths.isEmpty) Right(())
34+
else Right(
35+
os.walk(output)
36+
.filter(os.isFile(_))
37+
.filter(_.last.endsWith(".tasty")) // make that case-insensitive just in case?
38+
.foreach(updateTastyFile(logger, paths))
39+
)
40+
}
41+
}
42+
43+
private def updateTastyFile(
44+
logger: Logger,
45+
updatedPaths: Map[String, String]
46+
)(f: os.Path): Unit = {
47+
logger.debug(s"Reading TASTy file $f")
48+
val content = os.read.bytes(f)
49+
val data = TastyData.read(content)
50+
logger.debug(s"Parsed TASTy file $f")
51+
var updatedOne = false
52+
val updatedData = data.mapNames { n =>
53+
updatedPaths.get(n) match {
54+
case Some(newName) =>
55+
updatedOne = true
56+
newName
57+
case None =>
58+
n
59+
}
60+
}
61+
if (updatedOne) {
62+
logger.debug(
63+
s"Overwriting ${if (f.startsWith(os.pwd)) f.relativeTo(os.pwd) else f}"
64+
)
65+
val updatedContent = TastyData.write(updatedData)
66+
os.write.over(f, updatedContent)
67+
}
5268
}
5369
}

modules/tasty-lib/src/main/scala/scala/build/tastylib/TastyFormat.scala

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,10 +18,6 @@ object TastyFormat {
1818

1919
final val header: Array[Int] = Array(0x5c, 0xa1, 0xab, 0x1f)
2020

21-
final val MajorVersion: Int = 28
22-
final val MinorVersion: Int = 1
23-
final val ExperimentalVersion: Int = 0
24-
2521
def isVersionCompatible(
2622
fileMajor: Int,
2723
fileMinor: Int,

modules/tasty-lib/src/main/scala/scala/build/tastylib/TastyHeaderUnpickler.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@ package scala.build.tastylib
1616

1717
import java.util.UUID
1818

19-
import scala.build.tastylib.TastyFormat.{ExperimentalVersion, MajorVersion, MinorVersion, header}
19+
import scala.build.tastylib.TastyFormat.header
20+
import scala.build.tastylib.TastyVersions.{ExperimentalVersion, MajorVersion, MinorVersion}
2021

2122
class TastyHeaderUnpickler(reader: TastyReader) {
2223
import TastyHeaderUnpickler._
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package scala.build.tastylib
2+
3+
object TastyVersions {
4+
5+
// Every time tasty version is updated, please update LatestSupportedScala as well!
6+
final val MajorVersion: Int = 28
7+
final val MinorVersion: Int = 1
8+
final val ExperimentalVersion: Int = 0
9+
10+
object LatestSupportedScala {
11+
final val MajorVersion: Int = 3
12+
final val MinorVersion: Int = 1
13+
}
14+
15+
def shouldRunPreprocessor(
16+
scalaVersion: String,
17+
scalaCliVersion: String
18+
): Either[String, Boolean] =
19+
if (!scalaVersion.startsWith("3.") && scalaVersion != "3" ) Right(false)
20+
else
21+
scalaVersion.split('.')(1).toInt match {
22+
case scalaMinor if scalaMinor > LatestSupportedScala.MinorVersion =>
23+
Left(
24+
s"Scala CLI (v. $scalaCliVersion) cannot post process TASTY files from Scala $scalaVersion.\n" +
25+
s"This is not a fatal error since post processing only cleans up source paths in TASTY file " +
26+
s"and it should not affect your application.\n" +
27+
s"To get rid of this message, please update Scala CLI version."
28+
)
29+
case _ =>
30+
Right(true)
31+
}
32+
}

0 commit comments

Comments
 (0)