Skip to content

Commit 4d4e4b7

Browse files
committed
Fix #2859: Remove @JSExportNamed
1 parent facca85 commit 4d4e4b7

File tree

9 files changed

+11
-451
lines changed

9 files changed

+11
-451
lines changed

compiler/src/main/scala/org/scalajs/core/compiler/GenJSCode.scala

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -392,10 +392,7 @@ abstract class GenJSCode extends plugins.PluginComponent
392392
() // fields are added via genClassFields()
393393

394394
case dd: DefDef =>
395-
if (isNamedExporterDef(dd))
396-
generatedMethods ++= genNamedExporterDef(dd)
397-
else
398-
generatedMethods ++= genMethod(dd)
395+
generatedMethods ++= genMethod(dd)
399396

400397
case _ => abort("Illegal tree in gen of genClass(): " + tree)
401398
}
@@ -798,10 +795,7 @@ abstract class GenJSCode extends plugins.PluginComponent
798795
case Template(_, _, body) => body.flatMap(gen)
799796

800797
case dd: DefDef =>
801-
if (isNamedExporterDef(dd))
802-
genNamedExporterDef(dd).toList
803-
else
804-
genMethod(dd).toList
798+
genMethod(dd).toList
805799

806800
case _ =>
807801
abort("Illegal tree in gen of genInterface(): " + tree)

compiler/src/main/scala/org/scalajs/core/compiler/GenJSExports.scala

