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
use crate::ast::{FunctionParam, JsxElement, JsxFragment, JsxSelfClosingElement, Statement, TypeAnnotation, TypeParameter};
use core::range::Range;
/// Represents a TypeScript expression.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct Expression {
/// The kind of expression.
pub kind: Box<ExpressionKind>,
/// Source span of the expression.
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
pub span: Range<usize>,
}
impl Expression {
/// Creates a new `Expression`.
pub fn new(kind: ExpressionKind, span: Range<usize>) -> Self {
Self { kind: Box::new(kind), span }
}
/// Gets the span of the expression.
pub fn span(&self) -> Range<usize> {
self.span.clone()
}
}
/// Represents the different kinds of expressions in TypeScript.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ExpressionKind {
/// An identifier.
Identifier(String),
/// A numeric literal.
NumericLiteral(f64),
/// A string literal.
StringLiteral(String),
/// A BigInt literal.
BigIntLiteral(String),
/// A boolean literal.
BooleanLiteral(bool),
/// A null literal.
NullLiteral,
/// A regular expression literal.
RegexLiteral(String),
/// A template string literal.
TemplateString(String),
/// A unary expression.
UnaryExpression {
/// Unary operator.
operator: String,
/// Argument expression.
argument: Box<Expression>,
},
/// An update expression.
UpdateExpression {
/// Update operator.
operator: String,
/// Argument expression.
argument: Box<Expression>,
/// Whether the operator is a prefix.
prefix: bool,
},
/// A binary expression.
BinaryExpression {
/// Left-hand side expression.
left: Box<Expression>,
/// Binary operator.
operator: String,
/// Right-hand side expression.
right: Box<Expression>,
},
/// A conditional (ternary) expression.
ConditionalExpression {
/// Condition expression.
test: Box<Expression>,
/// Expression to evaluate if the condition is true.
consequent: Box<Expression>,
/// Expression to evaluate if the condition is false.
alternate: Box<Expression>,
},
/// A member expression.
MemberExpression {
/// Object expression.
object: Box<Expression>,
/// Property expression.
property: Box<Expression>,
/// Whether the property is computed (using `[]`).
computed: bool,
/// Whether the access is optional (using `?.`).
optional: bool,
},
/// A call expression.
CallExpression {
/// Function to call.
func: Box<Expression>,
/// Arguments to the function call.
args: Vec<Expression>,
},
/// A new expression.
NewExpression {
/// Constructor function to call.
func: Box<Expression>,
/// Arguments to the constructor call.
args: Vec<Expression>,
},
/// An assignment expression.
AssignmentExpression {
/// Left-hand side expression.
left: Box<Expression>,
/// Assignment operator.
operator: String,
/// Right-hand side expression.
right: Box<Expression>,
},
/// An 'as' expression (type assertion).
AsExpression {
/// Expression being asserted.
expression: Box<Expression>,
/// Type annotation being asserted to.
type_annotation: TypeAnnotation,
},
/// An arrow function expression.
ArrowFunction {
/// Type parameters of the arrow function.
type_params: Vec<TypeParameter>,
/// Parameters of the arrow function.
params: Vec<FunctionParam>,
/// Return type of the arrow function.
return_type: Option<TypeAnnotation>,
/// Body of the arrow function.
body: Box<Statement>,
/// Whether the arrow function is async.
async_: bool,
},
/// An object literal.
ObjectLiteral {
/// Properties within the object literal.
properties: Vec<ObjectProperty>,
},
/// An array literal.
ArrayLiteral {
/// Elements within the array literal.
elements: Vec<Expression>,
},
/// A spread element.
SpreadElement(Box<Expression>),
/// An await expression.
AwaitExpression(Box<Expression>),
/// A yield expression.
YieldExpression(Option<Box<Expression>>),
/// An import expression.
ImportExpression {
/// Module specifier being imported.
module_specifier: Box<Expression>,
},
/// A function expression.
FunctionExpression {
/// Optional name of the function.
name: Option<String>,
/// Type parameters of the function.
type_params: Vec<TypeParameter>,
/// Parameters of the function.
params: Vec<FunctionParam>,
/// Return type of the function.
return_type: Option<TypeAnnotation>,
/// Body of the function.
body: Vec<Statement>,
/// Whether the function is async.
async_: bool,
/// Whether the function is a generator.
generator: bool,
},
/// A tagged template expression.
TaggedTemplateExpression {
/// Tag function expression.
tag: Box<Expression>,
/// Template literal expression.
template: Box<Expression>,
},
/// A type assertion expression (e.g., `<Type>expression`).
TypeAssertionExpression {
/// Expression being asserted.
expression: Box<Expression>,
/// Type annotation being asserted to.
type_annotation: TypeAnnotation,
},
/// A non-null expression (e.g., `expression!`).
NonNullExpression(Box<Expression>),
/// A JSX element.
JsxElement(Box<JsxElement>),
/// A JSX fragment.
JsxFragment(Box<JsxFragment>),
/// A self-closing JSX element.
JsxSelfClosingElement(Box<JsxSelfClosingElement>),
}
/// Represents a property in an object literal.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum ObjectProperty {
/// A property declaration.
Property {
/// Name of the property.
name: String,
/// Value of the property.
value: Expression,
/// Whether the property is shorthand.
shorthand: bool,
/// Source span of the property.
#[cfg_attr(feature = "serde", serde(with = "oak_core::serde_range"))]
span: Range<usize>,
},
/// A spread property.
Spread(Expression),
}
/// Represents a literal type.
#[derive(Debug, Clone)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub enum LiteralType {
/// A string literal type.
String(String),
/// A numeric literal type.
Number(f64),
/// A boolean literal type.
Boolean(bool),
/// A BigInt literal type.
BigInt(String),
}