Skip to content

Commit 6d7f782

Browse files
committed
Fix notify Zinc about class file in jar
1 parent c1b25d6 commit 6d7f782

File tree

2 files changed

+21
-16
lines changed

2 files changed

+21
-16
lines changed

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

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package dotty.tools.backend.jvm
22

3-
import java.io.{DataOutputStream, IOException, BufferedOutputStream, FileOutputStream}
3+
import java.io.{DataOutputStream, File, IOException, BufferedOutputStream, FileOutputStream}
44
import java.nio.ByteBuffer
55
import java.nio.channels.{ClosedByInterruptException, FileChannel}
66
import java.nio.charset.StandardCharsets.UTF_8
@@ -12,7 +12,7 @@ import java.util.zip.{CRC32, Deflater, ZipEntry, ZipOutputStream}
1212

1313
import dotty.tools.dotc.core.Contexts.*
1414
import dotty.tools.dotc.core.Decorators.em
15-
import dotty.tools.io.{AbstractFile, PlainFile}
15+
import dotty.tools.io.{AbstractFile, PlainFile, VirtualFile}
1616
import dotty.tools.io.PlainFile.toPlainFile
1717
import BTypes.InternalName
1818
import scala.util.chaining.*
@@ -26,7 +26,6 @@ import scala.language.unsafeNulls
2626
* Until then, any changes to this file should be copied to `dotty.tools.io.FileWriters` as well.
2727
*/
2828
class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
29-
type NullableFile = AbstractFile | Null
3029
import frontendAccess.{compilerSettings, backendReporting}
3130

3231
sealed trait TastyWriter {
@@ -46,7 +45,7 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
4645
/**
4746
* Write a classfile
4847
*/
49-
def writeClass(name: InternalName, bytes: Array[Byte], sourceFile: AbstractFile): NullableFile
48+
def writeClass(name: InternalName, bytes: Array[Byte], sourceFile: AbstractFile): AbstractFile
5049

5150

5251
/**
@@ -91,7 +90,7 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
9190
}
9291

9392
private final class SingleClassWriter(underlying: FileWriter) extends ClassfileWriter {
94-
override def writeClass(className: InternalName, bytes: Array[Byte], sourceFile: AbstractFile): NullableFile = {
93+
override def writeClass(className: InternalName, bytes: Array[Byte], sourceFile: AbstractFile): AbstractFile = {
9594
underlying.writeFile(classRelativePath(className), bytes)
9695
}
9796
override def writeTasty(className: InternalName, bytes: Array[Byte], sourceFile: AbstractFile): Unit = {
@@ -103,7 +102,7 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
103102
}
104103

105104
private final class DebugClassWriter(basic: ClassfileWriter, dump: FileWriter) extends ClassfileWriter {
106-
override def writeClass(className: InternalName, bytes: Array[Byte], sourceFile: AbstractFile): NullableFile = {
105+
override def writeClass(className: InternalName, bytes: Array[Byte], sourceFile: AbstractFile): AbstractFile = {
107106
val outFile = basic.writeClass(className, bytes, sourceFile)
108107
dump.writeFile(classRelativePath(className), bytes)
109108
outFile
@@ -121,7 +120,7 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
121120
}
122121

123122
sealed trait FileWriter {
124-
def writeFile(relativePath: String, bytes: Array[Byte]): NullableFile
123+
def writeFile(relativePath: String, bytes: Array[Byte]): AbstractFile
125124
def close(): Unit
126125
}
127126

@@ -165,7 +164,7 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
165164

166165
lazy val crc = new CRC32
167166

168-
override def writeFile(relativePath: String, bytes: Array[Byte]): NullableFile = this.synchronized {
167+
override def writeFile(relativePath: String, bytes: Array[Byte]): AbstractFile = this.synchronized {
169168
val entry = new ZipEntry(relativePath)
170169
if (storeOnly) {
171170
// When using compression method `STORED`, the ZIP spec requires the CRC and compressed/
@@ -182,7 +181,13 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
182181
jarWriter.putNextEntry(entry)
183182
try jarWriter.write(bytes, 0, bytes.length)
184183
finally jarWriter.flush()
185-
null
184+
// important detail here, even on Windows, Zinc expects the separator within the jar
185+
// to be the system default, (even if in the actual jar file the entry always uses '/').
186+
// see https://github.com/sbt/zinc/blob/dcddc1f9cfe542d738582c43f4840e17c053ce81/internal/compiler-bridge/src/main/scala/xsbt/JarUtils.scala#L47
187+
val pathInJar =
188+
if File.separatorChar == '/' then relativePath
189+
else relativePath.replace('/', File.separatorChar)
190+
PlainFile.toPlainFile(Paths.get(s"${file.absolutePath}!$pathInJar"))
186191
}
187192

188193
override def close(): Unit = this.synchronized(jarWriter.close())
@@ -230,7 +235,7 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
230235
private val fastOpenOptions = util.EnumSet.of(StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)
231236
private val fallbackOpenOptions = util.EnumSet.of(StandardOpenOption.CREATE, StandardOpenOption.WRITE, StandardOpenOption.TRUNCATE_EXISTING)
232237

233-
override def writeFile(relativePath: String, bytes: Array[Byte]): NullableFile = {
238+
override def writeFile(relativePath: String, bytes: Array[Byte]): AbstractFile = {
234239
val path = base.resolve(relativePath)
235240
try {
236241
ensureDirForPath(base, path)
@@ -279,7 +284,7 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
279284
finally out.close()
280285
}
281286

282-
override def writeFile(relativePath: String, bytes: Array[Byte]):NullableFile = {
287+
override def writeFile(relativePath: String, bytes: Array[Byte]): AbstractFile = {
283288
val outFile = getFile(base, relativePath)
284289
writeBytes(outFile, bytes)
285290
outFile

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

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,11 +44,11 @@ class PostProcessor(val frontendAccess: PostProcessorFrontendAccess, val bTypes:
4444
backendReporting.error(em"Error while emitting $internalName\n${ex.getMessage}")
4545
null
4646

47-
if bytes != null then
48-
if (AsmUtils.traceSerializedClassEnabled && internalName.contains(AsmUtils.traceSerializedClassPattern))
49-
AsmUtils.traceClass(bytes)
50-
val clsFile = classfileWriter.writeClass(internalName, bytes, sourceFile)
51-
if clsFile != null then clazz.onFileCreated(clsFile)
47+
if bytes != null then
48+
if AsmUtils.traceSerializedClassEnabled && internalName.contains(AsmUtils.traceSerializedClassPattern) then
49+
AsmUtils.traceClass(bytes)
50+
val clsFile = classfileWriter.writeClass(internalName, bytes, sourceFile)
51+
clazz.onFileCreated(clsFile)
5252
}
5353

5454
def sendToDisk(tasty: GeneratedTasty, sourceFile: AbstractFile): Unit = {

0 commit comments

Comments
 (0)