Skip to content

Commit 7ca29b5

Browse files
committed
Use java.nio.file.FileSystems to write to jar directly
1 parent 68d383c commit 7ca29b5

File tree

2 files changed

+40
-22
lines changed

2 files changed

+40
-22
lines changed

compiler/src/dotty/tools/backend/jvm/GenBCode.scala

+39-21
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import dotty.tools.dotc.core.Phases.Phase
77
import dotty.tools.dotc.core.Names.TypeName
88

99
import scala.collection.mutable
10+
import scala.collection.JavaConverters._
1011
import scala.tools.asm.{ClassVisitor, CustomAttr, FieldVisitor, MethodVisitor}
1112
import scala.tools.nsc.backend.jvm._
1213
import dotty.tools.dotc
@@ -26,14 +27,15 @@ import Denotations._
2627
import Phases._
2728
import java.lang.AssertionError
2829
import java.io.{DataOutputStream, File => JFile}
29-
import dotty.tools.io.{Jar, File, Directory}
30+
import java.nio.file.{Files, FileSystem, FileSystems, Path => JPath}
31+
32+
import dotty.tools.io.{Directory, File, Jar}
3033

3134
import scala.tools.asm
3235
import scala.tools.asm.tree._
3336
import dotty.tools.dotc.util.{DotClass, Positions}
3437
import tpd._
3538
import StdNames._
36-
3739
import dotty.tools.io._
3840

3941
class GenBCode extends Phase {
@@ -50,37 +52,53 @@ class GenBCode extends Phase {
5052
def outputDir(implicit ctx: Context): AbstractFile = {
5153
val path = ctx.settings.outputDir.value
5254
if (path.isDirectory) new PlainDirectory(Directory(path))
53-
else new PlainFile(path)
55+
else jarOutput(path)
5456
}
5557

56-
private[this] var classOutput: AbstractFile = _
57-
5858
def run(implicit ctx: Context): Unit = {
5959
new GenBCodePipeline(entryPoints.toList,
60-
new DottyBackendInterface(classOutput, superCallsMap.toMap)(ctx))(ctx).run(ctx.compilationUnit.tpdTree)
60+
new DottyBackendInterface(outputDir, superCallsMap.toMap)(ctx))(ctx).run(ctx.compilationUnit.tpdTree)
6161
entryPoints.clear()
6262
}
6363

6464
override def runOn(units: List[CompilationUnit])(implicit ctx: Context) = {
65-
val output = outputDir
66-
if (output.isDirectory) {
67-
classOutput = output
68-
val res = super.runOn(units)
69-
classOutput = null
70-
res
71-
} else {
72-
assert(output.hasExtension("jar"))
73-
classOutput = new PlainDirectory(Path(Path(output.file).parent + "/tmp-jar-" + System.currentTimeMillis().toHexString).createDirectory())
74-
val res = super.runOn(units)
75-
Jar.create(new File(ctx.settings.outputDir.value.jfile), new Directory(classOutput.file), mainClass = "")
76-
classOutput.delete()
77-
classOutput = null
78-
res
65+
try super.runOn(units)
66+
finally if (jarFs ne null) {
67+
try { jarFs.close() } catch { case _: Throwable => }
68+
jarFs = null
69+
}
70+
}
71+
72+
private[this] var jarFs: java.nio.file.FileSystem = _
73+
private def jarOutput(path: Path) = {
74+
assert(path.extension == "jar")
75+
76+
path.delete()
77+
78+
val env = Map("create" -> "true").asJava
79+
val jar = java.net.URI.create("jar:file:" + path.toAbsolute.path)
80+
jarFs = java.nio.file.FileSystems.newFileSystem(jar, env)
81+
82+
new JarFilePath(jarFs, jarFs.getRootDirectories.iterator().next())
83+
}
84+
85+
private class JarFilePath(jarFs: FileSystem, path: JPath) extends PlainDirectory(new Directory(path)) {
86+
override def name = "<jar-file>"
87+
override def file = throw new UnsupportedOperationException
88+
override def fileNamed(name: String): AbstractFile = new PlainNioFile(pathTo(name))
89+
override def subdirectoryNamed(name: String): AbstractFile = {
90+
val subPath = pathTo(name)
91+
if (!Files.exists(subPath)) Files.createDirectory(subPath)
92+
new JarFilePath(jarFs, subPath)
93+
}
94+
private def pathTo(name: String) = {
95+
val absolutePath = if (path.toString == "/") name else path.resolve(name).toString
96+
jarFs.getPath(absolutePath)
7997
}
8098
}
8199
}
82100

83-
class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInterface)(implicit val ctx: Context) extends BCodeSyncAndTry{
101+
class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInterface)(implicit val ctx: Context) extends BCodeSyncAndTry {
84102

85103
var tree: Tree = _
86104

doc-tool/src/dotty/tools/dottydoc/staticsite/Site.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ case class Site(
409409
}
410410

411411
private def toSourceFile(f: JFile): SourceFile =
412-
SourceFile(AbstractFile.getFile(new File(f)), Source.fromFile(f).toArray)
412+
SourceFile(AbstractFile.getFile(new File(f.toPath)), Source.fromFile(f).toArray)
413413

414414
private def collectFiles(dir: JFile, includes: String => Boolean): Array[JFile] =
415415
dir

0 commit comments

Comments
 (0)