@@ -152,7 +152,8 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
152
152
153
153
case Constructor | Method =>
154
154
val methodDef = withNewLocalNameScope {
155
- genExportMethod(tups.map(_._2), JSName .Literal (info.jsName), static = true )
155
+ genExportMethod(tups.map(_._2), JSName .Literal (info.jsName), static = true ,
156
+ allowCallsiteInlineSingle = false )
156
157
}
157
158
158
159
js.TopLevelMethodExportDef (info.moduleID, methodDef)
@@ -191,11 +192,13 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
191
192
kind match {
192
193
case Method =>
193
194
methodProps += genMemberExportOrDispatcher(
194
- JSName .Literal (info.jsName), isProp = false , alts, static = true )
195
+ JSName .Literal (info.jsName), isProp = false , alts, static = true ,
196
+ allowCallsiteInlineSingle = false )
195
197
196
198
case Property =>
197
199
methodProps += genMemberExportOrDispatcher(
198
- JSName .Literal (info.jsName), isProp = true , alts, static = true )
200
+ JSName .Literal (info.jsName), isProp = true , alts, static = true ,
201
+ allowCallsiteInlineSingle = false )
199
202
200
203
case Field =>
201
204
val sym = checkSingleField(tups)
@@ -244,7 +247,8 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
244
247
s " Exported $kind $jsName conflicts with ${alts.head.fullName}" )
245
248
}
246
249
247
- genMemberExportOrDispatcher(JSName .Literal (jsName), isProp, alts, static = false )
250
+ genMemberExportOrDispatcher(JSName .Literal (jsName), isProp, alts,
251
+ static = false , allowCallsiteInlineSingle = false )
248
252
}
249
253
250
254
private def genJSClassDispatcher (classSym : Symbol , name : JSName ): js.JSMethodPropDef = {
@@ -272,22 +276,24 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
272
276
implicit val pos = alts.head.pos
273
277
js.JSPropertyDef (js.MemberFlags .empty, genExpr(name), None , None )(Unversioned )
274
278
} else {
275
- genMemberExportOrDispatcher(name, isProp, alts, static = false )
279
+ genMemberExportOrDispatcher(name, isProp, alts, static = false ,
280
+ allowCallsiteInlineSingle = true )
276
281
}
277
282
}
278
283
279
284
def genMemberExportOrDispatcher (jsName : JSName , isProp : Boolean ,
280
- alts : List [Symbol ], static : Boolean ): js.JSMethodPropDef = {
285
+ alts : List [Symbol ], static : Boolean ,
286
+ allowCallsiteInlineSingle : Boolean ): js.JSMethodPropDef = {
281
287
withNewLocalNameScope {
282
288
if (isProp)
283
- genExportProperty(alts, jsName, static)
289
+ genExportProperty(alts, jsName, static, allowCallsiteInlineSingle )
284
290
else
285
- genExportMethod(alts, jsName, static)
291
+ genExportMethod(alts, jsName, static, allowCallsiteInlineSingle )
286
292
}
287
293
}
288
294
289
295
private def genExportProperty (alts : List [Symbol ], jsName : JSName ,
290
- static : Boolean ): js.JSPropertyDef = {
296
+ static : Boolean , allowCallsiteInlineSingle : Boolean ): js.JSPropertyDef = {
291
297
assert(! alts.isEmpty,
292
298
s " genExportProperty with empty alternatives for $jsName" )
293
299
@@ -307,7 +313,8 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
307
313
reportCannotDisambiguateError(jsName, alts)
308
314
309
315
val getterBody = getter.headOption.map { getterSym =>
310
- genApplyForSym(new FormalArgsRegistry (0 , false ), getterSym, static)
316
+ genApplyForSym(new FormalArgsRegistry (0 , false ), getterSym, static,
317
+ inline = allowCallsiteInlineSingle)
311
318
}
312
319
313
320
val setterArgAndBody = {
@@ -316,9 +323,18 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
316
323
} else {
317
324
val formalArgsRegistry = new FormalArgsRegistry (1 , false )
318
325
val (List (arg), None ) = formalArgsRegistry.genFormalArgs()
319
- val body = genOverloadDispatchSameArgc(jsName, formalArgsRegistry,
320
- alts = setters.map(new ExportedSymbol (_, static)), jstpe.AnyType ,
321
- paramIndex = 0 )
326
+
327
+ val body = {
328
+ if (setters.size == 1 ) {
329
+ genApplyForSym(formalArgsRegistry, setters.head, static,
330
+ inline = allowCallsiteInlineSingle)
331
+ } else {
332
+ genOverloadDispatchSameArgc(jsName, formalArgsRegistry,
333
+ alts = setters.map(new ExportedSymbol (_, static)), jstpe.AnyType ,
334
+ paramIndex = 0 )
335
+ }
336
+ }
337
+
322
338
Some ((arg, body))
323
339
}
324
340
}
@@ -329,7 +345,7 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
329
345
/** generates the exporter function (i.e. exporter for non-properties) for
330
346
* a given name */
331
347
private def genExportMethod (alts0 : List [Symbol ], jsName : JSName ,
332
- static : Boolean ): js.JSMethodDef = {
348
+ static : Boolean , allowCallsiteInlineSingle : Boolean ): js.JSMethodDef = {
333
349
assert(alts0.nonEmpty,
334
350
" need at least one alternative to generate exporter method" )
335
351
@@ -354,8 +370,20 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
354
370
355
371
val overloads = alts.map(new ExportedSymbol (_, static))
356
372
357
- val (formalArgs, restParam, body) =
358
- genOverloadDispatch(jsName, overloads, jstpe.AnyType )
373
+ val (formalArgs, restParam, body) = {
374
+ if (overloads.size == 1 ) {
375
+ val trg = overloads.head
376
+ val minArgc = trg.params.lastIndexWhere(p => ! p.hasDefault && ! p.repeated) + 1
377
+ val formalArgsRegistry = new FormalArgsRegistry (minArgc,
378
+ needsRestParam = trg.params.size > minArgc)
379
+ val body = genApplyForSym(formalArgsRegistry, trg.sym, static,
380
+ inline = allowCallsiteInlineSingle)
381
+ val (formalArgs, restParam) = formalArgsRegistry.genFormalArgs()
382
+ (formalArgs, restParam, body)
383
+ } else {
384
+ genOverloadDispatch(jsName, overloads, jstpe.AnyType )
385
+ }
386
+ }
359
387
360
388
js.JSMethodDef (flags, genExpr(jsName), formalArgs, restParam, body)(
361
389
OptimizerHints .empty, Unversioned )
@@ -633,13 +661,13 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
633
661
* required.
634
662
*/
635
663
private def genApplyForSym (formalArgsRegistry : FormalArgsRegistry ,
636
- sym : Symbol , static : Boolean ): js.Tree = {
664
+ sym : Symbol , static : Boolean , inline : Boolean ): js.Tree = {
637
665
if (isNonNativeJSClass(currentClassSym) &&
638
666
sym.owner != currentClassSym.get) {
639
667
assert(! static, s " nonsensical JS super call in static export of $sym" )
640
668
genApplyForSymJSSuperCall(formalArgsRegistry, sym)
641
669
} else {
642
- genApplyForSymNonJSSuperCall(formalArgsRegistry, sym, static)
670
+ genApplyForSymNonJSSuperCall(formalArgsRegistry, sym, static, inline )
643
671
}
644
672
}
645
673
@@ -681,7 +709,7 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
681
709
682
710
private def genApplyForSymNonJSSuperCall (
683
711
formalArgsRegistry : FormalArgsRegistry , sym : Symbol ,
684
- static : Boolean ): js.Tree = {
712
+ static : Boolean , inline : Boolean ): js.Tree = {
685
713
implicit val pos = sym.pos
686
714
687
715
val varDefs = new mutable.ListBuffer [js.VarDef ]
@@ -696,7 +724,7 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
696
724
697
725
val builtVarDefs = varDefs.result()
698
726
699
- val jsResult = genResult(sym, builtVarDefs.map(_.ref), static)
727
+ val jsResult = genResult(sym, builtVarDefs.map(_.ref), static, inline )
700
728
701
729
js.Block (builtVarDefs :+ jsResult)
702
730
}
@@ -850,7 +878,7 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
850
878
851
879
/** Generate the final forwarding call to the exported method. */
852
880
private def genResult (sym : Symbol , args : List [js.Tree ],
853
- static : Boolean )(implicit pos : Position ): js.Tree = {
881
+ static : Boolean , inline : Boolean )(implicit pos : Position ): js.Tree = {
854
882
def receiver = {
855
883
if (static)
856
884
genLoadModule(sym.owner)
@@ -860,17 +888,18 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
860
888
861
889
if (isNonNativeJSClass(currentClassSym)) {
862
890
assert(sym.owner == currentClassSym.get, sym.fullName)
863
- ensureResultBoxed(genApplyJSClassMethod(receiver, sym, args), sym)
891
+ ensureResultBoxed(genApplyJSClassMethod(receiver, sym, args, inline = inline ), sym)
864
892
} else {
865
893
if (sym.isClassConstructor)
866
894
genNew(currentClassSym, sym, args)
867
895
else if (sym.isPrivate)
868
- ensureResultBoxed(genApplyMethodStatically(receiver, sym, args), sym)
896
+ ensureResultBoxed(genApplyMethodStatically(receiver, sym, args, inline = inline ), sym)
869
897
else
870
- ensureResultBoxed(genApplyMethod(receiver, sym, args), sym)
898
+ ensureResultBoxed(genApplyMethod(receiver, sym, args, inline = inline ), sym)
871
899
}
872
900
}
873
901
902
+ // Note: GenJSCode creates an anonymous subclass of Exported for JS class constructors.
874
903
abstract class Exported (val sym : Symbol ,
875
904
// Parameters participating in overload resolution.
876
905
val params : immutable.IndexedSeq [JSParamInfo ]) {
@@ -895,7 +924,7 @@ trait GenJSExports[G <: Global with Singleton] extends SubComponent {
895
924
private class ExportedSymbol (sym : Symbol , static : Boolean )
896
925
extends Exported (sym, jsParamInfos(sym).toIndexedSeq) {
897
926
def genBody (formalArgsRegistry : FormalArgsRegistry ): js.Tree =
898
- genApplyForSym(formalArgsRegistry, sym, static)
927
+ genApplyForSym(formalArgsRegistry, sym, static, inline = false )
899
928
}
900
929
}
901
930
0 commit comments