Skip to content

Commit 1314b45

Browse files
authored
Merge pull request scala#8175 from retronym/topic/write-sig-file
Add a compiler option to write .sig files to disk
2 parents 627a110 + 3ee75e0 commit 1314b45

File tree

7 files changed

+214
-243
lines changed

7 files changed

+214
-243
lines changed

src/compiler/scala/tools/nsc/PipelineMain.scala

+9-58
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import java.lang.Thread.UncaughtExceptionHandler
1717
import java.nio.file.attribute.FileTime
1818
import java.nio.file.{Files, Path, Paths}
1919
import java.time.Instant
20+
import java.util.concurrent.ConcurrentHashMap
2021
import java.util.{Collections, Locale}
2122
import java.util.concurrent.atomic.{AtomicBoolean, AtomicInteger}
2223

@@ -44,10 +45,13 @@ class PipelineMainClass(argFiles: Seq[Path], pipelineSettings: PipelineMain.Pipe
4445
val root = file.getRoot
4546
// An empty component on Unix, just the drive letter on Windows
4647
val validRootPathComponent = root.toString.replaceAllLiterally("/", "").replaceAllLiterally(":", "")
47-
changeExtension(pickleCache.resolve(validRootPathComponent).resolve(root.relativize(file)).normalize(), newExtension)
48+
val result = changeExtension(pickleCache.resolve(validRootPathComponent).resolve(root.relativize(file)).normalize(), newExtension)
49+
if (useJars) Files.createDirectories(result.getParent)
50+
strippedAndExportedClassPath.put(file.toRealPath().normalize(), result)
51+
result
4852
}
4953

50-
private val strippedAndExportedClassPath = mutable.HashMap[Path, Path]()
54+
private val strippedAndExportedClassPath = new ConcurrentHashMap[Path, Path]().asScala
5155

