@@ -73,10 +73,16 @@ object JSSymUtils {
73
73
lazy val pc = sym.info.paramNamess.map(_.size).sum
74
74
75
75
sym.name match {
76
- case nme.apply => Call
77
- case JSUnaryOpMethodName (code) if pc == 0 => UnaryOp (code)
78
- case JSBinaryOpMethodName (code) if pc == 1 => BinaryOp (code)
79
- case _ => default
76
+ case nme.apply =>
77
+ Call
78
+ case JSUnaryOpMethodName (code, defaultsToOp)
79
+ if (defaultsToOp || sym.hasAnnotation(jsdefn.JSOperatorAnnot )) && pc == 0 =>
80
+ UnaryOp (code)
81
+ case JSBinaryOpMethodName (code, defaultsToOp)
82
+ if (defaultsToOp || sym.hasAnnotation(jsdefn.JSOperatorAnnot )) && pc == 1 =>
83
+ BinaryOp (code)
84
+ case _ =>
85
+ default
80
86
}
81
87
} else {
82
88
default
@@ -182,6 +188,7 @@ object JSSymUtils {
182
188
sym.info.paramNamess.flatten.zip(sym.info.paramInfoss.flatten)
183
189
184
190
val paramInfosAtElimRepeated = atPhase(elimRepeatedPhase) {
191
+ // See also JSCodeGen.genActualArgs
185
192
val list =
186
193
for ((name, info) <- paramNamesAndTypes) yield {
187
194
val v =
@@ -230,43 +237,70 @@ object JSSymUtils {
230
237
end sjsNeedsField
231
238
}
232
239
240
+ /** Extractor for a `TermName` that *may* be a JS unary operator.
241
+ *
242
+ * If it may be a JS unary operator, then a method with that name may have
243
+ * the `@JSOperator` annotation, and it will be treated as such.
244
+ *
245
+ * If a method has neither `@JSName` nor `@JSOperator`, then a default is
246
+ * chosen. If the `Boolean` value is `true`, the default is to treat the
247
+ * method as if it had `@JSOperator`. If it is `false`, the default is *not*
248
+ * to treat it as an operator.
249
+ *
250
+ * Currently, all JS unary operators default to `@JSOperator`.
251
+ */
233
252
private object JSUnaryOpMethodName {
234
253
private val map = Map (
235
- nme.UNARY_+ -> js.JSUnaryOp .+ ,
236
- nme.UNARY_- -> js.JSUnaryOp .- ,
237
- nme.UNARY_~ -> js.JSUnaryOp .~ ,
238
- nme.UNARY_! -> js.JSUnaryOp .!
254
+ nme.UNARY_+ -> ( js.JSUnaryOp .+ , true ) ,
255
+ nme.UNARY_- -> ( js.JSUnaryOp .- , true ) ,
256
+ nme.UNARY_~ -> ( js.JSUnaryOp .~ , true ) ,
257
+ nme.UNARY_! -> ( js.JSUnaryOp .! , true ),
239
258
)
240
259
241
- def unapply (name : TermName ): Option [js.JSUnaryOp .Code ] =
260
+ def unapply (name : TermName ): Option [( js.JSUnaryOp .Code , Boolean ) ] =
242
261
map.get(name)
243
262
}
244
263
264
+ /** Extractor for a `TermName` that *may* be a JS binary operator.
265
+ *
266
+ * If it may be a JS binary operator, then a method with that name may have
267
+ * the `@JSOperator` annotation, and it will be treated as such.
268
+ *
269
+ * If a method has neither `@JSName` nor `@JSOperator`, then a default is
270
+ * chosen. If the `Boolean` value is `true`, the default is to treat the
271
+ * method as if it had `@JSOperator`. If it is `false`, the default is *not*
272
+ * to treat it as an operator.
273
+ *
274
+ * Most JS binary operators default to `@JSOperator`. Currently, the only
275
+ * exception is `**`, for backward compatibility reasons.
276
+ */
245
277
private object JSBinaryOpMethodName {
246
278
private val map = Map (
247
- nme.ADD -> js.JSBinaryOp .+ ,
248
- nme.SUB -> js.JSBinaryOp .- ,
249
- nme.MUL -> js.JSBinaryOp .* ,
250
- nme.DIV -> js.JSBinaryOp ./ ,
251
- nme.MOD -> js.JSBinaryOp .% ,
252
-
253
- nme.LSL -> js.JSBinaryOp .<< ,
254
- nme.ASR -> js.JSBinaryOp .>> ,
255
- nme.LSR -> js.JSBinaryOp .>>> ,
256
- nme.OR -> js.JSBinaryOp .| ,
257
- nme.AND -> js.JSBinaryOp .& ,
258
- nme.XOR -> js.JSBinaryOp .^ ,
259
-
260
- nme.LT -> js.JSBinaryOp .< ,
261
- nme.LE -> js.JSBinaryOp .<= ,
262
- nme.GT -> js.JSBinaryOp .> ,
263
- nme.GE -> js.JSBinaryOp .>= ,
264
-
265
- nme.ZAND -> js.JSBinaryOp .&& ,
266
- nme.ZOR -> js.JSBinaryOp .||
279
+ nme.ADD -> (js.JSBinaryOp .+ , true ),
280
+ nme.SUB -> (js.JSBinaryOp .- , true ),
281
+ nme.MUL -> (js.JSBinaryOp .* , true ),
282
+ nme.DIV -> (js.JSBinaryOp ./ , true ),
283
+ nme.MOD -> (js.JSBinaryOp .% , true ),
284
+
285
+ nme.LSL -> (js.JSBinaryOp .<< , true ),
286
+ nme.ASR -> (js.JSBinaryOp .>> , true ),
287
+ nme.LSR -> (js.JSBinaryOp .>>> , true ),
288
+ nme.OR -> (js.JSBinaryOp .| , true ),
289
+ nme.AND -> (js.JSBinaryOp .& , true ),
290
+ nme.XOR -> (js.JSBinaryOp .^ , true ),
291
+
292
+ nme.LT -> (js.JSBinaryOp .< , true ),
293
+ nme.LE -> (js.JSBinaryOp .<= , true ),
294
+ nme.GT -> (js.JSBinaryOp .> , true ),
295
+ nme.GE -> (js.JSBinaryOp .>= , true ),
296
+
297
+ nme.ZAND -> (js.JSBinaryOp .&& , true ),
298
+ nme.ZOR -> (js.JSBinaryOp .|| , true ),
299
+
300
+ termName(" **" ) -> (js.JSBinaryOp .** , false ),
267
301
)
268
302
269
- def unapply (name : TermName ): Option [js.JSBinaryOp .Code ] =
303
+ def unapply (name : TermName ): Option [( js.JSBinaryOp .Code , Boolean ) ] =
270
304
map.get(name)
271
305
}
272
306
}
0 commit comments