summaryrefslogtreecommitdiff
path: root/examples/scala-js/ir/src/main/scala/scala/scalajs/ir/Transformers.scala
diff options
context:
space:
mode:
Diffstat (limited to 'examples/scala-js/ir/src/main/scala/scala/scalajs/ir/Transformers.scala')
-rw-r--r--examples/scala-js/ir/src/main/scala/scala/scalajs/ir/Transformers.scala218
1 files changed, 218 insertions, 0 deletions
diff --git a/examples/scala-js/ir/src/main/scala/scala/scalajs/ir/Transformers.scala b/examples/scala-js/ir/src/main/scala/scala/scalajs/ir/Transformers.scala
new file mode 100644
index 0000000..5e4f40c
--- /dev/null
+++ b/examples/scala-js/ir/src/main/scala/scala/scalajs/ir/Transformers.scala
@@ -0,0 +1,218 @@
+/* __ *\
+** ________ ___ / / ___ __ ____ Scala.js IR **
+** / __/ __// _ | / / / _ | __ / // __/ (c) 2014, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ |/_// /_\ \ http://scala-js.org/ **
+** /____/\___/_/ |_/____/_/ | |__/ /____/ **
+** |/____/ **
+\* */
+
+
+package scala.scalajs.ir
+
+import Trees._
+
+object Transformers {
+
+ abstract class Transformer {
+ final def transformStat(tree: Tree): Tree =
+ transform(tree, isStat = true)
+
+ final def transformExpr(tree: Tree): Tree =
+ transform(tree, isStat = false)
+
+ def transform(tree: Tree, isStat: Boolean): Tree = {
+ implicit val pos = tree.pos
+
+ tree match {
+ // Definitions
+
+ case VarDef(ident, vtpe, mutable, rhs) =>
+ VarDef(ident, vtpe, mutable, transformExpr(rhs))
+
+ // Control flow constructs
+
+ case Block(stats :+ expr) =>
+ Block(stats.map(transformStat) :+ transform(expr, isStat))
+
+ case Labeled(label, tpe, body) =>
+ Labeled(label, tpe, transform(body, isStat))
+
+ case Assign(lhs, rhs) =>
+ Assign(transformExpr(lhs), transformExpr(rhs))
+
+ case Return(expr, label) =>
+ Return(transformExpr(expr), label)
+
+ case If(cond, thenp, elsep) =>
+ If(transformExpr(cond), transform(thenp, isStat),
+ transform(elsep, isStat))(tree.tpe)
+
+ case While(cond, body, label) =>
+ While(transformExpr(cond), transformStat(body), label)
+
+ case DoWhile(body, cond, label) =>
+ DoWhile(transformStat(body), transformExpr(cond), label)
+
+ case Try(block, errVar, handler, finalizer) =>
+ Try(transform(block, isStat), errVar, transform(handler, isStat),
+ transformStat(finalizer))(tree.tpe)
+
+ case Throw(expr) =>
+ Throw(transformExpr(expr))
+
+ case Match(selector, cases, default) =>
+ Match(transformExpr(selector),
+ cases map (c => (c._1, transform(c._2, isStat))),
+ transform(default, isStat))(tree.tpe)
+
+ // Scala expressions
+
+ case New(cls, ctor, args) =>
+ New(cls, ctor, args map transformExpr)
+
+ case StoreModule(cls, value) =>
+ StoreModule(cls, transformExpr(value))
+
+ case Select(qualifier, item, mutable) =>
+ Select(transformExpr(qualifier), item, mutable)(tree.tpe)
+
+ case Apply(receiver, method, args) =>
+ Apply(transformExpr(receiver), method,
+ args map transformExpr)(tree.tpe)
+
+ case StaticApply(receiver, cls, method, args) =>
+ StaticApply(transformExpr(receiver), cls, method,
+ args map transformExpr)(tree.tpe)
+
+ case TraitImplApply(impl, method, args) =>
+ TraitImplApply(impl, method, args map transformExpr)(tree.tpe)
+
+ case UnaryOp(op, lhs) =>
+ UnaryOp(op, transformExpr(lhs))
+
+ case BinaryOp(op, lhs, rhs) =>
+ BinaryOp(op, transformExpr(lhs), transformExpr(rhs))
+
+ case NewArray(tpe, lengths) =>
+ NewArray(tpe, lengths map transformExpr)
+
+ case ArrayValue(tpe, elems) =>
+ ArrayValue(tpe, elems map transformExpr)
+
+ case ArrayLength(array) =>
+ ArrayLength(transformExpr(array))
+
+ case ArraySelect(array, index) =>
+ ArraySelect(transformExpr(array), transformExpr(index))(tree.tpe)
+
+ case RecordValue(tpe, elems) =>
+ RecordValue(tpe, elems map transformExpr)
+
+ case IsInstanceOf(expr, cls) =>
+ IsInstanceOf(transformExpr(expr), cls)
+
+ case AsInstanceOf(expr, cls) =>
+ AsInstanceOf(transformExpr(expr), cls)
+
+ case Unbox(expr, charCode) =>
+ Unbox(transformExpr(expr), charCode)
+
+ case GetClass(expr) =>
+ GetClass(transformExpr(expr))
+
+ case CallHelper(helper, args) =>
+ CallHelper(helper, args map transformExpr)(tree.tpe)
+
+ // JavaScript expressions
+
+ case JSNew(ctor, args) =>
+ JSNew(transformExpr(ctor), args map transformExpr)
+
+ case JSDotSelect(qualifier, item) =>
+ JSDotSelect(transformExpr(qualifier), item)
+
+ case JSBracketSelect(qualifier, item) =>
+ JSBracketSelect(transformExpr(qualifier), transformExpr(item))
+
+ case JSFunctionApply(fun, args) =>
+ JSFunctionApply(transformExpr(fun), args map transformExpr)
+
+ case JSDotMethodApply(receiver, method, args) =>
+ JSDotMethodApply(transformExpr(receiver), method,
+ args map transformExpr)
+
+ case JSBracketMethodApply(receiver, method, args) =>
+ JSBracketMethodApply(transformExpr(receiver), transformExpr(method),
+ args map transformExpr)
+
+ case JSDelete(prop) =>
+ JSDelete(transformExpr(prop))
+
+ case JSUnaryOp(op, lhs) =>
+ JSUnaryOp(op, transformExpr(lhs))
+
+ case JSBinaryOp(op, lhs, rhs) =>
+ JSBinaryOp(op, transformExpr(lhs), transformExpr(rhs))
+
+ case JSArrayConstr(items) =>
+ JSArrayConstr(items map transformExpr)
+
+ case JSObjectConstr(fields) =>
+ JSObjectConstr(fields map {
+ case (name, value) => (name, transformExpr(value))
+ })
+
+ // Atomic expressions
+
+ case Closure(captureParams, params, body, captureValues) =>
+ Closure(captureParams, params, transformExpr(body),
+ captureValues.map(transformExpr))
+
+ // Trees that need not be transformed
+
+ case _:Skip | _:Continue | _:LoadModule | _:JSEnvInfo |
+ _:Literal | _:VarRef | _:This | EmptyTree =>
+ tree
+
+ case _ =>
+ sys.error(s"Invalid tree in transform() of class ${tree.getClass}")
+ }
+ }
+ }
+
+ abstract class ClassTransformer extends Transformer {
+ def transformClassDef(tree: ClassDef): ClassDef = {
+ val ClassDef(name, kind, parent, ancestors, defs) = tree
+ ClassDef(name, kind, parent, ancestors, defs.map(transformDef))(tree.pos)
+ }
+
+ def transformDef(tree: Tree): Tree = {
+ implicit val pos = tree.pos
+
+ tree match {
+ case VarDef(name, vtpe, mutable, rhs) =>
+ VarDef(name, vtpe, mutable, transformExpr(rhs))
+
+ case MethodDef(name, args, resultType, body) =>
+ MethodDef(name, args, resultType, transformStat(body))(None)
+
+ case PropertyDef(name, getterBody, setterArg, setterBody) =>
+ PropertyDef(
+ name,
+ transformStat(getterBody),
+ setterArg,
+ transformStat(setterBody))
+
+ case ConstructorExportDef(fullName, args, body) =>
+ ConstructorExportDef(fullName, args, transformStat(body))
+
+ case ModuleExportDef(_) =>
+ tree
+
+ case _ =>
+ sys.error(s"Invalid tree in transformDef() of class ${tree.getClass}")
+ }
+ }
+ }
+
+}