10000 Merge pull request #5178 from gzm0/walk-stream · scala-wasm/scala-wasm@25d9a5f · GitHub
[go: up one dir, main page]

Skip to content

Commit 25d9a5f

Browse files
authored
Merge pull request scala-js#5178 from gzm0/walk-stream
Improvements to the IRCleaner
2 parents f73a8ae + 8a35205 commit 25d9a5f

File tree

1 file changed

+36
-41
lines changed

1 file changed

+36
-41
lines changed

project/JavalibIRCleaner.scala

Lines changed: 36 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,11 @@ import java.net.URI
1313
import java.nio._
1414
import java.nio.file._
1515
import java.nio.file.attribute._
16+
import java.util.stream.{Stream, StreamSupport}
1617

1718
import scala.collection.immutable.IndexedSeq
1819
import scala.collection.mutable
20+
import scala.collection.JavaConverters._
1921

2022
import sbt.{Logger, MessageOnlyException}
2123

@@ -43,6 +45,8 @@ import sbt.{Logger, MessageOnlyException}
4345
final class JavalibIRCleaner(baseDirectoryURI: URI) {
4446
import JavalibIRCleaner._
4547

48+
type JSTypes = Map[ClassName, Option[JSNativeLoadSpec]]
49+
4650
def cleanIR(dependencyFiles: Seq[File], libFileMappings: Seq[(File, File)],
4751
logger: Logger): Set[File] = {
4852

@@ -55,14 +59,16 @@ final class JavalibIRCleaner(baseDirectoryURI: URI) {
5559
}
5660

5761
val jsTypes = {
58-
val dependencyIR = dependencyFiles.iterator.flatMap { file =>
59-
if (file.getName().endsWith(".jar"))
60-
readIRJar(file)
61-
else
62-
List(readIR(file))
62+
val dependencyIR: Stream[ClassDef] = {
63+
dependencyFiles.asJava.stream().flatMap { file =>
64+
if (file.getName().endsWith(".jar"))
65+
readIRJar(file)
66+
else
67+
Stream.of[ClassDef](readIR(file))
68+
}
6369
}
64-
val libIR = libIRMappings.iterator.map(_._1)
65-
getJSTypes(dependencyIR ++ libIR)
70+
val libIR: Stream[ClassDef] = libIRMappings.asJava.stream().map(_._1)
71+
getJSTypes(Stream.concat(dependen 10000 cyIR, libIR))
6672
}
6773

6874
val resultBuilder = Set.newBuilder[File]
@@ -123,31 +129,21 @@ final class JavalibIRCleaner(baseDirectoryURI: URI) {
123129
Serializers.deserialize(buffer)
124130
}
125131

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-
}
132+
private def readIRJar(jar: File): Stream[ClassDef] = {
133+
def isIRFile(path: Path) = {
134+
val fn = path.getFileName() // null if path is FS root
135+
fn != null && fn.toString().endsWith(".sjsir")
137136
}
138137

139138
// Open zip/jar file as filesystem.
140139
// The type ascription is necessary on JDK 13+.
141140
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()
141+
StreamSupport
142+
.stream(fs.getRootDirectories().spliterator(), /* parallel= */ false)
143+
.flatMap(Files.walk(_))
144+
.filter(isIRFile(_))
145+
.map[ClassDef](readIR(_))
146+
.onClose(() => fs.close()) // only close fs once all IR is read.
151147
}
152148

153149
private def writeIRFile(file: File, tree: ClassDef): Unit = {
@@ -161,17 +157,19 @@ final class JavalibIRCleaner(baseDirectoryURI: URI) {
161157
}
162158
}
163159

164-
private def getJSTypes(trees: Iterator[ClassDef]): Map[ClassName, ClassDef] =
165-
trees.filter(_.kind.isJSType).map(t => t.className -> t).toMap
160+
private def getJSTypes(trees: Stream[ClassDef]): JSTypes = {
161+
trees.filter(_.kind.isJSType).reduce[JSTypes](
162+
Map.empty, (m, v) => m.updated(v.className, v.jsNativeLoadSpec), _ ++ _)
163+
}
166164

167-
private def cleanTree(tree: ClassDef, jsTypes: Map[ClassName, ClassDef],
165+
private def cleanTree(tree: ClassDef, jsTypes: JSTypes,
168166
errorManager: ErrorManager): ClassDef = {
169167
new ClassDefCleaner(tree.className, jsTypes, errorManager)
170168
.cleanClassDef(tree)
171169
}
172170

173171
private final class ClassDefCleaner(enclosingClassName: ClassName,
174-
jsTypes: Map[ClassName, ClassDef], errorManager: ErrorManager)
172+
jsTypes: JSTypes, errorManager: ErrorManager)
175173
extends Transformers.ClassTransformer {
176174

177175
def cleanClassDef(tree: ClassDef): ClassDef = {
@@ -500,16 +498,13 @@ final class JavalibIRCleaner(baseDirectoryURI: URI) {
500498
private def genLoadFromLoadSpecOf(className: ClassName)(
501499
implicit pos: Position): Tree = {
502500
jsTypes.get(className) match {
503-
case Some(classDef) =>
504-
classDef.jsNativeLoadSpec match {
505-
case Some(loadSpec) =>
506-
genLoadFromLoadSpec(loadSpec)
507-
case None =>
508-
reportError(
509-
s"${className.nameString} does not have a load spec " +
510-
"(this shouldn't have happened at all; bug in the compiler?)")
511-
JSGlobalRef("Object")
512-
}
501+
case Some(Some(loadSpec)) =>
502+
genLoadFromLoadSpec(loadSpec)
503+
case Some(None) =>
504+
reportError(
505+
s"${className.nameString} does not have a load spec " +
506+
"(this shouldn't have happened at all; bug in the compiler?)")
507+
JSGlobalRef("Object")
513508
case None =>
514509
reportError(s"${className.nameString} is not a JS type")
515510
JSGlobalRef("Object")

0 commit comments

Comments
 (0)
0