5256
/** Forward errors to the (current) reporter. */
5357
protected def scalacError(msg: String): Unit = {
@@ -73,51 +77,6 @@ class PipelineMainClass(argFiles: Seq[Path], pipelineSettings: PipelineMain.Pipe
7377
p.getParent.resolve(changedFileName)
7478
}
7579

76-
def registerPickleClassPath[G <: Global](output: Path, data: mutable.AnyRefMap[G#Symbol, PickleBuffer]): Unit = {
77-
val jarPath = cachePath(output)
78-
val root = RootPath(jarPath, writable = true)
79-
Files.createDirectories(root.root)
80-
81-
val dirs = mutable.Map[G#Symbol, Path]()
82-
def packageDir(packSymbol: G#Symbol): Path = {
83-
if (packSymbol.isEmptyPackageClass) root.root
84-
else if (dirs.contains(packSymbol)) dirs(packSymbol)
85-
else if (packSymbol.owner.isRoot) {
86-
val subDir = root.root.resolve(packSymbol.encodedName)
87-
Files.createDirectories(subDir)
88-
dirs.put(packSymbol, subDir)
89-
subDir
90-
} else {
91-
val base = packageDir(packSymbol.owner)
92-
val subDir = base.resolve(packSymbol.encodedName)
93-
Files.createDirectories(subDir)
94-
dirs.put(packSymbol, subDir)
95-
subDir
96-
}
97-
}
98-
val written = new java.util.IdentityHashMap[AnyRef, Unit]()
99-
try {
100-
for ((symbol, pickle) <- data) {
101-
if (!written.containsKey(pickle)) {
102-
val base = packageDir(symbol.owner)
103-
val primary = base.resolve(symbol.encodedName + ".sig")
104-
val writer = new BufferedOutputStream(Files.newOutputStream(primary))
105-
try {
106-
writer.write(pickle.bytes, 0, pickle.writeIndex)
107-
} finally {
108-
writer.close()
109-
}
110-
written.put(pickle, ())
111-
}
112-
}
113-
} finally {
114-
root.close()
115-
}
116-
Files.setLastModifiedTime(jarPath, FileTime.from(Instant.now()))
117-
strippedAndExportedClassPath.put(output.toRealPath().normalize(), jarPath)
118-
}
119-
120-
12180
def writeDotFile(logDir: Path, dependsOn: mutable.LinkedHashMap[Task, List[Dependency]]): Unit = {
12281
val builder = new java.lang.StringBuilder()
12382
builder.append("digraph projects {\n")
@@ -375,7 +334,6 @@ class PipelineMainClass(argFiles: Seq[Path], pipelineSettings: PipelineMain.Pipe
375334
if (p.outlineTimer.durationMicros > 0d) {
376335
val desc = if (strategy == OutlineTypePipeline) "outline-type" else "parser-to-pickler"
377336
events += durationEvent(p.label, desc, p.outlineTimer)
378-
events += durationEvent(p.label, "pickle-export", p.pickleExportTimer)
379337
}
380338
for ((g, ix) <- p.groups.zipWithIndex) {
381339
if (g.timer.durationMicros > 0d)
@@ -453,7 +411,6 @@ class PipelineMainClass(argFiles: Seq[Path], pipelineSettings: PipelineMain.Pipe
453411
val isGrouped = groups.size > 1
454412

455413
val outlineTimer = new Timer()
456-
val pickleExportTimer = new Timer
457414
val javaTimer = new Timer()
458415

459416
var outlineCriticalPathMs = 0d
@@ -491,14 +448,11 @@ class PipelineMainClass(argFiles: Seq[Path], pipelineSettings: PipelineMain.Pipe
491448
command.settings.Youtline.value = true
492449
command.settings.stopAfter.value = List("pickler")
493450
command.settings.Ymacroexpand.value = command.settings.MacroExpand.None
451+
command.settings.YpickleWrite.value = cachePath(command.settings.outputDirs.getSingleOutput.get.file.toPath).toAbsolutePath.toString
494452
val run1 = new compiler.Run()
495453
run1 compile files
496454
outlineTimer.stop()
497455
log(f"scalac outline: done ${outlineTimer.durationMs}%.0f ms")
498-
pickleExportTimer.start()
499-
registerPickleClassPath(command.settings.outputDirs.getSingleOutput.get.file.toPath, run1.symData)
500-
pickleExportTimer.stop()
501-
log(f"scalac: exported pickles ${pickleExportTimer.durationMs}%.0f ms")
502456
reporter.finish()
503457
if (reporter.hasErrors) {
504458
log("scalac outline: failed")
@@ -518,6 +472,7 @@ class PipelineMainClass(argFiles: Seq[Path], pipelineSettings: PipelineMain.Pipe
518472
command.settings.Youtline.value = false
519473
command.settings.stopAfter.value = Nil
520474
command.settings.Ymacroexpand.value = command.settings.MacroExpand.Normal
475+
command.settings.YpickleWrite.value = ""
521476

522477
val groupCount = groups.size
523478
for ((group, ix) <- groups.zipWithIndex) {
@@ -552,18 +507,14 @@ class PipelineMainClass(argFiles: Seq[Path], pipelineSettings: PipelineMain.Pipe
552507
assert(groups.size == 1)
553508
val group = groups.head
554509
log("scalac: start")
510+
command.settings.YpickleWrite.value = cachePath(command.settings.outputDirs.getSingleOutput.get.file.toPath).toString
555511
outlineTimer.start()
556512
try {
557513
val run2 = new compiler.Run() {
558-
559514
override def advancePhase(): Unit = {
560515
if (compiler.phase == this.picklerPhase) {
561516
outlineTimer.stop()
562517
log(f"scalac outline: done ${outlineTimer.durationMs}%.0f ms")
563-
pickleExportTimer.start()
564-
registerPickleClassPath(command.settings.outputDirs.getSingleOutput.get.file.toPath, symData)
565-
pickleExportTimer.stop()
566-
log(f"scalac: exported pickles ${pickleExportTimer.durationMs}%.0f ms")
567518
outlineDone.complete(Success(()))
568519
group.timer.start()
569520
}

0 commit comments

Comments
 (0)