8000 Remove the stat/expr distinction from `Transformers.Transformer`. · scala-js/scala-js@2f0eed8 · GitHub
[go: up one dir, main page]

Skip to content

Commit 2f0eed8

Browse files
committed
Remove the stat/expr distinction from Transformers.Transformer.
Recent changes have all but removed the distinction between statements and expressions in the IR. Notably: * bb4f6da Allow Return arg to be a void if the target Labeled is a void. * cdcff99 Rename NoType to VoidType and print it as "void". Therefore, it made no sense anymore that `Transformer.transform` had an `isStat` argument. In fact, the first of the two commits mentionned above semi-broke the semantics of that argument anyway. Moreover, `isStat` was never *used* in our codebase (only forwarded everywhere for no reason). The only exception was a deserialization hack for IR <= 1.5. This one was already hacking around the fact the IR produced back then was not well-typed. See #4442 for context. We now remove that parameter everywhere. It makes the deserialization hack a bit more verbose, but everything else becomes simpler.
1 parent c05ec0b commit 2f0eed8

File tree

10 files changed

+205
-193
lines changed

10 files changed

+205
-193
lines changed

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

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1107,19 +1107,19 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
11071107

11081108
// After the super call, substitute `selfRef` for `This()`
11091109
val afterSuper = new ir.Transformers.Transformer {
1110-
override def transform(tree: js.Tree, isStat: Boolean): js.Tree = tree match {
1110+
override def transform(tree: js.Tree): js.Tree = tree match {
11111111
case js.This() =>
11121112
selfRef(tree.pos)
11131113

11141114
// Don't traverse closure boundaries
11151115
case closure: js.Closure =>
1116-
val newCaptureValues = closure.captureValues.map(transformExpr)
1116+
val newCaptureValues = transformTrees(closure.captureValues)
11171117
closure.copy(captureValues = newCaptureValues)(closure.pos)
11181118

11191119
case tree =>
1120-
super.transform(tree, isStat)
1120+
super.transform(tree)
11211121
}
1122-
}.transformStats(ctorBody.afterSuper)
1122+
}.transformTrees(ctorBody.afterSuper)
11231123

11241124
beforeSuper ::: superCall ::: afterSuper
11251125
}
@@ -2170,20 +2170,18 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
21702170
js.ParamDef(name, originalName, ptpe, newMutable(name.name, mutable))(p.pos)
21712171
}
21722172
val transformer = new ir.Transformers.Transformer {
2173-
override def transform(tree: js.Tree, isStat: Boolean): js.Tree = tree match {
2173+
override def transform(tree: js.Tree): js.Tree = tree match {
21742174
case js.VarDef(name, originalName, vtpe, mutable, rhs) =>
2175-
assert(isStat, s"found a VarDef in expression position at ${tree.pos}")
21762175
super.transform(js.VarDef(name, originalName, vtpe,
2177-
newMutable(name.name, mutable), rhs)(tree.pos), isStat)
2176+
newMutable(name.name, mutable), rhs)(tree.pos))
21782177
case js.Closure(arrow, captureParams, params, restParam, body, captureValues) =>
21792178
js.Closure(arrow, captureParams, params, restParam, body,
2180-
captureValues.map(transformExpr))(tree.pos)
2179+
transformTrees(captureValues))(tree.pos)
21812180
case _ =>
2182-
super.transform(tree, isStat)
2181+
super.transform(tree)
21832182
}
21842183
}
2185-
val newBody = body.map(
2186-
b => transformer.transform(b, isStat = resultType == jstpe.VoidType))
2184+
val newBody = transformer.transformTreeOpt(body)
21872185
js.MethodDef(flags, methodName, originalName, newParams, resultType,
21882186
newBody)(methodDef.optimizerHints, Unversioned)(methodDef.pos)
21892187
}
@@ -2208,18 +2206,17 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
22082206
js.ParamDef(name, originalName, newType(name, ptpe), mutable)(p.pos)
22092207
}
22102208
val transformer = new ir.Transformers.Transformer {
2211-
override def transform(tree: js.Tree, isStat: Boolean): js.Tree = tree match {
2209+
override def transform(tree: js.Tree): js.Tree = tree match {
22122210
case tree @ js.VarRef(name) =>
22132211
js.VarRef(name)(newType(name, tree.tpe))(tree.pos)
22142212
case js.Closure(arrow, captureParams, params, restParam, body, captureValues) =>
22152213
js.Closure(arrow, captureParams, params, restParam, body,
2216-
captureValues.map(transformExpr))(tree.pos)
2214+
transformTrees(captureValues))(tree.pos)
22172215
case _ =>
2218-
super.transform(tree, isStat)
2216+
super.transform(tree)
22192217
}
22202218
}
2221-
val newBody = body.map(
2222-
b => transformer.transform(b, isStat = resultType == jstpe.VoidType))
2219+
val newBody = transformer.transformTreeOpt(body)
22232220
js.MethodDef(flags, methodName, originalName, newParams, resultType,
22242221
newBody)(methodDef.optimizerHints, Unversioned)(methodDef.pos)
22252222
}
@@ -7282,7 +7279,7 @@ abstract class GenJSCode[G <: Global with Singleton](val global: G)
72827279

72837280
def traverse(traverser: ir.Traversers.Traverser): Unit = ()
72847281

