Skip to content

Commit c36de8a

Browse files
Move post-processing stuff to its own class hierarchy (#128)
1 parent d1ba138 commit c36de8a

File tree

9 files changed

+162
-111
lines changed

9 files changed

+162
-111
lines changed

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

Lines changed: 9 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,9 @@ import com.swoval.files.FileTreeViews.Observer
66
import com.swoval.files.{FileTreeRepositories, PathWatcher, PathWatchers}
77
import dependency._
88
import scala.build.blooprifle.BloopRifleConfig
9-
import scala.build.internal.{
10-
AsmPositionUpdater,
11-
Constants,
12-
CustomCodeWrapper,
13-
LineConversion,
14-
MainClass,
15-
SemanticdbProcessor,
16-
Util
17-
}
9+
import scala.build.internal.{Constants, CustomCodeWrapper, MainClass, Util}
1810
import scala.build.options.BuildOptions
19-
import scala.build.tastylib.TastyData
11+
import scala.build.postprocessing._
2012

2113
import java.io.{File, IOException}
2214
import java.lang.{Boolean => JBoolean}
@@ -465,20 +457,6 @@ object Build {
465457
Failed(inputs, options, sources, artifacts, project, buildClient.diagnostics)
466458
}
467459

468-
@tailrec
469-
private def deleteSubPathIfEmpty(base: os.Path, subPath: os.SubPath, logger: Logger): Unit =
470-
if (subPath.segments.nonEmpty) {
471-
val p = base / subPath
472-
if (os.isDir(p) && os.list.stream(p).headOption.isEmpty) {
473-
try os.remove(p)
474-
catch {
475-
case e: FileSystemException =>
476-
logger.debug(s"Ignoring $e while cleaning up $p")
477-
}
478-
deleteSubPathIfEmpty(base, subPath / os.up, logger)
479-
}
480-
}
481-
482460
def postProcess(
483461
generatedSources: Seq[GeneratedSource],
484462
generatedSrcRoot: os.Path,
@@ -500,90 +478,14 @@ object Build {
500478
(relPath, (reportingPath, lineShift))
501479
}
502480
.toMap
503-
AsmPositionUpdater.postProcess(mappings, classesDir, logger)
504-
505-
if (updateSemanticDbs) {
506-
logger.debug("Moving semantic DBs around")
507-
val semDbRoot = classesDir / "META-INF" / "semanticdb"
508-
for (source <- generatedSources; originalSource <- source.reportingPath) {
509-
val fromSourceRoot = source.generated.relativeTo(workspace)
510-
val actual = originalSource.relativeTo(workspace)
511-
512-
val semDbSubPath = {
513-
val dirSegments = fromSourceRoot.segments.dropRight(1)
514-
os.sub / dirSegments / s"${fromSourceRoot.last}.semanticdb"
515-
}
516-
val semDbFile = semDbRoot / semDbSubPath
517-
if (os.exists(semDbFile)) {
518-
val finalSemDbFile = {
519-
val dirSegments = actual.segments.dropRight(1)
520-
semDbRoot / dirSegments / s"${actual.last}.semanticdb"
521-
}
522-
SemanticdbProcessor.postProcess(
523-
os.read(originalSource),
524-
originalSource.relativeTo(workspace),
525-
None,
526-
if (source.topWrapperLen == 0) n => Some(n)
527-
else
528-
LineConversion.scalaLineToScLine(
529-
os.read(originalSource),
530-
os.read(source.generated),
531-
source.topWrapperLen
532-
),
533-
semDbFile,
534-
finalSemDbFile
535-
)
536-
try os.remove(semDbFile)
537-
catch {
538-
case ex: FileSystemException =>
539-
logger.debug(s"Ignoring $ex while removing $semDbFile")
540-
}
541-
deleteSubPathIfEmpty(semDbRoot, semDbSubPath / os.up, logger)
542-
}
543-
}
544481

545-
if (updateTasty) {
546-
val updatedPaths = generatedSources
547-
.flatMap { source =>
548-
source.reportingPath.toOption.toSeq.map { originalSource =>
549-
val fromSourceRoot = source.generated.relativeTo(workspace)
550-
val actual = originalSource.relativeTo(workspace)
551-
fromSourceRoot.toString -> actual.toString
552-
}
553-
}
554-
.toMap
555-
556-
if (updatedPaths.nonEmpty)
557-
os.walk(classesDir)
558-
.filter(os.isFile(_))
559-
.filter(_.last.endsWith(".tasty")) // make that case-insensitive just in case?
560-
.foreach { f =>
561-
logger.debug(s"Reading TASTy file $f")
562-
val content = os.read.bytes(f)
563-
val data = TastyData.read(content)
564-
logger.debug(s"Parsed TASTy file $f")
565-
var updatedOne = false
566-
val updatedData = data.mapNames { n =>
567-
updatedPaths.get(n) match {
568-
case Some(newName) =>
569-
updatedOne = true
570-
newName
571-
case None =>
572-
n
573-
}
574-
}
575-
if (updatedOne) {
576-
logger.debug(
577-
s"Overwriting ${if (f.startsWith(os.pwd)) f.relativeTo(os.pwd) else f}"
578-
)
579-
val updatedContent = TastyData.write(updatedData)
580-
os.write.over(f, updatedContent)
581-
}
582-
}
583-
}
584-
}
585-
else
586-
logger.debug("Custom generated source directory used, not moving semantic DBs around")
482+
val postProcessors =
483+
Seq(ByteCodePostProcessor) ++
484+
(if (updateSemanticDbs) Seq(SemanticDbPostProcessor) else Nil) ++
485+
(if (updateTasty) Seq(TastyPostProcessor) else Nil)
486+
487+
for (p <- postProcessors)
488+
p.postProcess(generatedSources, mappings, workspace, classesDir, logger)
587489
}
588490

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

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import java.nio.file.Paths
77
import java.util.concurrent.ExecutorService
88

99
import scala.build.{BloopBuildClient, GeneratedSource, Logger}
10-
import scala.build.internal.LineConversion
10+
import scala.build.postprocessing.LineConversion
1111
import scala.collection.JavaConverters._
1212

1313
class BspClient(

modules/build/src/main/scala/scala/build/internal/AsmPositionUpdater.scala renamed to modules/build/src/main/scala/scala/build/postprocessing/AsmPositionUpdater.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package scala.build.internal
1+
package scala.build.postprocessing
22

33
import org.objectweb.asm
44

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
package scala.build.postprocessing
2+
3+
import scala.build.{GeneratedSource, Logger}
4+
5+
case object ByteCodePostProcessor extends PostProcessor {
6+
def postProcess(
7+
generatedSources: Seq[GeneratedSource],
8+
mappings: Map[String, (String, Int)],
9+
workspace: os.Path,
10+
output: os.Path,
11+
logger: Logger
12+
): Unit =
13+
AsmPositionUpdater.postProcess(mappings, output, logger)
14+
}

modules/build/src/main/scala/scala/build/internal/LineConversion.scala renamed to modules/build/src/main/scala/scala/build/postprocessing/LineConversion.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
package scala.build.internal
1+
package scala.build.postprocessing
22

33
object LineConversion {
44

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package scala.build.postprocessing
2+
3+
import scala.build.{GeneratedSource, Logger}
4+
5+
trait PostProcessor {
6+
def postProcess(
7+
generatedSources: Seq[GeneratedSource],
8+
mappings: Map[String, (String, Int)],
9+
workspace: os.Path,
10+
output: os.Path,
11+
logger: Logger
12+
): Unit
13+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package scala.build.postprocessing
2+
3+
import java.nio.file.FileSystemException
4+
5+
import scala.annotation.tailrec
6+
import scala.build.{GeneratedSource, Logger}
7+
8+
case object SemanticDbPostProcessor extends PostProcessor {
9+
def postProcess(
10+
generatedSources: Seq[GeneratedSource],
11+
mappings: Map[String, (String, Int)],
12+
workspace: os.Path,
13+
output: os.Path,
14+
logger: Logger
15+
): Unit = {
16+
logger.debug("Moving semantic DBs around")
17+
val semDbRoot = output / "META-INF" / "semanticdb"
18+
for (source <- generatedSources; originalSource <- source.reportingPath) {
19+
val fromSourceRoot = source.generated.relativeTo(workspace)
20+
val actual = originalSource.relativeTo(workspace)
21+
22+
val semDbSubPath = {
23+
val dirSegments = fromSourceRoot.segments.dropRight(1)
24+
os.sub / dirSegments / s"${fromSourceRoot.last}.semanticdb"
25+
}
26+
val semDbFile = semDbRoot / semDbSubPath
27+
if (os.exists(semDbFile)) {
28+
val finalSemDbFile = {
29+
val dirSegments = actual.segments.dropRight(1)
30+
semDbRoot / dirSegments / s"${actual.last}.semanticdb"
31+
}
32+
SemanticdbProcessor.postProcess(
33+
os.read(originalSource),
34+
originalSource.relativeTo(workspace),
35+
None,
36+
if (source.topWrapperLen == 0) n => Some(n)
37+
else
38+
LineConversion.scalaLineToScLine(
39+
os.read(originalSource),
40+
os.read(source.generated),
41+
source.topWrapperLen
42+
),
43+
semDbFile,
44+
finalSemDbFile
45+
)
46+
try os.remove(semDbFile)
47+
catch {
48+
case ex: FileSystemException =>
49+
logger.debug(s"Ignoring $ex while removing $semDbFile")
50+
}
51+
deleteSubPathIfEmpty(semDbRoot, semDbSubPath / os.up, logger)
52+
}
53+
}
54+
}
55+
56+
@tailrec
57+
private def deleteSubPathIfEmpty(base: os.Path, subPath: os.SubPath, logger: Logger): Unit =
58+
if (subPath.segments.nonEmpty) {
59+
val p = base / subPath
60+
if (os.isDir(p) && os.list.stream(p).headOption.isEmpty) {
61+
try os.remove(p)
62+
catch {
63+
case e: FileSystemException =>
64+
logger.debug(s"Ignoring $e while cleaning up $p")
65+
}
66+
deleteSubPathIfEmpty(base, subPath / os.up, logger)
67+
}
68+
}
69+
}

modules/build/src/main/scala/scala/build/internal/SemanticdbProcessor.scala renamed to modules/build/src/main/scala/scala/build/postprocessing/SemanticdbProcessor.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// adapted from https://github.com/com-lihaoyi/Ammonite/blob/2da846d2313f1e12e812802babf9c69005f5d44a/amm/interp/src/main/scala/ammonite/interp/script/SemanticdbProcessor.scala
22

3-
package scala.build.internal
3+
package scala.build.postprocessing
44

55
import java.math.BigInteger
66
import java.nio.charset.StandardCharsets
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package scala.build.postprocessing
2+
3+
import scala.build.{GeneratedSource, Logger}
4+
import scala.build.tastylib.TastyData
5+
6+
case object TastyPostProcessor extends PostProcessor {
7+
def postProcess(
8+
generatedSources: Seq[GeneratedSource],
9+
mappings: Map[String, (String, Int)],
10+
workspace: os.Path,
11+
output: os.Path,
12+
logger: Logger
13+
): Unit = {
14+
15+
val updatedPaths = generatedSources
16+
.flatMap { source =>
17+
source.reportingPath.toOption.toSeq.map { originalSource =>
18+
val fromSourceRoot = source.generated.relativeTo(workspace)
19+
val actual = originalSource.relativeTo(workspace)
20+
fromSourceRoot.toString -> actual.toString
21+
}
22+
}
23+
.toMap
24+
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+
}
52+
}
53+
}

0 commit comments

Comments
 (0)