Lines changed: 1 addition & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -74,19 +74,7 @@ trait GenJSExports extends SubComponent { self: GenJSCode =>
7474
val exports = for {
7575
(jsName, specs) <- ctorExports.groupBy(_._1.jsName) // group by exported name
7676
} yield {
77-
val (namedExports, normalExports) = specs.partition(_._1.isNamed)
78-
79-
val normalCtors = normalExports.map(s => ExportedSymbol(s._2))
80-
val namedCtors = for {
81-
(exp, ctor) <- namedExports
82-
} yield {
83-
implicit val pos = exp.pos
84-
ExportedBody(List(JSAnyTpe),
85-
genNamedExporterBody(ctor, genFormalArg(1).ref),
86-
nme.CONSTRUCTOR.toString, pos)
87-
}
88-
89-
val ctors = normalCtors ++ namedCtors
77+
val ctors = specs.map(s => ExportedSymbol(s._2))
9078

9179
implicit val pos = ctors.head.pos
9280

@@ -106,7 +94,6 @@ trait GenJSExports extends SubComponent { self: GenJSCode =>
10694
exp <- jsInterop.registeredExportsOf(classSym)
10795
} yield {
10896
implicit val pos = exp.pos
109-
assert(!exp.isNamed, "Class cannot be exported named")
11097

11198
exp.destination match {
11299
case ExportDestination.Normal | ExportDestination.TopLevel =>
@@ -123,7 +110,6 @@ trait GenJSExports extends SubComponent { self: GenJSCode =>
123110
exp <- jsInterop.registeredExportsOf(classSym)
124111
} yield {
125112
implicit val pos = exp.pos
126-
assert(!exp.isNamed, "Module cannot be exported named")
127113

128114
exp.destination match {
129115
case ExportDestination.Normal =>
@@ -237,66 +223,6 @@ trait GenJSExports extends SubComponent { self: GenJSCode =>
237223
}
238224
}
239225

240-
/** Tests whether the given def a named exporter def that needs to be
241-
* generated with `genNamedExporterDef`.
242-
*/
243-
def isNamedExporterDef(dd: DefDef): Boolean = {
244-
jsInterop.isExport(dd.symbol) &&
245-
dd.symbol.annotations.exists(_.symbol == JSExportNamedAnnotation)
246-
}
247-
248-
/** Generate the exporter proxy for a named export */
249-
def genNamedExporterDef(dd: DefDef): Option[js.MethodDef] = {
250-
implicit val pos = dd.pos
251-
252-
if (isAbstractMethod(dd)) {
253-
None
254-
} else {
255-
val sym = dd.symbol
256-
257-
val Block(Apply(fun, _) :: Nil, _) = dd.rhs
258-
val trgSym = fun.symbol
259-
260-
val inArg =
261-
js.ParamDef(js.Ident("namedParams"), jstpe.AnyType,
262-
mutable = false, rest = false)
263-
val inArgRef = inArg.ref
264-
265-
val methodIdent = encodeMethodSym(sym)
266-
267-
Some(js.MethodDef(static = false, methodIdent,
268-
List(inArg), toIRType(sym.tpe.resultType),
269-
Some(genNamedExporterBody(trgSym, inArg.ref)))(
270-
OptimizerHints.empty, None))
271-
}
272-
}
273-
274-
private def genNamedExporterBody(trgSym: Symbol, inArg: js.Tree)(
275-
implicit pos: Position) = {
276-
277-
if (hasRepeatedParam(trgSym)) {
278-
reporter.error(pos,
279-
"You may not name-export a method with a *-parameter")
280-
}
281-
282-
val jsArgs = for {
283-
(pSym, index) <- trgSym.info.params.zipWithIndex
284-
} yield {
285-
val rhs = js.JSBracketSelect(inArg,
286-
js.StringLiteral(pSym.name.decoded))
287-
js.VarDef(js.Ident("namedArg$" + index), jstpe.AnyType,
288-
mutable = false, rhs = rhs)
289-
}
290-
291-
val jsArgRefs = jsArgs.map(_.ref)
292-
293-
// Generate JS code to prepare arguments (default getters and unboxes)
294-
val jsArgPrep = genPrepareArgs(jsArgRefs, trgSym)
295-
val jsResult = genResult(trgSym, jsArgPrep.map(_.ref), static = false)
296-
297-
js.Block(jsArgs ++ jsArgPrep :+ jsResult)
298-
}
299-
300226
private def genMemberExport(classSym: Symbol, name: TermName): js.Tree = {
301227
val alts = classSym.info.member(name).alternatives
302228

compiler/src/main/scala/org/scalajs/core/compiler/JSDefinitions.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,6 @@ trait JSDefinitions { self: JSGlobalAddons =>
5959
lazy val JSBracketCallAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSBracketCall")
6060
lazy val JSExportAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExport")
6161
lazy val JSExportAllAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportAll")
62-
lazy val JSExportNamedAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportNamed")
6362
lazy val JSExportStaticAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportStatic")
6463
lazy val JSExportTopLevelAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSExportTopLevel")
6564
lazy val JSImportAnnotation = getRequiredClass("scala.scalajs.js.annotation.JSImport")

compiler/src/main/scala/org/scalajs/core/compiler/JSGlobalAddons.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ trait JSGlobalAddons extends JSDefinitions
6565
trait ExportInfo {
6666
val jsName: String
6767
val pos: Position
68-
val isNamed: Boolean
6968
val destination: ExportDestination
7069
}
7170

compiler/src/main/scala/org/scalajs/core/compiler/PrepJSExports.scala

Lines changed: 6 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,9 @@ trait PrepJSExports { this: PrepJSInterop =>
2121

2222
import scala.reflect.internal.Flags
2323

24-
case class ExportInfo(jsName: String, isNamed: Boolean,
24+
case class ExportInfo(jsName: String,
2525
destination: ExportDestination)(val pos: Position)
26-
extends jsInterop.ExportInfo {
27-
assert(!isNamed || destination == ExportDestination.Normal)
28-
}
26+
extends jsInterop.ExportInfo
2927

3028
private final val SuppressExportDeprecationsMsg = {
3129
"\n (you can suppress this warning in 0.6.x by passing the option " +
@@ -98,12 +96,7 @@ trait PrepJSExports { this: PrepJSInterop =>
9896
jsInterop.registerForExport(baseSym, topLevelAndStaticExports)
9997

10098
// Actually generate exporter methods
101-
normalExports.flatMap { exp =>
102-
if (exp.isNamed)
103-
genNamedExport(baseSym, exp.jsName, exp.pos) :: Nil
104-
else
105-
genExportDefs(baseSym, exp.jsName, exp.pos)
106-
}
99+
normalExports.flatMap(exp => genExportDefs(baseSym, exp.jsName, exp.pos))
107100
}
108101
}
109102

@@ -147,16 +140,7 @@ trait PrepJSExports { this: PrepJSInterop =>
147140
} else if (!isMod && !hasAnyNonPrivateCtor) {
148141
err("You may not export a class that has only private constructors")
149142
} else {
150-
val (named, normal) = exports.partition(_.isNamed)
151-
152-
for {
153-
exp <- named
154-
} {
155-
reporter.error(exp.pos, "You may not use @JSNamedExport on " +
156-
(if (isMod) "an object" else "a Scala.js-defined JS class"))
157-
}
158-
159-
jsInterop.registerForExport(sym, normal)
143+
jsInterop.registerForExport(sym, exports)
160144
}
161145
}
162146
}
@@ -204,7 +188,6 @@ trait PrepJSExports { this: PrepJSInterop =>
204188
val allExportInfos = for {
205189
annot <- directAnnots ++ unitAnnots
206190
} yield {
207-
val isNamedExport = annot.symbol == JSExportNamedAnnotation
208191
val isExportAll = annot.symbol == JSExportAllAnnotation
209192
val isTopLevelExport = annot.symbol == JSExportTopLevelAnnotation
210193
val isStaticExport = annot.symbol == JSExportStaticAnnotation
@@ -288,20 +271,14 @@ trait PrepJSExports { this: PrepJSInterop =>
288271
case ExportDestination.Normal =>
289272
// Make sure we do not override the default export of toString
290273
def isIllegalToString = {
291-
isMember && !isNamedExport &&
292-
name == "toString" && sym.name != nme.toString_ &&
274+
isMember && name == "toString" && sym.name != nme.toString_ &&
293275
sym.tpe.params.isEmpty && !jsInterop.isJSGetter(sym)
294276
}
295277
if (isIllegalToString) {
296278
reporter.error(annot.pos, "You may not export a zero-argument " +
297279
"method named other than 'toString' under the name 'toString'")
298280
}
299281

300-
if (isNamedExport && jsInterop.isJSProperty(sym)) {
301-
reporter.error(annot.pos,
302-
"You may not export a getter or a setter as a named export")
303-
}
304-
305282
// Don't allow nested class / module exports without explicit name.
306283
def isStaticNested = {
307284
/* For Scala.js defined JS classes, sym is the class itself. For
@@ -388,7 +365,7 @@ trait PrepJSExports { this: PrepJSInterop =>
388365
}
389366
}
390367

391-
ExportInfo(name, isNamedExport, destination)(annot.pos)
368+
ExportInfo(name, destination)(annot.pos)
392369
}
393370

394371
/* Filter out static exports of accessors (as they are not actually
@@ -483,7 +460,6 @@ trait PrepJSExports { this: PrepJSInterop =>
483460

484461
// Remove export annotations
485462
expSym.removeAnnotation(JSExportAnnotation)
486-
expSym.removeAnnotation(JSExportNamedAnnotation)
487463

488464
// Add symbol to class
489465
clsSym.info.decls.enter(expSym)
@@ -500,43 +476,6 @@ trait PrepJSExports { this: PrepJSInterop =>
500476
exporter :: defaultGetters
501477
}
502478

503-
/** Generate a dummy DefDef tree for a named export. This tree is captured
504-
* by GenJSCode again to generate the required JavaScript logic.
505-
*/
506-
private def genNamedExport(defSym: Symbol, jsName: String, pos: Position) = {
507-
val clsSym = defSym.owner
508-
val scalaName = jsInterop.scalaExportName(jsName, false)
509-
510-
// Create symbol for the new exporter method
511-
val expSym = clsSym.newMethodSymbol(scalaName, pos,
512-
Flags.SYNTHETIC | Flags.FINAL)
513-
514-
// Mark the symbol to be a named export
515-
expSym.addAnnotation(JSExportNamedAnnotation)
516-
517-
// Create a single parameter of type Any
518-
val param = expSym.newValueParameter(newTermName("namedArgs"), pos)
519-
param.setInfo(AnyTpe)
520-
521-
// Set method type
522-
expSym.setInfo(MethodType(param :: Nil, AnyClass.tpe))
523-
524-
// Register method to parent
525-
clsSym.info.decls.enter(expSym)
526-
527-
// Placeholder tree
528-
def ph = Ident(Predef_???)
529-
530-
// Create a call to the forwarded method with ??? as args
531-
val sel: Tree = Select(This(clsSym), defSym)
532-
val call = (sel /: defSym.paramss) {
533-
(fun, params) => Apply(fun, List.fill(params.size)(ph))
534-
}
535-
536-
// rhs is a block to prevent boxing of result
537-
typer.typedDefDef(DefDef(expSym, Block(call, ph)))
538-
}
539-
540479
private def genExportDefaultGetter(clsSym: Symbol, trgMethod: Symbol,
541480
exporter: Symbol, paramPos: Int, pos: Position) = {
542481

@@ -613,7 +552,6 @@ trait PrepJSExports { this: PrepJSInterop =>
613552
/** Whether a symbol is an annotation that goes directly on a member */
614553
private lazy val isDirectMemberAnnot = Set[Symbol](
615554
JSExportAnnotation,
616-
JSExportNamedAnnotation,
617555
JSExportTopLevelAnnotation,
618556
JSExportStaticAnnotation
619557
)

0 commit comments

Comments
 (0)