object Types {
abstract sealed class Type
case object AnyType extends Type
case object NothingType extends Type
case object UndefType extends Type
case object BooleanType extends Type
case object IntType extends Type
case object LongType extends Type
case object FloatType extends Type
case object DoubleType extends Type
case object StringType extends Type
case object NullType extends Type
sealed abstract class ReferenceType extends Type
final case class ClassType(className: String) extends ReferenceType
final case class ArrayType(baseClassName: String, dimensions: Int) extends ReferenceType
final case class RecordType(fields: List[RecordType.Field]) extends Type
object RecordType {
final case class Field(name: String, originalName: Option[String],
tpe: Type, mutable: Boolean)
}
case object NoType extends Type
}
sealed abstract class ClassKind
object ClassKind {
case object Class extends ClassKind
case object ModuleClass extends ClassKind
case object Interface extends ClassKind
case object RawJSType extends ClassKind
case object HijackedClass extends ClassKind
case object TraitImpl extends ClassKind
}
object Trees {
import Types._
abstract sealed class Tree
case object EmptyTree extends Tree
sealed trait PropertyName
case class Ident(name: String, originalName: Option[String]) extends PropertyName
object Ident {
def apply(name: String): Ident =
new Ident(name, Some(name))
}
case class VarDef(name: Ident, vtpe: Type, mutable: Boolean, rhs: Tree) extends Tree
case class ParamDef(name: Ident, ptpe: Type, mutable: Boolean) extends Tree
case class Skip() extends Tree
class Block private(val stats: List[Tree]) extends Tree
object Block {
def unapply(block: Block): Some[List[Tree]] = Some(block.stats)
}
case class Labeled(label: Ident, tpe: Type, body: Tree) extends Tree
case class Assign(lhs: Tree, rhs: Tree) extends Tree
case class Return(expr: Tree, label: Option[Ident] = None) extends Tree
case class If(cond: Tree, thenp: Tree, elsep: Tree) extends Tree
case class While(cond: Tree, body: Tree, label: Option[Ident] = None) extends Tree
case class DoWhile(body: Tree, cond: Tree, label: Option[Ident] = None) extends Tree
case class Try(block: Tree, errVar: Ident, handler: Tree, finalizer: Tree) extends Tree
case class Throw(expr: Tree) extends Tree
case class Continue(label: Option[Ident] = None) extends Tree
case class Match(selector: Tree, cases: List[(List[Literal], Tree)], default: Tree) extends Tree
case class Debugger() extends Tree
case class New(cls: ClassType, ctor: Ident, args: List[Tree]) extends Tree
case class LoadModule(cls: ClassType) extends Tree
case class StoreModule(cls: ClassType, value: Tree) extends Tree
case class Select(qualifier: Tree, item: Ident, mutable: Boolean) extends Tree
case class Apply(receiver: Tree, method: Ident, args: List[Tree]) extends Tree
case class StaticApply(receiver: Tree, cls: ClassType, method: Ident, args: List[Tree]) extends Tree
case class TraitImplApply(impl: ClassType, method: Ident, args: List[Tree]) extends Tree
case class UnaryOp(op: Int, lhs: Tree) extends Tree
case class BinaryOp(op: Int, lhs: Tree, rhs: Tree) extends Tree
case class NewArray(tpe: ArrayType, lengths: List[Tree]) extends Tree
case class ArrayValue(tpe: ArrayType, elems: List[Tree]) extends Tree
case class ArrayLength(array: Tree) extends Tree
case class ArraySelect(array: Tree, index: Tree) extends Tree
case class RecordValue(tpe: RecordType, elems: List[Tree]) extends Tree
case class IsInstanceOf(expr: Tree, cls: ReferenceType) extends Tree
case class AsInstanceOf(expr: Tree, cls: ReferenceType) extends Tree
case class Unbox(expr: Tree, charCode: Char) extends Tree
case class GetClass(expr: Tree) extends Tree
case class CallHelper(helper: String, args: List[Tree]) extends Tree
case class JSNew(ctor: Tree, args: List[Tree]) extends Tree
case class JSDotSelect(qualifier: Tree, item: Ident) extends Tree
case class JSBracketSelect(qualifier: Tree, item: Tree) extends Tree
case class JSFunctionApply(fun: Tree, args: List[Tree]) extends Tree
case class JSDotMethodApply(receiver: Tree, method: Ident, args: List[Tree]) extends Tree
case class JSBracketMethodApply(receiver: Tree, method: Tree, args: List[Tree]) extends Tree
case class JSDelete(prop: Tree) extends Tree
case class JSUnaryOp(op: String, lhs: Tree) extends Tree
case class JSBinaryOp(op: String, lhs: Tree, rhs: Tree) extends Tree
case class JSArrayConstr(items: List[Tree]) extends Tree
case class JSObjectConstr(fields: List[(PropertyName, Tree)]) extends Tree
case class JSEnvInfo() extends Tree
sealed trait Literal extends Tree
case class Undefined() extends Literal
case class UndefinedParam() extends Literal
case class Null() extends Literal
case class BooleanLiteral(value: Boolean) extends Literal
case class IntLiteral(value: Int) extends Literal
case class LongLiteral(value: Long) extends Literal
case class FloatLiteral(value: Float) extends Literal
case class DoubleLiteral(value: Double) extends Literal
case class StringLiteral(value: String) extends Literal with PropertyName
case class ClassOf(cls: ReferenceType) extends Literal
case class VarRef(ident: Ident, mutable: Boolean) extends Tree
case class This() extends Tree
case class Closure(captureParams: List[ParamDef], params: List[ParamDef],
body: Tree, captureValues: List[Tree]) extends Tree
case class ClassDef(name: Ident, kind: ClassKind, parent: Option[Ident], ancestors: List[Ident], defs: List[Tree]) extends Tree
case class MethodDef(name: PropertyName, args: List[ParamDef], resultType: Type, body: Tree) extends Tree
case class PropertyDef(name: PropertyName, getterBody: Tree, setterArg: ParamDef, setterBody: Tree) extends Tree
case class ConstructorExportDef(name: String, args: List[ParamDef], body: Tree) extends Tree
case class ModuleExportDef(fullName: String) extends Tree
final class TreeHash(val treeHash: Array[Byte], val posHash: Array[Byte])
}
object Main {
import Trees._
import Types._
private def transform(tree: Tree) = {
val ObjectClass = "O"
tree match {
case VarDef(_, _, _, rhs) =>
case tree: Block =>
case Labeled(ident@Ident(label, _), tpe, body) =>
case Assign(lhs, rhs) =>
case Return(expr, optLabel) =>
case If(cond, thenp, elsep) =>
case While(cond, body, optLabel) =>
case DoWhile(body, cond, None) =>
case Try(block, errVar, EmptyTree, finalizer) =>
case Try(block, errVar@Ident(name, originalName), handler, finalizer) =>
case Throw(expr) =>
case Continue(optLabel) =>
case Match(selector, cases, default) =>
case New(cls, ctor, args) =>
case StoreModule(cls, value) =>
case tree: Select =>
case tree: Apply =>
case tree: StaticApply =>
case tree: TraitImplApply =>
case tree@UnaryOp(_, arg) =>
case tree@BinaryOp(op, lhs, rhs) =>
case NewArray(tpe, lengths) =>
case ArrayValue(tpe, elems) =>
case ArrayLength(array) =>
case ArraySelect(array, index) =>
case RecordValue(tpe, elems) =>
case IsInstanceOf(expr, ClassType(ObjectClass)) =>
case IsInstanceOf(expr, tpe) =>
case AsInstanceOf(expr, ClassType(ObjectClass)) =>
case AsInstanceOf(expr, cls) =>
case Unbox(arg, charCode) =>
case GetClass(expr) =>
case JSNew(ctor, args) =>
case JSDotSelect(qualifier, item) =>
case JSBracketSelect(qualifier, item) =>
case tree: JSFunctionApply =>
case JSDotMethodApply(receiver, method, args) =>
case JSBracketMethodApply(receiver, method, args) =>
case JSDelete(JSDotSelect(obj, prop)) =>
case JSDelete(JSBracketSelect(obj, prop)) =>
case JSUnaryOp(op, lhs) =>
case JSBinaryOp(op, lhs, rhs) =>
case JSArrayConstr(items) =>
case JSObjectConstr(fields) =>
case _: VarRef | _: This =>
case Closure(captureParams, params, body, captureValues) =>
case _: Skip | _: Debugger | _: LoadModule |
_: JSEnvInfo | _: Literal | EmptyTree =>
}
}
}