@@ -85,28 +85,39 @@ class ScalaJSClosureOptimizer {
85
85
}
86
86
87
87
logTime(logger, " Closure: Write result" ) {
88
- writeResult(result, compiler, cfg.output )
88
+ writeResult(result, compiler, cfg)
89
89
}
90
90
}
91
91
92
92
private def writeResult (result : Result , compiler : ClosureCompiler ,
93
- output : WritableVirtualJSFile ): Unit = {
93
+ cfg : Config ): Unit = {
94
+ val output = cfg.output
94
95
95
- val outputContent = if (result.errors.nonEmpty) " "
96
- else " (function(){'use strict';" + compiler.toSource + " }).call(this);\n "
96
+ def withNewLine (str : String ): String = if (str == " " ) " " else str + " \n "
97
+
98
+ val (header0, footer0) = cfg.customOutputWrapper
99
+ val header = withNewLine(header0) + " (function(){'use strict';\n "
100
+ val footer = " }).call(this);\n " + withNewLine(footer0)
101
+
102
+ val outputContent =
103
+ if (result.errors.nonEmpty) " // errors while producing source\n "
104
+ else compiler.toSource + " \n "
97
105
98
106
val sourceMap = Option (compiler.getSourceMap())
99
107
100
108
// Write optimized code
101
109
val w = output.contentWriter
102
110
try {
111
+ w.write(header)
103
112
w.write(outputContent)
113
+ w.write(footer)
104
114
if (sourceMap.isDefined)
105
115
w.write(" //# sourceMappingURL=" + output.name + " .map\n " )
106
116
} finally w.close()
107
117
108
118
// Write source map (if available)
109
119
sourceMap.foreach { sm =>
120
+ sm.setWrapperPrefix(header)
110
121
val w = output.sourceMapWriter
111
122
try sm.appendTo(w, output.name)
112
123
finally w.close()
@@ -151,34 +162,225 @@ object ScalaJSClosureOptimizer {
151
162
}
152
163
153
164
/** Configuration for the output of the Scala.js Closure optimizer */
154
- final case class Config (
165
+ final class Config private [ Config ] (
155
166
/** Writer for the output */
156
- output : WritableVirtualJSFile ,
167
+ val output : WritableVirtualJSFile ,
157
168
/** Cache file */
158
- cache : Option [WritableVirtualTextFile ] = None ,
169
+ val cache : Option [WritableVirtualTextFile ],
159
170
/** Whether to only warn if the linker has errors. Implicitly true, if
160
- * noWarnMissing is nonEmpty
161
- */
162
- bypassLinkingErrors : Boolean = false ,
171
+ * noWarnMissing is nonEmpty */
172
+ val bypassLinkingErrors : Boolean ,
163
173
/** If true, performs expensive checks of the IR for the used parts. */
164
- checkIR : Boolean = false ,
174
+ val checkIR : Boolean ,
165
175
/** If true, the optimizer removes trees that have not been used in the
166
176
* last run from the cache. Otherwise, all trees that has been used once,
167
177
* are kept in memory. */
168
- unCache : Boolean = true ,
178
+ val unCache : Boolean ,
169
179
/** If true, no optimizations are performed */
170
- disableOptimizer : Boolean = false ,
180
+ val disableOptimizer : Boolean ,
171
181
/** If true, nothing is performed incrementally */
172
- batchMode : Boolean = false ,
182
+ val batchMode : Boolean ,
173
183
/** Ask to produce source map for the output */
174
- wantSourceMap : Boolean = false ,
184
+ val wantSourceMap : Boolean ,
175
185
/** Pretty-print the output. */
176
- prettyPrint : Boolean = false ,
186
+ val prettyPrint : Boolean ,
177
187
/** Base path to relativize paths in the source map */
178
- relativizeSourceMapBase : Option [URI ] = None ,
188
+ val relativizeSourceMapBase : Option [URI ],
179
189
/** Elements we won't warn even if they don't exist */
180
- noWarnMissing : Seq [ScalaJSOptimizer .NoWarnMissing ] = Nil
190
+ val noWarnMissing : Seq [ScalaJSOptimizer .NoWarnMissing ],
191
+ /** Custom js code that wraps the output */
192
+ val customOutputWrapper : (String , String )
181
193
) extends OptimizerConfig with ScalaJSOptimizer .OptimizerConfig
194
+ /* for binary compatibility */ with Product with Serializable with Equals {
195
+
196
+ /* NOTE: This class was previously a case class and hence many useless
197
+ * methods were implemented for binary compatibility :(
198
+ */
199
+
200
+ // For binary compatibility
201
+ @ deprecated(" Use Config(output) and .withXYZ() methods" , " 0.6.5" )
202
+ def this (
203
+ output : WritableVirtualJSFile ,
204
+ cache : Option [WritableVirtualTextFile ] = None ,
205
+ bypassLinkingErrors : Boolean = false ,
206
+ checkIR : Boolean = false ,
207
+ unCache : Boolean = true ,
208
+ disableOptimizer : Boolean = false ,
209
+ batchMode : Boolean = false ,
210
+ wantSourceMap : Boolean = false ,
211
+ prettyPrint : Boolean = false ,
212
+ relativizeSourceMapBase : Option [URI ] = None ,
213
+ noWarnMissing : Seq [ScalaJSOptimizer .NoWarnMissing ] = Nil ) = {
214
+
215
+ this (
216
+ output = output,
217
+ cache = cache,
218
+ bypassLinkingErrors = bypassLinkingErrors,
219
+ checkIR = checkIR,
220
+ unCache = unCache,
221
+ disableOptimizer = disableOptimizer,
222
+ batchMode = batchMode,
223
+ wantSourceMap = wantSourceMap,
224
+ prettyPrint = prettyPrint,
225
+ relativizeSourceMapBase = relativizeSourceMapBase,
226
+ noWarnMissing = noWarnMissing,
227
+ customOutputWrapper = (" " , " " ))
228
+ }
229
+
230
+ def withCache (cache : Option [WritableVirtualTextFile ]): Config =
231
+ copyWith(cache = cache)
232
+
233
+ def withBypassLinkingErrors (bypassLinkingErrors : Boolean ): Config =
234
+ copyWith(bypassLinkingErrors = bypassLinkingErrors)
235
+
236
+ def withCheckIR (checkIR : Boolean ): Config =
237
+ copyWith(checkIR = checkIR)
238
+
239
+ def withUnCache (unCache : Boolean ): Config =
240
+ copyWith(unCache = unCache)
241
+
242
+ def withDisableOptimizer (disableOptimizer : Boolean ): Config =
243
+ copyWith(disableOptimizer = disableOptimizer)
244
+
245
+ def withBatchMode (batchMode : Boolean ): Config =
246
+ copyWith(batchMode = batchMode)
247
+
248
+ def withWantSourceMap (wantSourceMap : Boolean ): Config =
249
+ copyWith(wantSourceMap = wantSourceMap)
250
+
251
+ def withPrettyPrint (prettyPrint : Boolean ): Config =
252
+ copyWith(prettyPrint = prettyPrint)
253
+
254
+ def withRelativizeSourceMapBase (relativizeSourceMapBase : Option [URI ]): Config =
255
+ copyWith(relativizeSourceMapBase = relativizeSourceMapBase)
256
+
257
+ def withNoWarnMissing (noWarnMissing : Seq [ScalaJSOptimizer .NoWarnMissing ]): Config =
258
+ copyWith(noWarnMissing = noWarnMissing)
259
+
260
+ def withCustomOutputWrapper (customOutputWrapper : (String , String )): Config =
261
+ copyWith(customOutputWrapper = customOutputWrapper)
262
+
263
+ @ deprecated(" Not a case class anymore" , " 0.6.5" )
264
+ def copy (
265
+ output : WritableVirtualJSFile = this .output,
266
+ cache : Option [WritableVirtualTextFile ] = this .cache,
267
+ bypassLinkingErrors : Boolean = this .bypassLinkingErrors,
268
+ checkIR : Boolean = this .checkIR,
269
+ unCache : Boolean = this .unCache,
270
+ disableOptimizer : Boolean = this .disableOptimizer,
271
+ batchMode : Boolean = this .batchMode,
272
+ wantSourceMap : Boolean = this .wantSourceMap,
273
+ prettyPrint : Boolean = this .prettyPrint,
274
+ relativizeSourceMapBase : Option [URI ] = this .relativizeSourceMapBase,
275
+ noWarnMissing : Seq [ScalaJSOptimizer .NoWarnMissing ] = this .noWarnMissing): Config = {
276
+
277
+ copyWith(output, cache, bypassLinkingErrors, checkIR, unCache,
278
+ disableOptimizer, batchMode, wantSourceMap, prettyPrint,
279
+ relativizeSourceMapBase, noWarnMissing)
280
+ }
281
+
282
+ private def copyWith (
283
+ output : WritableVirtualJSFile = this .output,
284
+ cache : Option [WritableVirtualTextFile ] = this .cache,
285
+ bypassLinkingErrors : Boolean = this .bypassLinkingErrors,
286
+ checkIR : Boolean = this .checkIR,
287
+ unCache : Boolean = this .unCache,
288
+ disableOptimizer : Boolean = this .disableOptimizer,
289
+ batchMode : Boolean = this .batchMode,
290
+ wantSourceMap : Boolean = this .wantSourceMap,
291
+ prettyPrint : Boolean = this .prettyPrint,
292
+ relativizeSourceMapBase : Option [URI ] = this .relativizeSourceMapBase,
293
+ noWarnMissing : Seq [ScalaJSOptimizer .NoWarnMissing ] = this .noWarnMissing,
294
+ customOutputWrapper : (String , String ) = this .customOutputWrapper): Config = {
295
+
296
+ new Config (output, cache, bypassLinkingErrors, checkIR, unCache,
297
+ disableOptimizer, batchMode, wantSourceMap, prettyPrint,
298
+ relativizeSourceMapBase, noWarnMissing, customOutputWrapper)
299
+ }
300
+
301
+ // For binary compatibility
302
+ @ deprecated(" Not a case class anymore" , " 0.6.5" )
303
+ def canEqual (that : Any ): Boolean = true
304
+
305
+ // For binary compatibility
306
+ @ deprecated(" Not a case class anymore" , " 0.6.5" )
307
+ def productArity : Int = productArray.length
308
+
309
+ // For binary compatibility
310
+ @ deprecated(" Not a case class anymore" , " 0.6.5" )
311
+ def productElement (n : Int ): Any = productArray(n)
312
+
313
+ private def productArray : Array [Any ] = {
314
+ Array [Any ](output, cache, bypassLinkingErrors, checkIR, unCache,
315
+ disableOptimizer, batchMode, wantSourceMap, prettyPrint,
316
+ relativizeSourceMapBase, noWarnMissing, customOutputWrapper)
317
+ }
318
+
319
+ // For binary compatibility
320
+ override def equals (other : Any ): Boolean = super .equals(other)
321
+
322
+ // For binary compatibility
323
+ override def hashCode (): Int = super .hashCode()
324
+
325
+ // For binary compatibility
326
+ override def toString (): String =
327
+ productArray.mkString(" Config(" , " , " , " )" )
328
+ }
329
+
330
+ object Config extends runtime.AbstractFunction11 [WritableVirtualJSFile ,
331
+ Option [WritableVirtualTextFile ], Boolean , Boolean , Boolean ,
332
+ Boolean , Boolean , Boolean , Boolean , Option [URI ],
333
+ Seq [ScalaJSOptimizer .NoWarnMissing ], Config ] {
334
+
335
+ def apply (output : WritableVirtualJSFile ): Config = {
336
+ new Config (
337
+ output = output,
338
+ cache = None ,
339
+ bypassLinkingErrors = false ,
340
+ checkIR = false ,
341
+ unCache = true ,
342
+ disableOptimizer = false ,
343
+ batchMode = false ,
344
+ wantSourceMap = false ,
345
+ prettyPrint = false ,
346
+ relativizeSourceMapBase = None ,
347
+ noWarnMissing = Nil ,
348
+ customOutputWrapper = (" " , " " ))
349
+ }
350
+
351
+ // For binary compatibility
352
+ @ deprecated(" Use Config(output) and .withXYZ() methods" , " 0.6.5" )
353
+ def apply (
354
+ output : WritableVirtualJSFile ,
355
+ cache : Option [WritableVirtualTextFile ] = None ,
356
+ bypassLinkingErrors : Boolean = false ,
357
+ checkIR : Boolean = false ,
358
+ unCache : Boolean = true ,
359
+ disableOptimizer : Boolean = false ,
360
+ batchMode : Boolean = false ,
361
+ wantSourceMap : Boolean = false ,
362
+ prettyPrint : Boolean = false ,
363
+ relativizeSourceMapBase : Option [URI ] = None ,
364
+ noWarnMissing : Seq [ScalaJSOptimizer .NoWarnMissing ] = Nil ): Config = {
365
+
366
+ new Config (output, cache, bypassLinkingErrors, checkIR, unCache,
367
+ disableOptimizer, batchMode, wantSourceMap, prettyPrint,
368
+ relativizeSourceMapBase, noWarnMissing, customOutputWrapper = (" " , " " ))
369
+ }
370
+
371
+ // For binary compatibility
372
+ @ deprecated(" Not a case class anymore" , " 0.6.5" )
373
+ def unapply (config : Config ): Option [(WritableVirtualJSFile ,
374
+ Option [WritableVirtualTextFile ], Boolean , Boolean , Boolean ,
375
+ Boolean , Boolean , Boolean , Boolean , Option [URI ],
376
+ Seq [ScalaJSOptimizer .NoWarnMissing ])] = {
377
+
378
+ Some ((config.output, config.cache, config.bypassLinkingErrors,
379
+ config.checkIR, config.unCache, config.disableOptimizer,
380
+ config.batchMode, config.wantSourceMap, config.prettyPrint,
381
+ config.relativizeSourceMapBase, config.noWarnMissing))
382
+ }
383
+ }
182
384
183
385
/** Minimal set of externs to compile Scala.js-emitted code with Closure. */
184
386
val ScalaJSExterns = """
0 commit comments