Skip to content

Commit d8d1840

Browse files
Merge pull request #3550 from dotty-staging/fix-loading-tasty-file-in-jar
Fix #3549: Load .tasty from jar if necessary
2 parents c352fde + 4774922 commit d8d1840

File tree

3 files changed

+42
-10
lines changed

3 files changed

+42
-10
lines changed

compiler/src/dotty/tools/dotc/core/classfile/ClassfileParser.scala

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,13 @@ import SymDenotations._, unpickleScala2.Scala2Unpickler._, Constants._, Annotati
88
import NameKinds.{ModuleClassName, DefaultGetterName}
99
import ast.tpd._
1010
import java.io.{ ByteArrayInputStream, DataInputStream, File, IOException }
11+
import java.nio
1112
import java.lang.Integer.toHexString
1213
import scala.collection.{ mutable, immutable }
1314
import scala.collection.mutable.{ ListBuffer, ArrayBuffer }
1415
import scala.annotation.switch
1516
import typer.Checking.checkNonCyclic
16-
import io.{AbstractFile, PlainFile}
17+
import io.{AbstractFile, PlainFile, Path, ZipArchive, JarArchive}
1718
import scala.util.control.NonFatal
1819

1920
object ClassfileParser {
@@ -781,11 +782,28 @@ class ClassfileParser(
781782

782783
if (scan(tpnme.TASTYATTR)) {
783784
val attrLen = in.nextInt
784-
if (attrLen == 0) {
785-
// A tasty attribute implies the existence of the .tasty file
786-
val file = new PlainFile(io.File(classfile.jpath).changeExtension("tasty"))
787-
if (file.exists) return unpickleTASTY(new AbstractFileReader(file).nextBytes(file.sizeOption.get))
788-
else ctx.error("Could not find " + file)
785+
if (attrLen == 0) { // A tasty attribute implies the existence of the .tasty file
786+
def readTastyForClass(jpath: nio.file.Path): Array[Byte] = {
787+
val plainFile = new PlainFile(io.File(jpath).changeExtension("tasty"))
788+
if (plainFile.exists) plainFile.toByteArray
789+
else {
790+
ctx.error("Could not find " + plainFile)
791+
Array.empty
792+
}
793+
}
794+
val tastyBytes = classfile.underlyingSource match { // TODO: simplify when #3552 is fixed
795+
case None =>
796+
ctx.error("Could not load TASTY from .tasty for virtual file " + classfile)
797+
Array.empty[Byte]
798+
case Some(jar: ZipArchive) => // We are in a jar
799+
val jarFile = JarArchive.open(io.File(jar.jpath))
800+
try readTastyForClass(jarFile.jpath.resolve(classfile.path))
801+
finally jarFile.close()
802+
case _ =>
803+
readTastyForClass(classfile.jpath)
804+
}
805+
if (tastyBytes.nonEmpty)
806+
return unpickleTASTY(tastyBytes)
789807
}
790808
else return unpickleTASTY(in.nextBytes(attrLen))
791809
}

compiler/src/dotty/tools/io/JarArchive.scala

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,17 @@ object JarArchive {
1616
/** Create a new jar file. Overwrite if file already exists */
1717
def create(path: Path): JarArchive = {
1818
require(path.extension == "jar")
19-
2019
path.delete()
20+
open(path, create = true)
21+
}
22+
23+
/** Create a jar file. */
24+
def open(path: Path, create: Boolean = false): JarArchive = {
25+
require(path.extension == "jar")
2126

2227
// creating a new zip file system by using the JAR URL syntax:
2328
// https://docs.oracle.com/javase/7/docs/technotes/guides/io/fsp/zipfilesystemprovider.html
24-
val env = Map("create" -> "true").asJava
29+
val env = Map("create" -> create.toString).asJava
2530
val uri = java.net.URI.create("jar:file:" + path.toAbsolute.path)
2631
val fs = FileSystems.newFileSystem(uri, env)
2732

project/scripts/sbtTests

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ fi
3030

3131
# check that `sbt dotc -decompile` runs
3232
echo "testing sbt dotc -decompile"
33-
./project/scripts/sbt ";dotc -decompile -code -color:never -classpath out/scriptedtest1 dotrtest.Test" > sbtdotc3.out
33+
./project/scripts/sbt ";dotc -decompile -color:never -classpath out/scriptedtest1 dotrtest.Test" > sbtdotc3.out
3434
cat sbtdotc3.out
3535
if grep -e "def main(args: Array\[String\]): Unit =" sbtdotc3.out; then
3636
echo "output ok"
@@ -39,11 +39,20 @@ else
3939
exit -1
4040
fi
4141
echo "testing sbt dotr with no -classpath"
42-
4342
./project/scripts/sbt ";dotc tests/pos/sbtDotrTest.scala; dotr dotrtest.Test" > sbtdotr3.out
4443
cat sbtdotr3.out
4544
if grep -e "dotr test ok" sbtdotr3.out; then
4645
echo "output ok"
4746
else
4847
exit -1
4948
fi
49+
50+
echo "testing loading tasty from .tasty file in jar"
51+
./project/scripts/sbt ";dotc -d out/scriptedtest4.jar -YemitTasty tests/pos/sbtDotrTest.scala; dotc -decompile -classpath out/scriptedtest4.jar -color:never dotrtest.Test" > sbtdot4.out
52+
cat sbtdot4.out
53+
if grep -e "def main(args: Array\[String\]): Unit =" sbtdot4.out; then
54+
echo "output ok"
55+
else
56+
echo "failed output check"
57+
exit -1
58+
fi

0 commit comments

Comments
 (0)