[rust] Update swc->estree->hir conversion for new estree
The previous PRs to make `estree` use codegen broke the swc->estree and estree->hir conversions. This PR updates those conversions so everything builds now.
Joe Savona committed
Jul 11, 2023 at 11:52 UTC
bdd50d522dd44e976dadbfe890856a46633b400b
11 files changed
+183
-130
compiler/forget/crates/build-hir/src/build.rs
+55
-32
@@ -1,7 +1,8 @@
1
use bumpalo::collections::{String, Vec};
2
use estree::{
3
- AssignmentTarget, BinaryExpression, ExpressionLike, ForInit, ForStatement, FunctionDeclaration,
4
- IfStatement, Literal, LiteralValue, Pattern, Statement, VariableDeclarationKind,
3
+ AssignmentTarget, BinaryExpression, BlockStatement, Expression, ForInit, ForStatement,
4
+ FunctionDeclaration, IfStatement, JsValue, Literal, Pattern, Statement,
5
+ VariableDeclarationKind,
6
};
7
use hir::{
8
ArrayElement, BlockKind, BranchTerminal, Environment, ForTerminal, Function, GotoKind,
@@ -27,7 +28,21 @@ pub fn build<'a>(
28
) -> Result<Function<'a>, BuildDiagnostic> {
29
let mut builder = Builder::new(environment);
30
30
- lower_statement(environment, &mut builder, fun.body.unwrap(), None)?;
31
+ match fun.function.body {
32
+ Some(estree::FunctionBody::BlockStatement(body)) => {
33
+ lower_block_statement(environment, &mut builder, *body, None)?
34
+ }
35
+ Some(estree::FunctionBody::Expression(body)) => {
36
+ lower_expression_to_temporary(environment, &mut builder, body)?;
37
+ }
38
+ None => {
39
+ return Err(BuildDiagnostic::new(
40
+ DiagnosticError::EmptyFunction,
41
+ ErrorSeverity::InvalidSyntax,
42
+ fun.range,
43
+ ));
44
+ }
45
+ }
46
47
// In case the function did not explicitly return, terminate the final
48
// block with an explicit `return undefined`. If the function *did* return,
@@ -49,11 +64,23 @@ pub fn build<'a>(
64
let body = builder.build()?;
65
Ok(Function {
66
body,
52
- is_async: fun.is_async,
53
- is_generator: fun.is_generator,
67
+ is_async: fun.function.is_async,
68
+ is_generator: fun.function.is_generator,
69
})
70
}
71
72
+fn lower_block_statement<'a>(
73
+ env: &'a Environment<'a>,
74
+ builder: &mut Builder<'a>,
75
+ stmt: BlockStatement,
76
+ label: Option<String<'a>>,
77
+) -> Result<(), BuildDiagnostic> {
78
+ for stmt in stmt.body {
79
+ lower_statement(env, builder, stmt, None)?;
80
+ }
81
+ Ok(())
82
+}
83
+
84
/// Convert a statement to HIR. This will often result in multiple instructions and blocks
85
/// being created as statements often describe control flow.
86
fn lower_statement<'a>(
@@ -64,9 +91,7 @@ fn lower_statement<'a>(
91
) -> Result<(), BuildDiagnostic> {
92
match stmt {
93
Statement::BlockStatement(stmt) => {
67
- for stmt in stmt.body {
68
- lower_statement(env, builder, stmt, None)?;
69
- }
94
+ lower_block_statement(env, builder, *stmt, label)?;
95
}
96
Statement::BreakStatement(stmt) => {
97
let block = builder.resolve_break(stmt.label.as_ref())?;
@@ -292,7 +317,7 @@ fn lower_statement<'a>(
317
fn lower_expression_to_temporary<'a>(
318
env: &'a Environment<'a>,
319
builder: &mut Builder<'a>,
295
- expr: ExpressionLike,
320
+ expr: Expression,
321
) -> Result<Place<'a>, BuildDiagnostic> {
322
let value = lower_expression(env, builder, expr)?;
323
Ok(lower_value_to_temporary(env, builder, value))
@@ -305,10 +330,10 @@ fn lower_expression_to_temporary<'a>(
330
fn lower_expression<'a>(
331
env: &'a Environment<'a>,
332
builder: &mut Builder<'a>,
308
- expr: ExpressionLike,
333
+ expr: Expression,
334
) -> Result<InstructionValue<'a>, BuildDiagnostic> {
335
Ok(match expr {
311
- ExpressionLike::Identifier(expr) => {
336
+ Expression::Identifier(expr) => {
337
// TODO: handle unbound variables
338
let binding = builder.resolve_binding(&expr)?;
339
match binding {
@@ -324,24 +349,31 @@ fn lower_expression<'a>(
349
}),
350
}
351
}
327
- ExpressionLike::Literal(expr) => InstructionValue::Primitive(hir::Primitive {
352
+ Expression::Literal(expr) => InstructionValue::Primitive(hir::Primitive {
353
value: lower_primitive(env, builder, *expr),
354
}),
330
- ExpressionLike::ArrayExpression(expr) => {
355
+ Expression::ArrayExpression(expr) => {
356
let mut elements = Vec::with_capacity_in(expr.elements.len(), &env.allocator);
357
for expr in expr.elements {
358
let element = match expr {
334
- ExpressionLike::SpreadElement(expr) => ArrayElement::Spread(
335
- lower_expression_to_temporary(env, builder, expr.argument)?,
359
+ Some(estree::ExpressionOrSpread::SpreadElement(expr)) => {
360
+ Some(ArrayElement::Spread(lower_expression_to_temporary(
361
+ env,
362
+ builder,
363
+ expr.argument,
364
+ )?))
365
+ }
366
+ Some(estree::ExpressionOrSpread::Expression(expr)) => Some(
367
+ ArrayElement::Place(lower_expression_to_temporary(env, builder, expr)?),
368
),
337
- _ => ArrayElement::Place(lower_expression_to_temporary(env, builder, expr)?),
369
+ None => None,
370
};
371
elements.push(element);
372
}
373
InstructionValue::Array(hir::Array { elements })
374
}
375
344
- ExpressionLike::AssignmentExpression(expr) => match expr.operator {
376
+ Expression::AssignmentExpression(expr) => match expr.operator {
377
estree::AssignmentOperator::Equals => {
378
let right = lower_expression_to_temporary(env, builder, expr.right)?;
379
lower_assignment(env, builder, InstructionKind::Reassign, expr.left, right)?
@@ -349,7 +381,7 @@ fn lower_expression<'a>(
381
_ => todo!("lower assignment expr {:#?}", expr),
382
},
383
352
- ExpressionLike::BinaryExpression(expr) => {
384
+ Expression::BinaryExpression(expr) => {
385
let BinaryExpression {
386
left,
387
operator,
@@ -365,15 +397,6 @@ fn lower_expression<'a>(
397
})
398
}
399
368
- // Cases that cannot appear in expression position but which are included in ExpressionLike
369
- // to make serialization easier
370
- ExpressionLike::SpreadElement(expr) => {
371
- return Err(BuildDiagnostic::new(
372
- DiagnosticError::NonExpressionInExpressionPosition,
373
- ErrorSeverity::Invariant,
374
- expr.range,
375
- ));
376
- }
400
_ => todo!("Lower expr {expr:#?}"),
401
})
402
}
@@ -386,7 +409,7 @@ fn lower_assignment<'a>(
409
value: Place<'a>,
410
) -> Result<InstructionValue<'a>, BuildDiagnostic> {
411
Ok(match lvalue {
389
- AssignmentTarget::Pattern(lvalue) => match *lvalue {
412
+ AssignmentTarget::Pattern(lvalue) => match lvalue {
413
Pattern::Identifier(lvalue) => {
414
let place = lower_identifier_for_assignment(env, builder, kind, *lvalue)?;
415
let temporary = lower_value_to_temporary(
@@ -466,10 +489,10 @@ fn lower_primitive<'a>(
489
literal: Literal,
490
) -> PrimitiveValue<'a> {
491
match literal.value {
469
- LiteralValue::Boolean(bool) => PrimitiveValue::Boolean(bool),
470
- LiteralValue::Null => PrimitiveValue::Null,
471
- LiteralValue::Number(value) => PrimitiveValue::Number(f64::from(value).into()),
472
- LiteralValue::String(s) => PrimitiveValue::String(String::from_str_in(&s, &env.allocator)),
492
+ JsValue::Bool(bool) => PrimitiveValue::Boolean(bool),
493
+ JsValue::Null => PrimitiveValue::Null,
494
+ JsValue::Number(value) => PrimitiveValue::Number(f64::from(value).into()),
495
+ JsValue::String(s) => PrimitiveValue::String(String::from_str_in(&s, &env.allocator)),
496
_ => todo!("Lower literal {literal:#?}"),
497
}
498
}
compiler/forget/crates/build-hir/src/error.rs
+4
@@ -76,6 +76,10 @@ pub enum DiagnosticError {
76
/// ErrorSeverity::Invariant
77
#[error("Invariant: Identifier was not resolved (did name resolution run successfully?)")]
78
UnknownIdentifier,
79
+
80
+ /// ErrorSeverity::InvalidSyntax
81
+ #[error("Expected function to have a body")]
82
+ EmptyFunction,
83
}
84
85
#[derive(Error, Diagnostic, Debug)]
compiler/forget/crates/estree-codegen/src/ecmascript.json
+2
-1
@@ -91,7 +91,8 @@
91
"type": "Vec<ModuleItem>"
92
},
93
"source_type": {
94
- "type": "Option<SourceType>",
94
+ "type": "SourceType",
95
+ "optional": true,
96
"rename": "sourceType"
97
}
98
}
compiler/forget/crates/estree-swc/src/lib.rs
+90
-89
@@ -71,9 +71,7 @@ fn convert_program(cx: &Context, program: &Program) -> estree::Program {
71
let body = &program.body;
72
program_items = Vec::with_capacity(body.len());
73
for item in body {
74
- program_items.push(estree::ModuleItem::Statement(Box::new(convert_statement(
75
- cx, item,
76
- ))));
74
+ program_items.push(estree::ModuleItem::Statement(convert_statement(cx, item)));
75
}
76
}
77
};
@@ -84,7 +82,7 @@ fn convert_program(cx: &Context, program: &Program) -> estree::Program {
82
estree::SourceType::Module
83
},
84
body: program_items,
87
- comments: None,
85
+ // comments: None,
86
loc: None,
87
range: None,
88
}
@@ -92,9 +90,7 @@ fn convert_program(cx: &Context, program: &Program) -> estree::Program {
90
91
fn convert_module_item(cx: &Context, item: &ModuleItem) -> estree::ModuleItem {
92
match item {
95
- ModuleItem::Stmt(item) => {
96
- estree::ModuleItem::Statement(Box::new(convert_statement(cx, item)))
97
- }
93
+ ModuleItem::Stmt(item) => estree::ModuleItem::Statement(convert_statement(cx, item)),
94
_ => todo!("translate module item {:#?}", item),
95
}
96
}
@@ -131,23 +127,27 @@ fn convert_statement(cx: &Context, stmt: &Stmt) -> estree::Statement {
127
Stmt::Decl(Decl::Fn(item)) => {
128
let name = item.ident.sym.to_string();
129
estree::Statement::FunctionDeclaration(Box::new(estree::FunctionDeclaration {
134
- id: Some(estree::Identifier {
135
- name,
136
- binding: convert_binding(cx, item.ident.span.ctxt),
137
- loc: None,
138
- range: convert_span(&item.ident.span),
139
- }),
140
- params: item
141
- .function
142
- .params
143
- .iter()
144
- .map(|param| convert_pattern(cx, ¶m.pat))
145
- .collect(),
146
- body: item.function.body.as_ref().map(|body| {
147
- estree::Statement::BlockStatement(Box::new(convert_block_statement(cx, body)))
148
- }),
149
- is_async: item.function.is_async,
150
- is_generator: item.function.is_generator,
130
+ function: estree::Function {
131
+ id: Some(estree::Identifier {
132
+ name,
133
+ binding: convert_binding(cx, item.ident.span.ctxt),
134
+ loc: None,
135
+ range: convert_span(&item.ident.span),
136
+ }),
137
+ params: item
138
+ .function
139
+ .params
140
+ .iter()
141
+ .map(|param| convert_pattern(cx, ¶m.pat))
142
+ .collect(),
143
+ body: item.function.body.as_ref().map(|body| {
144
+ estree::FunctionBody::BlockStatement(Box::new(convert_block_statement(
145
+ cx, body,
146
+ )))
147
+ }),
148
+ is_async: item.function.is_async,
149
+ is_generator: item.function.is_generator,
150
+ },
151
loc: None,
152
range: convert_span(&item.function.span),
153
}))
@@ -206,7 +206,7 @@ fn convert_statement(cx: &Context, stmt: &Stmt) -> estree::Statement {
206
Stmt::For(item) => estree::Statement::ForStatement(Box::new(estree::ForStatement {
207
init: item.init.as_ref().map(|init| match init {
208
VarDeclOrExpr::Expr(init) => {
209
- estree::ForInit::Expression(Box::new(convert_expression(cx, init)))
209
+ estree::ForInit::Expression(convert_expression(cx, init))
210
}
211
VarDeclOrExpr::VarDecl(init) => {
212
assert_eq!(init.decls.len(), 1);
@@ -268,28 +268,28 @@ fn convert_variable_declaration(cx: &Context, decl: &VarDecl) -> estree::Variabl
268
}
269
}
270
271
-fn convert_expression(cx: &Context, expr: &Expr) -> estree::ExpressionLike {
271
+fn convert_expression(cx: &Context, expr: &Expr) -> estree::Expression {
272
match expr {
273
- Expr::Ident(expr) => {
274
- estree::ExpressionLike::Identifier(Box::new(convert_identifier(cx, expr)))
275
- }
273
+ Expr::Ident(expr) => estree::Expression::Identifier(Box::new(convert_identifier(cx, expr))),
274
Expr::Array(expr) => {
277
- estree::ExpressionLike::ArrayExpression(Box::new(estree::ArrayExpression {
275
+ estree::Expression::ArrayExpression(Box::new(estree::ArrayExpression {
276
elements: expr
277
.elems
278
.iter()
279
.map(|item| {
280
// TODO: represent holes in array expressions
283
- let value = item.as_ref().unwrap();
281
+ let value = item.as_ref()?;
282
match value.spread {
285
- Some(spread) => estree::ExpressionLike::SpreadElement(Box::new(
286
- estree::SpreadElement {
283
+ Some(spread) => Some(estree::ExpressionOrSpread::SpreadElement(
284
+ Box::new(estree::SpreadElement {
285
argument: convert_expression(cx, &value.expr),
286
loc: None,
287
range: convert_span(&spread),
290
- },
288
+ }),
289
+ )),
290
+ None => Some(estree::ExpressionOrSpread::Expression(
291
+ convert_expression(cx, &value.expr),
292
)),
292
- None => convert_expression(cx, &value.expr),
293
}
294
})
295
.collect(),
@@ -297,17 +297,18 @@ fn convert_expression(cx: &Context, expr: &Expr) -> estree::ExpressionLike {
297
range: convert_span(&expr.span),
298
}))
299
}
300
- Expr::Await(expr) => {
301
- estree::ExpressionLike::AwaitExpression(Box::new(estree::AwaitExpression {
302
- argument: convert_expression(cx, &expr.arg),
303
- loc: None,
304
- range: convert_span(&expr.span),
305
- }))
300
+ Expr::Await(_expr) => {
301
+ // estree::Expression::AwaitExpression(Box::new(estree::AwaitExpression {
302
+ // argument: convert_expression(cx, &expr.arg),
303
+ // loc: None,
304
+ // range: convert_span(&expr.span),
305
+ // }))
306
+ todo!("await expression")
307
}
308
Expr::Unary(expr) => {
308
- estree::ExpressionLike::UnaryExpression(Box::new(estree::UnaryExpression {
309
+ estree::Expression::UnaryExpression(Box::new(estree::UnaryExpression {
310
operator: convert_unary_operator(expr.op),
310
- is_prefix: false,
311
+ prefix: false,
312
argument: convert_expression(cx, &expr.arg),
313
loc: None,
314
range: convert_span(&expr.span),
@@ -315,7 +316,7 @@ fn convert_expression(cx: &Context, expr: &Expr) -> estree::ExpressionLike {
316
}
317
Expr::Bin(expr) => match convert_binary_operator(expr.op) {
318
Operator::Binary(op) => {
318
- estree::ExpressionLike::BinaryExpression(Box::new(estree::BinaryExpression {
319
+ estree::Expression::BinaryExpression(Box::new(estree::BinaryExpression {
320
operator: op,
321
left: convert_expression(cx, &expr.left),
322
right: convert_expression(cx, &expr.right),
@@ -324,7 +325,7 @@ fn convert_expression(cx: &Context, expr: &Expr) -> estree::ExpressionLike {
325
}))
326
}
327
Operator::Logical(op) => {
327
- estree::ExpressionLike::LogicalExpression(Box::new(estree::LogicalExpression {
328
+ estree::Expression::LogicalExpression(Box::new(estree::LogicalExpression {
329
operator: op,
330
left: convert_expression(cx, &expr.left),
331
right: convert_expression(cx, &expr.right),
@@ -335,30 +336,28 @@ fn convert_expression(cx: &Context, expr: &Expr) -> estree::ExpressionLike {
336
},
337
Expr::Lit(expr) => {
338
let (value, range) = match expr {
338
- Lit::Bool(expr) => (
339
- estree::LiteralValue::Boolean(expr.value),
340
- convert_span(&expr.span),
341
- ),
339
+ Lit::Bool(expr) => (estree::JsValue::Bool(expr.value), convert_span(&expr.span)),
340
Lit::Num(expr) => (
343
- estree::LiteralValue::Number(expr.value.into()),
341
+ estree::JsValue::Number(expr.value.into()),
342
convert_span(&expr.span),
343
),
344
Lit::Str(expr) => (
347
- estree::LiteralValue::String(expr.value.to_string()),
345
+ estree::JsValue::String(expr.value.to_string()),
346
convert_span(&expr.span),
347
),
350
- Lit::Null(expr) => (estree::LiteralValue::Null, convert_span(&expr.span)),
348
+ Lit::Null(expr) => (estree::JsValue::Null, convert_span(&expr.span)),
349
_ => todo!(),
350
};
353
- estree::ExpressionLike::Literal(Box::new(estree::Literal {
351
+ estree::Expression::Literal(Box::new(estree::Literal {
352
value,
353
raw: None,
354
loc: None,
355
+ regex: None,
356
range,
357
}))
358
}
359
Expr::Assign(expr) => {
361
- estree::ExpressionLike::AssignmentExpression(Box::new(estree::AssignmentExpression {
360
+ estree::Expression::AssignmentExpression(Box::new(estree::AssignmentExpression {
361
operator: convert_assignment_operator(expr.op),
362
left: convert_assignment_target(cx, &expr.left),
363
right: convert_expression(cx, &expr.right),
@@ -367,7 +366,7 @@ fn convert_expression(cx: &Context, expr: &Expr) -> estree::ExpressionLike {
366
}))
367
}
368
Expr::Member(expr) => {
370
- estree::ExpressionLike::MemberExpression(Box::new(convert_member_expression(cx, expr)))
369
+ estree::Expression::MemberExpression(Box::new(convert_member_expression(cx, expr)))
370
}
371
_ => todo!("translate expression {:#?}", expr),
372
}
@@ -375,17 +374,17 @@ fn convert_expression(cx: &Context, expr: &Expr) -> estree::ExpressionLike {
374
375
fn convert_assignment_target(cx: &Context, target: &PatOrExpr) -> estree::AssignmentTarget {
376
match target {
378
- PatOrExpr::Pat(target) => {
379
- estree::AssignmentTarget::Pattern(Box::new(convert_pattern(cx, target)))
380
- }
377
+ PatOrExpr::Pat(target) => estree::AssignmentTarget::Pattern(convert_pattern(cx, target)),
378
PatOrExpr::Expr(target) => {
379
match target.as_ref() {
383
- Expr::Member(target) => estree::AssignmentTarget::MemberExpression(Box::new(
384
- convert_member_expression(cx, target),
385
- )),
386
- Expr::Ident(target) => estree::AssignmentTarget::Pattern(Box::new(
380
+ Expr::Member(target) => {
381
+ estree::AssignmentTarget::Expression(estree::Expression::MemberExpression(
382
+ Box::new(convert_member_expression(cx, target)),
383
+ ))
384
+ }
385
+ Expr::Ident(target) => estree::AssignmentTarget::Pattern(
386
estree::Pattern::Identifier(Box::new(convert_identifier(cx, target))),
388
- )),
387
+ ),
388
_ => {
389
panic!("Expected assignment target to be member expression or identifier, got {:#?}", target)
390
}
@@ -398,7 +397,7 @@ fn convert_member_expression(cx: &Context, expr: &MemberExpr) -> estree::MemberE
397
let (is_computed, property) = match &expr.prop {
398
MemberProp::Ident(prop) => (
399
false,
401
- estree::ExpressionLike::Identifier(Box::new(convert_identifier(cx, prop))),
400
+ estree::Expression::Identifier(Box::new(convert_identifier(cx, prop))),
401
),
402
MemberProp::Computed(prop) => (true, convert_expression(cx, &prop.expr)),
403
_ => {
@@ -406,10 +405,10 @@ fn convert_member_expression(cx: &Context, expr: &MemberExpr) -> estree::MemberE
405
}
406
};
407
estree::MemberExpression {
409
- object: convert_expression(cx, &expr.obj),
408
+ object: estree::ExpressionOrSuper::Expression(convert_expression(cx, &expr.obj)),
409
property,
411
- is_computed,
412
- is_optional: false,
410
+ computed: false, // TODO
411
+ // optional: false, // TODO
412
loc: None,
413
range: convert_span(&expr.span),
414
}
@@ -417,7 +416,7 @@ fn convert_member_expression(cx: &Context, expr: &MemberExpr) -> estree::MemberE
416
417
fn convert_unary_operator(op: UnaryOp) -> estree::UnaryOperator {
418
match op {
420
- UnaryOp::Bang => estree::UnaryOperator::Exclamation,
419
+ UnaryOp::Bang => estree::UnaryOperator::Negation,
420
UnaryOp::Delete => estree::UnaryOperator::Delete,
421
UnaryOp::Minus => estree::UnaryOperator::Minus,
422
UnaryOp::Plus => estree::UnaryOperator::Plus,
@@ -442,32 +441,34 @@ enum Operator {
441
442
fn convert_binary_operator(op: BinaryOp) -> Operator {
443
match op {
445
- BinaryOp::Add => Operator::Binary(estree::BinaryOperator::Plus),
446
- BinaryOp::BitAnd => Operator::Binary(estree::BinaryOperator::Ampersand),
447
- BinaryOp::BitOr => Operator::Binary(estree::BinaryOperator::Pipe),
448
- BinaryOp::BitXor => Operator::Binary(estree::BinaryOperator::Caret),
449
- BinaryOp::Div => Operator::Binary(estree::BinaryOperator::Slash),
450
- BinaryOp::EqEq => Operator::Binary(estree::BinaryOperator::EqualsEquals),
451
- BinaryOp::EqEqEq => Operator::Binary(estree::BinaryOperator::TripleEquals),
452
- BinaryOp::Exp => Operator::Binary(estree::BinaryOperator::AsteriskAsterisk),
444
+ BinaryOp::Add => Operator::Binary(estree::BinaryOperator::Add),
445
+ BinaryOp::BitAnd => Operator::Binary(estree::BinaryOperator::BinaryAnd),
446
+ BinaryOp::BitOr => Operator::Binary(estree::BinaryOperator::BinaryOr),
447
+ BinaryOp::BitXor => Operator::Binary(estree::BinaryOperator::BinaryXor),
448
+ BinaryOp::Div => Operator::Binary(estree::BinaryOperator::Divide),
449
+ BinaryOp::EqEq => Operator::Binary(estree::BinaryOperator::Equals),
450
+ BinaryOp::EqEqEq => Operator::Binary(estree::BinaryOperator::StrictEquals),
451
+ // BinaryOp::Exp => Operator::Binary(estree::BinaryOperator::AsteriskAsterisk),
452
BinaryOp::Gt => Operator::Binary(estree::BinaryOperator::GreaterThan),
454
- BinaryOp::GtEq => Operator::Binary(estree::BinaryOperator::GreaterThanEquals),
453
+ BinaryOp::GtEq => Operator::Binary(estree::BinaryOperator::GreaterThanOrEqual),
454
BinaryOp::In => Operator::Binary(estree::BinaryOperator::In),
455
BinaryOp::InstanceOf => Operator::Binary(estree::BinaryOperator::Instanceof),
457
- BinaryOp::LShift => Operator::Binary(estree::BinaryOperator::LtLt),
456
+ BinaryOp::LShift => Operator::Binary(estree::BinaryOperator::ShiftLeft),
457
BinaryOp::Lt => Operator::Binary(estree::BinaryOperator::LessThan),
459
- BinaryOp::LtEq => Operator::Binary(estree::BinaryOperator::LessThanEquals),
460
- BinaryOp::Mod => Operator::Binary(estree::BinaryOperator::Percent),
461
- BinaryOp::Mul => Operator::Binary(estree::BinaryOperator::Asterisk),
458
+ BinaryOp::LtEq => Operator::Binary(estree::BinaryOperator::LessThanOrEqual),
459
+ BinaryOp::Mod => Operator::Binary(estree::BinaryOperator::Modulo),
460
+ // BinaryOp::Mul => Operator::Binary(estree::BinaryOperator::Asterisk),
461
BinaryOp::NotEq => Operator::Binary(estree::BinaryOperator::NotEquals),
463
- BinaryOp::NotEqEq => Operator::Binary(estree::BinaryOperator::NotTripleEquals),
464
- BinaryOp::RShift => Operator::Binary(estree::BinaryOperator::GtGt),
465
- BinaryOp::Sub => Operator::Binary(estree::BinaryOperator::Minus),
466
- BinaryOp::ZeroFillRShift => Operator::Binary(estree::BinaryOperator::GtGtGt),
462
+ BinaryOp::NotEqEq => Operator::Binary(estree::BinaryOperator::NotStrictEquals),
463
+ BinaryOp::RShift => Operator::Binary(estree::BinaryOperator::ShiftRight),
464
+ BinaryOp::Sub => Operator::Binary(estree::BinaryOperator::Subtract),
465
+ BinaryOp::ZeroFillRShift => Operator::Binary(estree::BinaryOperator::UnsignedShiftRight),
466
+
467
+ BinaryOp::LogicalAnd => Operator::Logical(estree::LogicalOperator::And),
468
+ BinaryOp::LogicalOr => Operator::Logical(estree::LogicalOperator::Or),
469
+ BinaryOp::NullishCoalescing => Operator::Logical(estree::LogicalOperator::NullCoalescing),
470
468
- BinaryOp::LogicalAnd => Operator::Logical(estree::LogicalOperator::AmpersandAmpersand),
469
- BinaryOp::LogicalOr => Operator::Logical(estree::LogicalOperator::PipePipe),
470
- BinaryOp::NullishCoalescing => Operator::Logical(estree::LogicalOperator::QuestionQuestion),
471
+ _ => panic!("Unsupported binary operator `{}`", op),
472
}
473
}
474
@@ -484,7 +485,7 @@ fn convert_pattern(cx: &Context, pat: &Pat) -> estree::Pattern {
485
}
486
487
fn convert_binding(context: &Context, binding_cx: SyntaxContext) -> Option<Binding> {
487
- let id = BindingId::new(NonZeroU32::new(binding_cx.as_u32()).unwrap());
488
+ let id = BindingId::new(binding_cx.as_u32());
489
if binding_cx.as_u32() == context.top_level_mark.as_u32() {
490
Some(Binding::Global)
491
} else if binding_cx.as_u32() == context.unresolved_mark.as_u32() {
compiler/forget/crates/estree/src/binding.rs
+21
-2
@@ -1,4 +1,23 @@
1
use serde::{Deserialize, Serialize};
2
3
-#[derive(Serialize, Deserialize, Clone, Debug)]
4
-pub struct Binding;
3
+#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq, Hash)]
4
+pub enum Binding {
5
+ Global,
6
+ Module(BindingId),
7
+ Local(BindingId),
8
+}
9
+
10
+#[derive(Serialize, Deserialize, Copy, Clone, Debug, PartialEq, Eq, Hash)]
11
+pub struct BindingId(u32);
12
+
13
+impl BindingId {
14
+ pub fn new(value: u32) -> Self {
15
+ Self(value)
16
+ }
17
+}
18
+
19
+impl From<BindingId> for u32 {
20
+ fn from(value: BindingId) -> Self {
21
+ value.0
22
+ }
23
+}
compiler/forget/crates/estree/src/generated.rs
+2
-1
@@ -56,7 +56,8 @@ pub struct Literal {
56
pub struct Program {
57
pub body: Vec<ModuleItem>,
58
#[serde(rename = "sourceType")]
59
- pub source_type: Option<SourceType>,
59
+ #[serde(default)]
60
+ pub source_type: SourceType,
61
#[serde(default)]
62
pub loc: Option<SourceLocation>,
63
#[serde(default)]
compiler/forget/crates/estree/src/lib.rs
+1
-1
@@ -4,7 +4,7 @@ mod generated_extensions;
4
mod js_value;
5
mod range;
6
7
-pub use binding::Binding;
7
+pub use binding::{Binding, BindingId};
8
pub use generated::*;
9
pub use js_value::JsValue;
10
pub use range::SourceRange;
compiler/forget/crates/estree/src/snapshots/estree__tests__fixtures@simple.json.snap
+1
-1
@@ -351,7 +351,7 @@ Output:
351
}
352
}
353
],
354
- "sourceType": null,
354
+ "sourceType": "script",
355
"loc": {
356
"source": null,
357
"start": {
compiler/forget/crates/fixtures/tests/fixtures_test.rs
+1
-1
@@ -18,7 +18,7 @@ fn fixtures() {
18
19
for (ix, item) in ast.body.into_iter().enumerate() {
20
if let ModuleItem::Statement(stmt) = item {
21
- if let Statement::FunctionDeclaration(fun) = *stmt {
21
+ if let Statement::FunctionDeclaration(fun) = stmt {
22
let allocator = Bump::new();
23
let environment = allocator.alloc(Environment::new(
24
&allocator,
compiler/forget/crates/hir/src/instruction.rs
+1
-1
@@ -51,7 +51,7 @@ pub enum InstructionValue<'a> {
51
52
#[derive(Debug)]
53
pub struct Array<'a> {
54
- pub elements: Vec<'a, ArrayElement<'a>>,
54
+ pub elements: Vec<'a, Option<ArrayElement<'a>>>,
55
}
56
57
#[derive(Debug)]
compiler/forget/crates/hir/src/print.rs
+5
-1
@@ -55,7 +55,11 @@ impl<'a> Print for InstructionValue<'a> {
55
if ix != 0 {
56
write!(out, ", ")?;
57
}
58
- item.print(out)?;
58
+ if let Some(item) = item {
59
+ item.print(out)?;
60
+ } else {
61
+ write!(out, "<elision>")?;
62
+ }
63
}
64
write!(out, "]")?;
65
}