8000 Support reading jar files in the IR cleaner. · scala-wasm/scala-wasm@d97f4e4 · GitHub
[go: up one dir, main page]

Skip to content

Commit d97f4e4

Browse files
committed
Support reading jar files in the IR cleaner.
That allows the IR cleaner to see the JS type definitions from the library when it appears as a jar on the classpath. This is the case for the linker private library. Adding that support will allow the linker private library to use JS type definitions from the Scala.js library, as long as the references can be erased away.
1 parent e33a212 commit d97f4e4

File tree

2 files changed

+53
-6
lines changed

2 files changed

+53
-6
lines changed

project/Build.scala

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -750,9 +750,21 @@ object Build {
750750
val libFileMappings = (PathFinder(prevProducts) ** "*.sjsir")
751751
.pair(Path.rebase(prevProducts, outputDir))
752752

753+
/* Note: we cannot use `linkerImpl` here to load `IRFile`s. That would
754+
* create the circular dependency
755+
* linkerPrivateLibrary/products
756+
* -> linkerImpl
757+
* -> linker/fullClasspath
758+
* -> linkerPrivateLibrary/products
759+
*/
753760
val dependencyFiles = {
754761
val cp = Attributed.data((internalDependencyClasspath in Compile).value)
755-
(PathFinder(cp) ** "*.sjsir").get
762+
cp.flatMap { entry =>
763+
if (entry.getName().endsWith(".jar"))
764+
Seq(entry)
765+
else
766+
(PathFinder(entry) ** "*.sjsir").get
767+
}
756768
}
757769

758770
FileFunction.cached(s.cacheDirectory / "cleaned-sjsir",

project/JavalibIRCleaner.scala

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import org.scalajs.ir.WellKnownNames._
1010

1111
import java.io._
1212
import java.net.URI
13-
import java.nio.file.Files
13+
import java.nio._
14+
import java.nio.file._
15+
import java.nio.file.attribute._
1416

1517
import scala.collection.immutable.IndexedSeq
1618
import scala.collection.mutable
@@ -53,7 +55,12 @@ final class JavalibIRCleaner(baseDirectoryURI: URI) {
5355
}
5456

5557
val jsTypes = {
56-
val dependencyIR = dependencyFiles.iterator.map(readIR(_))
58+
val dependencyIR = dependencyFiles.iterator.flatMap { file =>
59+
if (file.getName().endsWith(".jar"))
60+
readIRJar(file)
61+
else
62+
List(readIR(file))
63+
}
5764
val libIR = libIRMappings.iterator.map(_._1)
5865
getJSTypes(dependencyIR ++ libIR)
5966
}
@@ -107,14 +114,42 @@ final class JavalibIRCleaner(baseDirectoryURI: URI) {
107114
def errorCount: Int = _errorCount
108115
}
109116

110-
private def readIR(file: File): ClassDef = {
111-
import java.nio.ByteBuffer
117+
private def readIR(file: File): ClassDef =
118+
readIR(file.toPath())
112119

113-
val bytes = Files.readAllBytes(file.toPath())
120+
private def readIR(path: Path): ClassDef = {
121+
val bytes = Files.readAllBytes(path)
114122
val buffer = ByteBuffer.wrap(bytes)
115123
Serializers.deserialize(buffer)
116124
}
117125

126+
private def readIRJar(jar: File): List[ClassDef] = {
127+
// Similar to PathIRContainer.JarIRContainer and its walkIR helper
128+
129+
val classDefs = List.newBuilder[ClassDef]
130+
131+
val dirVisitor = new SimpleFileVisitor[Path] {
132+
override def visitFile(path: Path, attrs: BasicFileAttributes): FileVisitResult = {
133+
if (path.getFileName().toString().endsWith(".sjsir"))
134+
classDefs += readIR(path)
135+
super.visitFile(path, attrs)
136+
}
137+
}
138+
139+
// Open zip/jar file as filesystem.
140+
// The type ascription is necessary on JDK 13+.
141+
val fs = FileSystems.newFileSystem(jar.toPath(), null: ClassLoader)
142+
try {
143+
val iter = fs.getRootDirectories().iterator()
144+
while (iter.hasNext())
145+
Files.walkFileTree(iter.next(), dirVisitor)
146+
} finally {
147+
fs.close()
148+
}
149+
150+
classDefs.result()
151+
}
152+
118153
private def writeIRFile(file: File, tree: ClassDef): Unit = {
119154
Files.createDirectories(file.toPath().getParent())
120155
val outputStream =

0 commit comments

Comments
 (0)
0