diff options
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.scala | 218 |
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}") + } + } + } + +} |