7285-
def transform(transformer: ir.Transformers.Transformer, isStat: Boolean)(
7282+
def transform(transformer: ir.Transformers.Transformer)(
72867283
implicit pos: ir.Position): js.Tree = {
72877284
js.Transient(this)
72887285
}

ir/shared/src/main/scala/org/scalajs/ir/Serializers.scala

Lines changed: 63 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,15 +1645,15 @@ object Serializers {
16451645
* We must replace those occurrences with a `Class_name` as well.
16461646
*/
16471647
val transformer = new Transformers.Transformer {
1648-
override def transform(tree: Tree, isStat: Boolean): Tree = tree match {
1648+
override def transform(tree: Tree): Tree = tree match {
16491649
case JSSelect(_, StringLiteral("name")) =>
16501650
implicit val pos = tree.pos
16511651
UnaryOp(UnaryOp.Class_name, thisJLClass)
16521652
case _ =>
1653-
super.transform(tree, isStat)
1653+
super.transform(tree)
16541654
}
16551655
}
1656-
transformer.transform(method.body.get, isStat = method.resultType == VoidType)
1656+
transformer.transform(method.body.get)
16571657
}
16581658

16591659
val newOptimizerHints =
@@ -2065,40 +2065,69 @@ object Serializers {
20652065
JSNativeMemberDef(flags, name, jsNativeLoadSpec)
20662066
}
20672067

2068-
private def bodyHack5(body: Tree, isStat: Boolean): Tree = {
2069-
if (!hacks.use5) {
2070-
body
2071-
} else {
2072-
/* #4442 and #4601: Patch Labeled, If, Match and TryCatch nodes in
2073-
* statement position to have type VoidType. These 4 nodes are the
2074-
* control structures whose result type is explicitly specified (and
2075-
* not derived from their children like Block or TryFinally, or
2076-
* constant like While).
2077-
*/
2078-
new Transformers.Transformer {
2079-
override def transform(tree: Tree, isStat: Boolean): Tree = {
2080-
val newTree = super.transform(tree, isStat)
2081-
if (isStat && newTree.tpe != VoidType) {
2082-
newTree match {
2083-
case Labeled(label, _, body) =>
2084-
Labeled(label, VoidType, body)(newTree.pos)
2085-
case If(cond, thenp, elsep) =>
2086-
If(cond, thenp, elsep)(VoidType)(newTree.pos)
2087-
case Match(selector, cases, default) =>
2088-
Match(selector, cases, default)(VoidType)(newTree.pos)
2089-
case TryCatch(block, errVar, errVarOriginalName, handler) =>
2090-
TryCatch(block, errVar, errVarOriginalName, handler)(VoidType)(newTree.pos)
2091-
case _ =>
2092-
newTree
2093-
}
2094-
} else {
2095-
newTree
2096-
}
2097-
}
2098-
}.transform(body, isStat)
2068+
/* #4442 and #4601: Patch Labeled, If, Match and TryCatch nodes in
2069+
* statement position to have type VoidType. These 4 nodes are the
2070+
* control structures whose result type is explicitly specified (and
2071+
* not derived from their children like Block or TryFinally, or
2072+
* constant like While).
2073+
*/
2074+
private object BodyHack5Transformer extends Transformers.Transformer {
2075+
def transformStat(tree: Tree): Tree = {
2076+
implicit val pos = tree.pos
2077+
2078+
tree match {
2079+
// Nodes that we actually need to alter
2080+
case Labeled(label, _, body) =>
2081+
Labeled(label, VoidType, transformStat(body))
2082+
case If(cond, thenp, elsep) =>
2083+
If(transform(cond), transformStat(thenp), transformStat(elsep))(VoidType)
2084+
case Match(selector, cases, default) =>
2085+
Match(transform(selector), cases.map(c => (c._1, transformStat(c._2))),
2086+
transformStat(default))(VoidType)
2087+
case TryCatch(block, errVar, errVarOriginalName, handler) =>
2088+
TryCatch(transformStat(block), errVar, errVarOriginalName,
2089+
transformStat(handler))(VoidType)
2090+
2091+
// Nodes for which we need to forward the statement position
2092+
case Block(stats) =>
2093+
Block(stats.map(transformStat(_)))
2094+
case TryFinally(block, finalizer) =>
2095+
Block(transformStat(block), transformStat(finalizer))
2096+
2097+
// For everything else, delegate to transform
2098+
case _ =>
2099+
transform(tree)
2100+
}
20992101
}
2102+
2103+
override def transform(tree: Tree): Tree = {
2104+
implicit val pos = tree.pos
2105+
2106+
tree match {
2107+
// Nodes that force a statement position for some of their parts
2108+
case Block(stats) =>
2109+
Block(stats.init.map(transformStat(_)), transform(stats.last))
2110+
case While(cond, body) =>
2111+
While(transform(cond), transformStat(body))
2112+
case ForIn(obj, keyVar, keyVarOriginalName, body) =>
2113+
ForIn(transform(obj), keyVar, keyVarOriginalName, transformStat(body))
2114+
case TryFinally(block, finalizer) =>
2115+
TryFinally(transform(block), transformStat(finalizer))
2116+
2117+
case _ =>
2118+
super.transform(tree)
2119+
}
2120+
}
2121+
2122+
def transform(tree: Tree, isStat: Boolean): Tree =
2123+
if (isStat) transformStat(tree)
2124+
else transform(tree)
21002125
}
21012126

2127+
private def bodyHack5(body: Tree, isStat: Boolean): Tree =
2128+
if (!hacks.use5) body
2129+
else BodyHack5Transformer.transform(body, isStat)
2130+
21022131
private def bodyHack5Expr(body: Tree): Tree = bodyHack5(body, isStat = false)
21032132

21042133
def readTopLevelExportDef(): TopLevelExportDef = {

0 commit comments

Comments
 (0)
0