-
Notifications
You must be signed in to change notification settings - Fork 51
/
Node.kt
456 lines (438 loc) · 14.8 KB
/
Node.kt
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
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
package kastree.ast
sealed class Node {
var tag: Any? = null
interface WithAnnotations {
val anns: List<Modifier.AnnotationSet>
}
interface WithModifiers : WithAnnotations {
val mods: List<Modifier>
override val anns: List<Modifier.AnnotationSet> get() = mods.mapNotNull { it as? Modifier.AnnotationSet }
}
interface Entry : WithAnnotations {
val pkg: Package?
val imports: List<Import>
}
data class File(
override val anns: List<Modifier.AnnotationSet>,
override val pkg: Package?,
override val imports: List<Import>,
val decls: List<Decl>
) : Node(), Entry
data class Script(
override val anns: List<Modifier.AnnotationSet>,
override val pkg: Package?,
override val imports: List<Import>,
val exprs: List<Expr>
) : Node(), Entry
data class Package(
override val mods: List<Modifier>,
val names: List<String>
) : Node(), WithModifiers
data class Import(
val names: List<String>,
val wildcard: Boolean,
val alias: String?
) : Node()
sealed class Decl : Node() {
data class Structured(
override val mods: List<Modifier>,
val form: Form,
val name: String,
val typeParams: List<TypeParam>,
val primaryConstructor: PrimaryConstructor?,
val parentAnns: List<Modifier.AnnotationSet>,
val parents: List<Parent>,
val typeConstraints: List<TypeConstraint>,
// TODO: Can include primary constructor
val members: List<Decl>
) : Decl(), WithModifiers {
enum class Form {
CLASS, ENUM_CLASS, INTERFACE, OBJECT, COMPANION_OBJECT
}
sealed class Parent : Node() {
data class CallConstructor(
val type: TypeRef.Simple,
val typeArgs: List<Node.Type?>,
val args: List<ValueArg>,
val lambda: Expr.Call.TrailLambda?
) : Parent()
data class Type(
val type: TypeRef.Simple,
val by: Expr?
) : Parent()
}
data class PrimaryConstructor(
override val mods: List<Modifier>,
val params: List<Func.Param>
) : Node(), WithModifiers
}
data class Init(val block: Block) : Decl()
data class Func(
override val mods: List<Modifier>,
val typeParams: List<TypeParam>,
val receiverType: Type?,
// Name not present on anonymous functions
val name: String?,
val paramTypeParams: List<TypeParam>,
val params: List<Func.Param>,
val type: Type?,
val typeConstraints: List<TypeConstraint>,
val body: Body?
) : Decl(), WithModifiers {
data class Param(
override val mods: List<Modifier>,
val readOnly: Boolean?,
val name: String,
// Type can be null for anon functions
val type: Type?,
val default: Expr?
) : Node(), WithModifiers
sealed class Body : Node() {
data class Block(val block: Node.Block) : Body()
data class Expr(val expr: Node.Expr) : Body()
}
}
data class Property(
override val mods: List<Modifier>,
val readOnly: Boolean,
val typeParams: List<TypeParam>,
val receiverType: Type?,
// Always at least one, more than one is destructuring, null is underscore in destructure
val vars: List<Var?>,
val typeConstraints: List<TypeConstraint>,
val delegated: Boolean,
val expr: Expr?,
val accessors: Accessors?
) : Decl(), WithModifiers {
data class Var(
val name: String,
val type: Type?
) : Node()
data class Accessors(
val first: Accessor,
val second: Accessor?
) : Node()
sealed class Accessor : Node(), WithModifiers {
data class Get(
override val mods: List<Modifier>,
val type: Type?,
val body: Func.Body?
) : Accessor()
data class Set(
override val mods: List<Modifier>,
val paramMods: List<Modifier>,
val paramName: String?,
val paramType: Type?,
val body: Func.Body?
) : Accessor()
}
}
data class TypeAlias(
override val mods: List<Modifier>,
val name: String,
val typeParams: List<TypeParam>,
val type: Type
) : Decl(), WithModifiers
data class Constructor(
override val mods: List<Modifier>,
val params: List<Func.Param>,
val delegationCall: DelegationCall?,
val block: Block?
) : Decl(), WithModifiers {
data class DelegationCall(
val target: DelegationTarget,
val args: List<ValueArg>
) : Node()
enum class DelegationTarget { THIS, SUPER }
}
data class EnumEntry(
override val mods: List<Modifier>,
val name: String,
val args: List<ValueArg>,
val members: List<Decl>
) : Decl(), WithModifiers
}
data class TypeParam(
override val mods: List<Modifier>,
val name: String,
val type: TypeRef?
) : Node(), WithModifiers
data class TypeConstraint(
override val anns: List<Modifier.AnnotationSet>,
val name: String,
val type: Type
) : Node(), WithAnnotations
sealed class TypeRef : Node() {
data class Paren(
override val mods: List<Modifier>,
val type: TypeRef
) : TypeRef(), WithModifiers
data class Func(
val receiverType: Type?,
val params: List<Param>,
val type: Type
) : TypeRef() {
data class Param(
val name: String?,
val type: Type
) : Node()
}
data class Simple(
val pieces: List<Piece>
) : TypeRef() {
data class Piece(
val name: String,
// Null means any
val typeParams: List<Type?>
) : Node()
}
data class Nullable(val type: TypeRef) : TypeRef()
data class Dynamic(val _unused_: Boolean = false) : TypeRef()
}
data class Type(
override val mods: List<Modifier>,
val ref: TypeRef
) : Node(), WithModifiers
data class ValueArg(
val name: String?,
val asterisk: Boolean,
val expr: Expr
) : Node()
sealed class Expr : Node() {
data class If(
val expr: Expr,
val body: Expr,
val elseBody: Expr?
) : Expr()
data class Try(
val block: Block,
val catches: List<Catch>,
val finallyBlock: Block?
) : Expr() {
data class Catch(
override val anns: List<Modifier.AnnotationSet>,
val varName: String,
val varType: TypeRef.Simple,
val block: Block
) : Node(), WithAnnotations
}
data class For(
override val anns: List<Modifier.AnnotationSet>,
// More than one means destructure, null means underscore
val vars: List<Decl.Property.Var?>,
val inExpr: Expr,
val body: Expr
) : Expr(), WithAnnotations
data class While(
val expr: Expr,
val body: Expr,
val doWhile: Boolean
) : Expr()
data class BinaryOp(
val lhs: Expr,
val oper: Oper,
val rhs: Expr
) : Expr() {
sealed class Oper : Node() {
data class Infix(val str: String) : Oper()
data class Token(val token: BinaryOp.Token) : Oper()
}
enum class Token(val str: String) {
MUL("*"), DIV("/"), MOD("%"), ADD("+"), SUB("-"),
IN("in"), NOT_IN("!in"),
GT(">"), GTE(">="), LT("<"), LTE("<="),
EQ("=="), NEQ("!="),
ASSN("="), MUL_ASSN("*="), DIV_ASSN("/="), MOD_ASSN("%="), ADD_ASSN("+="), SUB_ASSN("-="),
OR("||"), AND("&&"), ELVIS("?:"), RANGE(".."),
DOT("."), DOT_SAFE("?."), SAFE("?")
}
}
data class UnaryOp(
val expr: Expr,
val oper: Oper,
val prefix: Boolean
) : Expr() {
data class Oper(val token: Token) : Node()
enum class Token(val str: String) {
NEG("-"), POS("+"), INC("++"), DEC("--"), NOT("!"), NULL_DEREF("!!")
}
}
data class TypeOp(
val lhs: Expr,
val oper: Oper,
val rhs: Type
) : Expr() {
data class Oper(val token: Token) : Node()
enum class Token(val str: String) {
AS("as"), AS_SAFE("as?"), COL(":"), IS("is"), NOT_IS("!is")
}
}
sealed class DoubleColonRef : Expr() {
abstract val recv: Recv?
data class Callable(
override val recv: Recv?,
val name: String
) : DoubleColonRef()
data class Class(
override val recv: Recv?
) : DoubleColonRef()
sealed class Recv : Node() {
data class Expr(val expr: Node.Expr) : Recv()
data class Type(
val type: TypeRef.Simple,
val questionMarks: Int
) : Recv()
}
}
data class Paren(
val expr: Expr
) : Expr()
data class StringTmpl(
val elems: List<Elem>,
val raw: Boolean
) : Expr() {
sealed class Elem : Node() {
data class Regular(val str: String) : Elem()
data class ShortTmpl(val str: String) : Elem()
data class UnicodeEsc(val digits: String) : Elem()
data class RegularEsc(val char: Char) : Elem()
data class LongTmpl(val expr: Expr) : Elem()
}
}
data class Const(
val value: String,
val form: Form
) : Expr() {
enum class Form { BOOLEAN, CHAR, INT, FLOAT, NULL }
}
data class Brace(
val params: List<Param>,
val block: Block?
) : Expr() {
data class Param(
// Multiple means destructure, null means underscore
val vars: List<Decl.Property.Var?>,
val destructType: Type?
) : Expr()
}
data class This(
val label: String?
) : Expr()
data class Super(
val typeArg: Type?,
val label: String?
) : Expr()
data class When(
val expr: Expr?,
val entries: List<Entry>
) : Expr() {
data class Entry(
val conds: List<Cond>,
val body: Expr
) : Node()
sealed class Cond : Node() {
data class Expr(val expr: Node.Expr) : Cond()
data class In(
val expr: Node.Expr,
val not: Boolean
) : Cond()
data class Is(
val type: Type,
val not: Boolean
) : Cond()
}
}
data class Object(
val parents: List<Decl.Structured.Parent>,
val members: List<Decl>
) : Expr()
data class Throw(
val expr: Expr
) : Expr()
data class Return(
val label: String?,
val expr: Expr?
) : Expr()
data class Continue(
val label: String?
) : Expr()
data class Break(
val label: String?
) : Expr()
data class CollLit(
val exprs: List<Expr>
) : Expr()
data class Name(
val name: String
) : Expr()
data class Labeled(
val label: String,
val expr: Expr
) : Expr()
data class Annotated(
override val anns: List<Modifier.AnnotationSet>,
val expr: Expr
) : Expr(), WithAnnotations
data class Call(
val expr: Expr,
val typeArgs: List<Type?>,
val args: List<ValueArg>,
val lambda: TrailLambda?
) : Expr() {
data class TrailLambda(
override val anns: List<Modifier.AnnotationSet>,
val label: String?,
val func: Brace
) : Node(), WithAnnotations
}
data class ArrayAccess(
val expr: Expr,
val indices: List<Expr>
) : Expr()
data class AnonFunc(
val func: Decl.Func
) : Expr()
// This is only present for when expressions and labeled expressions
data class Property(
val decl: Decl.Property
) : Expr()
}
data class Block(val stmts: List<Stmt>) : Node()
sealed class Stmt : Node() {
data class Decl(val decl: Node.Decl) : Stmt()
data class Expr(val expr: Node.Expr) : Stmt()
}
sealed class Modifier : Node() {
data class AnnotationSet(
val target: Target?,
val anns: List<Annotation>
) : Modifier() {
enum class Target {
FIELD, FILE, PROPERTY, GET, SET, RECEIVER, PARAM, SETPARAM, DELEGATE
}
data class Annotation(
val names: List<String>,
val typeArgs: List<Type>,
val args: List<ValueArg>
) : Node()
}
data class Lit(val keyword: Keyword) : Modifier()
enum class Keyword {
ABSTRACT, FINAL, OPEN, ANNOTATION, SEALED, DATA, OVERRIDE, LATEINIT, INNER,
PRIVATE, PROTECTED, PUBLIC, INTERNAL,
IN, OUT, NOINLINE, CROSSINLINE, VARARG, REIFIED,
TAILREC, OPERATOR, INFIX, INLINE, EXTERNAL, SUSPEND, CONST,
ACTUAL, EXPECT
}
}
sealed class Extra : Node() {
data class BlankLines(
val count: Int
) : Extra()
data class Comment(
val text: String,
val startsLine: Boolean,
val endsLine: Boolean
) : Extra()
}
}