1212
1313package org .scalajs .jsenv .nodejs
1414
15- import java .nio .charset .StandardCharsets
1615
1716import scala .annotation .tailrec
18- import scala .collection .JavaConverters ._
17+
18+ import java .io ._
19+ import java .nio .charset .StandardCharsets
20+ import java .nio .file ._
1921
2022import org .scalajs .jsenv ._
2123import org .scalajs .jsenv .JSUtils .escapeJS
2224
23- import org .scalajs .io ._
2425import org .scalajs .logging ._
2526
26- import java . io . _
27+ import com . google . common . jimfs . Jimfs
2728
2829final class NodeJSEnv (config : NodeJSEnv .Config ) extends JSEnv {
2930 import NodeJSEnv ._
@@ -57,8 +58,7 @@ final class NodeJSEnv(config: NodeJSEnv.Config) extends JSEnv {
5758 }
5859 }
5960
60- private def internalStart (initFiles : List [VirtualBinaryFile ], input : Input ,
61- runConfig : RunConfig ): JSRun = {
61+ private def internalStart (initFiles : List [Path ], input : Input , runConfig : RunConfig ): JSRun = {
6262 val command = config.executable :: config.args
6363 val externalConfig = ExternalJSRun .Config ()
6464 .withEnv(env)
@@ -67,7 +67,7 @@ final class NodeJSEnv(config: NodeJSEnv.Config) extends JSEnv {
6767 NodeJSEnv .write(initFiles, input))
6868 }
6969
70- private def initFiles : List [VirtualBinaryFile ] = config.sourceMap match {
70+ private def initFiles : List [Path ] = config.sourceMap match {
7171 case SourceMap .Disable => Nil
7272 case SourceMap .EnableIfAvailable => installSourceMapIfAvailable :: Nil
7373 case SourceMap .Enable => installSourceMap :: Nil
@@ -83,43 +83,45 @@ final class NodeJSEnv(config: NodeJSEnv.Config) extends JSEnv {
8383}
8484
8585object NodeJSEnv {
86+ private lazy val fs = Jimfs .newFileSystem()
87+
8688 private lazy val validator = ExternalJSRun .supports(RunConfig .Validator ())
8789
8890 private lazy val installSourceMapIfAvailable = {
89- MemVirtualBinaryFile .fromStringUTF8(" sourceMapSupport.js" ,
91+ Files .write(
92+ fs.getPath(" optionalSourceMapSupport.js" ),
9093 """
9194 |try {
9295 | require('source-map-support').install();
9396 |} catch (e) {
9497 |};
95- """ .stripMargin
96- )
98+ """ .stripMargin.getBytes(StandardCharsets .UTF_8 ))
9799 }
98100
99101 private lazy val installSourceMap = {
100- MemVirtualBinaryFile .fromStringUTF8(" sourceMapSupport.js" ,
101- " require('source-map-support').install();" )
102+ Files .write(
103+ fs.getPath(" sourceMapSupport.js" ),
104+ " require('source-map-support').install();" .getBytes(StandardCharsets .UTF_8 ))
102105 }
103106
104- private def write (initFiles : List [VirtualBinaryFile ], input : Input )(
105- out : OutputStream ): Unit = {
107+ private def write (initFiles : List [Path ], input : Input )(out : OutputStream ): Unit = {
106108 val p = new PrintStream (out, false , " UTF8" )
107109 try {
108- def writeRunScript (file : VirtualBinaryFile ): Unit = {
109- file match {
110- case file : FileVirtualBinaryFile =>
111- val pathJS = " \" " + escapeJS(file.file .getAbsolutePath) + " \" "
112- p.println(s """
113- require('vm').runInThisContext(
114- require('fs').readFileSync( $pathJS, { encoding: "utf-8" }),
115- { filename: $pathJS, displayErrors: true }
116- );
117- """ )
118-
119- case _ =>
120- val code = readInputStreamToString(file.inputStream )
110+ def writeRunScript (path : Path ): Unit = {
111+ try {
112+ val f = path.toFile
113+ val pathJS = " \" " + escapeJS(f .getAbsolutePath) + " \" "
114+ p.println(s """
115+ require('vm').runInThisContext(
116+ require('fs').readFileSync( $pathJS, { encoding: "utf-8" }),
117+ { filename: $pathJS, displayErrors: true }
118+ );
119+ """ )
120+ } catch {
121+ case _ : UnsupportedOperationException =>
122+ val code = new String ( Files .readAllBytes(path), StandardCharsets . UTF_8 )
121123 val codeJS = " \" " + escapeJS(code) + " \" "
122- val pathJS = " \" " + escapeJS(file. path) + " \" "
124+ val pathJS = " \" " + escapeJS(path.toString ) + " \" "
123125 p.println(s """
124126 require('vm').runInThisContext(
125127 $codeJS,
@@ -129,17 +131,6 @@ object NodeJSEnv {
129131 }
130132 }
131133
132- def writeRequire (file : VirtualBinaryFile ): Unit = {
133- file match {
134- case file : FileVirtualBinaryFile =>
135- p.println(s """ require(" ${escapeJS(file.file.getAbsolutePath)}") """ )
136-
137- case _ =>
138- val f = tmpFile(file.path, file.inputStream)
139- p.println(s """ require(" ${escapeJS(f.getAbsolutePath)}") """ )
140- }
141- }
142-
143134 for (initFile <- initFiles)
144135 writeRunScript(initFile)
145136
@@ -150,16 +141,11 @@ object NodeJSEnv {
150141
151142 case Input .CommonJSModulesToLoad (modules) =>
152143 for (module <- modules)
153- writeRequire( module)
144+ p.println( s """ require(" ${escapeJS(toFile( module).getAbsolutePath)} ") """ )
154145
155146 case Input .ESModulesToLoad (modules) =>
156147 if (modules.nonEmpty) {
157- val uris = modules.map {
158- case module : FileVirtualBinaryFile =>
159- module.file.toURI
160- case module =>
161- tmpFile(module.path, module.inputStream).toURI
162- }
148+ val uris = modules.map(m => toFile(m).toURI)
163149
164150 val imports = uris.map { uri =>
165151 s """ import(" ${escapeJS(uri.toASCIIString)}") """
@@ -176,7 +162,8 @@ object NodeJSEnv {
176162 |});
177163 """ .stripMargin
178164 }
179- val f = tmpFile(" importer.js" , importerFileContent)
165+ val f = createTmpFile(" importer.js" )
166+ Files .write(f.toPath, importerFileContent.getBytes(StandardCharsets .UTF_8 ))
180167 p.println(s """ require(" ${escapeJS(f.getAbsolutePath)}"); """ )
181168 }
182169 }
@@ -185,48 +172,14 @@ object NodeJSEnv {
185172 }
186173 }
187174
188- private def readInputStreamToString (inputStream : InputStream ): String = {
189- val baos = new java.io.ByteArrayOutputStream
190- val in = inputStream
175+ private def toFile (path : Path ): File = {
191176 try {
192- val buf = new Array [Byte ](4096 )
193-
194- @ tailrec
195- def loop (): Unit = {
196- val read = in.read(buf)
197- if (read != - 1 ) {
198- baos.write(buf, 0 , read)
199- loop()
200- }
201- }
202-
203- loop()
204- } finally {
205- in.close()
206- }
207- new String (baos.toByteArray(), StandardCharsets .UTF_8 )
208- }
209-
210- private def tmpFile (path : String , content : String ): File = {
211- import java .nio .file .{Files , StandardOpenOption }
212-
213- val f = createTmpFile(path)
214- val contentList = new java.util.ArrayList [String ]()
215- contentList.add(content)
216- Files .write(f.toPath(), contentList, StandardCharsets .UTF_8 ,
217- StandardOpenOption .TRUNCATE_EXISTING )
218- f
219- }
220-
221- private def tmpFile (path : String , content : InputStream ): File = {
222- import java .nio .file .{Files , StandardCopyOption }
223-
224- try {
225- val f = createTmpFile(path)
226- Files .copy(content, f.toPath(), StandardCopyOption .REPLACE_EXISTING )
227- f
228- } finally {
229- content.close()
177+ path.toFile
178+ } catch {
179+ case _ : UnsupportedOperationException =>
180+ val f = createTmpFile(path.toString)
181+ Files .copy(path, f.toPath(), StandardCopyOption .REPLACE_EXISTING )
182+ f
230183 }
231184 }
232185
0 commit comments