1
1
package dotty .tools .backend .jvm
2
2
3
- import java .io .{DataOutputStream , IOException , BufferedOutputStream , FileOutputStream }
3
+ import java .io .{DataOutputStream , File , IOException , BufferedOutputStream , FileOutputStream }
4
4
import java .nio .ByteBuffer
5
5
import java .nio .channels .{ClosedByInterruptException , FileChannel }
6
6
import java .nio .charset .StandardCharsets .UTF_8
@@ -12,7 +12,7 @@ import java.util.zip.{CRC32, Deflater, ZipEntry, ZipOutputStream}
12
12
13
13
import dotty .tools .dotc .core .Contexts .*
14
14
import dotty .tools .dotc .core .Decorators .em
15
- import dotty .tools .io .{AbstractFile , PlainFile }
15
+ import dotty .tools .io .{AbstractFile , PlainFile , VirtualFile }
16
16
import dotty .tools .io .PlainFile .toPlainFile
17
17
import BTypes .InternalName
18
18
import scala .util .chaining .*
@@ -26,7 +26,6 @@ import scala.language.unsafeNulls
26
26
* Until then, any changes to this file should be copied to `dotty.tools.io.FileWriters` as well.
27
27
*/
28
28
class ClassfileWriters (frontendAccess : PostProcessorFrontendAccess ) {
29
- type NullableFile = AbstractFile | Null
30
29
import frontendAccess .{compilerSettings , backendReporting }
31
30
32
31
sealed trait TastyWriter {
@@ -46,7 +45,7 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
46
45
/**
47
46
* Write a classfile
48
47
*/
49
- def writeClass (name : InternalName , bytes : Array [Byte ], sourceFile : AbstractFile ): NullableFile
48
+ def writeClass (name : InternalName , bytes : Array [Byte ], sourceFile : AbstractFile ): AbstractFile
50
49
51
50
52
51
/**
@@ -91,7 +90,7 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
91
90
}
92
91
93
92
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 = {
95
94
underlying.writeFile(classRelativePath(className), bytes)
96
95
}
97
96
override def writeTasty (className : InternalName , bytes : Array [Byte ], sourceFile : AbstractFile ): Unit = {
@@ -103,7 +102,7 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
103
102
}
104
103
105
104
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 = {
107
106
val outFile = basic.writeClass(className, bytes, sourceFile)
108
107
dump.writeFile(classRelativePath(className), bytes)
109
108
outFile
@@ -121,7 +120,7 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
121
120
}
122
121
123
122
sealed trait FileWriter {
124
- def writeFile (relativePath : String , bytes : Array [Byte ]): NullableFile
123
+ def writeFile (relativePath : String , bytes : Array [Byte ]): AbstractFile
125
124
def close (): Unit
126
125
}
127
126
@@ -165,7 +164,7 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
165
164
166
165
lazy val crc = new CRC32
167
166
168
- override def writeFile (relativePath : String , bytes : Array [Byte ]): NullableFile = this .synchronized {
167
+ override def writeFile (relativePath : String , bytes : Array [Byte ]): AbstractFile = this .synchronized {
169
168
val entry = new ZipEntry (relativePath)
170
169
if (storeOnly) {
171
170
// When using compression method `STORED`, the ZIP spec requires the CRC and compressed/
@@ -182,7 +181,13 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
182
181
jarWriter.putNextEntry(entry)
183
182
try jarWriter.write(bytes, 0 , bytes.length)
184
183
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" ))
186
191
}
187
192
188
193
override def close (): Unit = this .synchronized (jarWriter.close())
@@ -230,7 +235,7 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
230
235
private val fastOpenOptions = util.EnumSet .of(StandardOpenOption .CREATE_NEW , StandardOpenOption .WRITE )
231
236
private val fallbackOpenOptions = util.EnumSet .of(StandardOpenOption .CREATE , StandardOpenOption .WRITE , StandardOpenOption .TRUNCATE_EXISTING )
232
237
233
- override def writeFile (relativePath : String , bytes : Array [Byte ]): NullableFile = {
238
+ override def writeFile (relativePath : String , bytes : Array [Byte ]): AbstractFile = {
234
239
val path = base.resolve(relativePath)
235
240
try {
236
241
ensureDirForPath(base, path)
@@ -279,7 +284,7 @@ class ClassfileWriters(frontendAccess: PostProcessorFrontendAccess) {
279
284
finally out.close()
280
285
}
281
286
282
- override def writeFile (relativePath : String , bytes : Array [Byte ]): NullableFile = {
287
+ override def writeFile (relativePath : String , bytes : Array [Byte ]): AbstractFile = {
283
288
val outFile = getFile(base, relativePath)
284
289
writeBytes(outFile, bytes)
285
290
outFile
0 commit comments