1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
|
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 =>
}
}
}
|