@samitouri / QOS-React-2 / commits / bdd50d522d

[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, &param.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, &param.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 }