@@ -13,9 +13,11 @@ import java.net.URI
13
13
import java .nio ._
14
14
import java .nio .file ._
15
15
import java .nio .file .attribute ._
16
+ import java .util .stream .{Stream , StreamSupport }
16
17
17
18
import scala .collection .immutable .IndexedSeq
18
19
import scala .collection .mutable
20
+ import scala .collection .JavaConverters ._
19
21
20
22
import sbt .{Logger , MessageOnlyException }
21
23
@@ -43,6 +45,8 @@ import sbt.{Logger, MessageOnlyException}
43
45
final class JavalibIRCleaner (baseDirectoryURI : URI ) {
44
46
import JavalibIRCleaner ._
45
47
48
+ type JSTypes = Map [ClassName , Option [JSNativeLoadSpec ]]
49
+
46
50
def cleanIR (dependencyFiles : Seq [File ], libFileMappings : Seq [(File , File )],
47
51
logger : Logger ): Set [File ] = {
48
52
@@ -55,14 +59,16 @@ final class JavalibIRCleaner(baseDirectoryURI: URI) {
55
59
}
56
60
57
61
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
+ }
63
69
}
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) )
66
72
}
67
73
68
74
val resultBuilder = Set .newBuilder[File ]
@@ -123,31 +129,21 @@ final class JavalibIRCleaner(baseDirectoryURI: URI) {
123
129
Serializers .deserialize(buffer)
124
130
}
125
131
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" )
137
136
}
138
137
139
138
// Open zip/jar file as filesystem.
140
139
// The type ascription is necessary on JDK 13+.
141
140
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.
151
147
}
152
148
153
149
private def writeIRFile (file : File , tree : ClassDef ): Unit = {
@@ -161,17 +157,19 @@ final class JavalibIRCleaner(baseDirectoryURI: URI) {
161
157
}
162
158
}
163
159
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
+ }
166
164
167
- private def cleanTree (tree : ClassDef , jsTypes : Map [ ClassName , ClassDef ] ,
165
+ private def cleanTree (tree : ClassDef , jsTypes : JSTypes ,
168
166
errorManager : ErrorManager ): ClassDef = {
169
167
new ClassDefCleaner (tree.className, jsTypes, errorManager)
170
168
.cleanClassDef(tree)
171
169
}
172
170
173
171
private final class ClassDefCleaner (enclosingClassName : ClassName ,
174
- jsTypes : Map [ ClassName , ClassDef ] , errorManager : ErrorManager )
172
+ jsTypes : JSTypes , errorManager : ErrorManager )
175
173
extends Transformers .ClassTransformer {
176
174
177
175
def cleanClassDef (tree : ClassDef ): ClassDef = {
@@ -500,16 +498,13 @@ final class JavalibIRCleaner(baseDirectoryURI: URI) {
500
498
private def genLoadFromLoadSpecOf (className : ClassName )(
501
499
implicit pos : Position ): Tree = {
502
500
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" )
513
508
case None =>
514
509
reportError(s " ${className.nameString} is not a JS type " )
515
510
JSGlobalRef (" Object" )
0 commit comments