@@ -6196,7 +6196,7 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
6196
6196
* But that lowers the type to iterable.
6197
6197
*/
6198
6198
if (hasRepeatedParam) {
6199
- val (p, l) = genPatchedParam(params.last, genJSArrayToVarArgs(_), ObjectTpe )
6199
+ val (p, l) = genPatchedParam(params.last, genJSArrayToVarArgs(_), jstpe. AnyType )
6200
6200
(Some (p), Some (l))
6201
6201
} else {
6202
6202
(None , None )
@@ -6266,32 +6266,45 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
6266
6266
* To translate them, we first construct a typed closure for the body:
6267
6267
* {{{
6268
6268
* typed-lambda<_this = this, capture1: U1 = capture1, ..., captureM: UM = captureM>(
6269
- * arg1: S1 , ..., argN: SN ): TR = {
6270
- * val arg1Unboxed: T1 = arg1.asInstanceOf[T1 ];
6269
+ * arg1: T1 , ..., argN: TN ): TR = {
6270
+ * val arg1Unboxed: S1 = arg1.asInstanceOf[S1 ];
6271
6271
* ...
6272
- * val argNUnboxed: TN = argN.asInstanceOf[TN ];
6272
+ * val argNUnboxed: SN = argN.asInstanceOf[SN ];
6273
6273
* // inlined body of `someMethod`, boxed
6274
6274
* }
6275
6275
* }}}
6276
6276
* In the closure, input params are unboxed before use, and the result of
6277
- * the body of `someMethod` is boxed back.
6277
+ * the body of `someMethod` is boxed back. The Si and SR are the types
6278
+ * found in the target `someMethod`; the Ti and TR are the types found in
6279
+ * the SAM method to be impleemnted. It is common for `Si` to be different
6280
+ * from `Ti`. For example, in a Scala function `(x: Int) => x`,
6281
+ * `S1 = SR = int`, but `T1 = TR = any`, because `scala.Function1` defines
6282
+ * an `apply` method that erases to using `any`'s.
6278
6283
*
6279
6284
* Then, we wrap that closure in a class satisfying the expected type.
6280
- * For Scala function types, we use the existing
6281
- * `scala.scalajs.runtime.AnonFunctionN` from the library. For other
6282
- * LMF-capable types, we generate a class on the fly, which looks like
6283
- * this:
6285
+ * For SAM types that do not need any bridges (including all Scala
6286
+ * function types), we use a `NewLambda` node.
6287
+ *
6288
+ * When bridges are required (which is rare), we generate a class on the
6289
+ * fly. In that case, we "inline" the captures of the typed closure as
6290
+ * fields of the class, and its body as the body of the main SAM method
6291
+ * implementation. Overall, it looks like this:
6284
6292
* {{{
6285
6293
* class AnonFun extends Object with FunctionalInterface {
6286
6294
* val ...captureI: UI
6287
6295
* def <init>(...captureI: UI) {
6288
6296
* super();
6289
6297
* ...this.captureI = captureI;
6290
6298
* }
6299
+ * // main SAM method implementation
6291
6300
* def theSAMMethod(params: Ti...): TR = {
6292
6301
* val ...captureI = this.captureI;
6293
6302
* // inline body of the typed-lambda
6294
6303
* }
6304
+ * // a bridge
6305
+ * def theSAMMethod(params: Vi...): VR = {
6306
+ * this.theSAMMethod(...params.asInstanceOf[Ti]).asInstanceOf[VR]
6307
+ * }
6295
6308
* }
6296
6309
* }}}
6297
6310
*/
@@ -6623,19 +6636,20 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
6623
6636
((param, paramSym), fromParamType) <- params.zip(paramSyms).zip(fromParamTypes)
6624
6637
} yield {
6625
6638
val paramTpe = paramTpes.getOrElse(paramSym.name, paramSym.tpe)
6626
- genPatchedParam(param, adaptBoxes(_, fromParamType, paramTpe), fromParamType)
6639
+ genPatchedParam(param, adaptBoxes(_, fromParamType, paramTpe),
6640
+ toIRType(underlyingOfEVT(fromParamType)))
6627
6641
}).unzip
6628
6642
}
6629
6643
6630
6644
private def genPatchedParam (param : js.ParamDef , rhs : js.VarRef => js.Tree ,
6631
- fromParamType : Type )(
6645
+ fromParamType : jstpe. Type )(
6632
6646
implicit pos : Position ): (js.ParamDef , js.VarDef ) = {
6633
6647
val paramNameIdent = param.name
6634
6648
val origName = param.originalName
6635
6649
val newNameIdent = freshLocalIdent(paramNameIdent.name)(paramNameIdent.pos)
6636
6650
val newOrigName = origName.orElse(paramNameIdent.name)
6637
- val patchedParam = js.ParamDef (newNameIdent, newOrigName,
6638
- toIRType(underlyingOfEVT(fromParamType)), mutable = false )(param.pos)
6651
+ val patchedParam = js.ParamDef (newNameIdent, newOrigName, fromParamType,
6652
+ mutable = false )(param.pos)
6639
6653
val paramLocal = js.VarDef (paramNameIdent, origName, param.ptpe,
6640
6654
mutable = false , rhs(patchedParam.ref))
6641
6655
(patchedParam, paramLocal)
0 commit comments