Skip to content

Commit

Permalink
feat(transformer/optional-chaining): change parent scope for expressi…
Browse files Browse the repository at this point in the history
…on when it wrapped with an arrow function (#8511)
  • Loading branch information
Dunqing committed Jan 16, 2025
1 parent 8dd0013 commit f413bb5
Show file tree
Hide file tree
Showing 3 changed files with 15 additions and 325 deletions.
18 changes: 12 additions & 6 deletions crates/oxc_transformer/src/es2020/optional_chaining.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ use std::mem;

use oxc_allocator::CloneIn;
use oxc_ast::{ast::*, NONE};
use oxc_semantic::ScopeFlags;
use oxc_span::SPAN;
use oxc_traverse::{Ancestor, BoundIdentifier, MaybeBoundIdentifier, Traverse, TraverseCtx};

Expand Down Expand Up @@ -244,14 +245,19 @@ impl<'a> OptionalChaining<'a, '_> {

/// Wrap the expression with an arrow function
///
/// `expr` -> `() => { return expr; }`
fn wrap_arrow_function(expr: &mut Expression<'a>, ctx: &mut TraverseCtx<'a>) -> Expression<'a> {
/// `expr` -> `(() => { return expr; })()`
fn wrap_arrow_function_iife(
expr: &mut Expression<'a>,
ctx: &mut TraverseCtx<'a>,
) -> Expression<'a> {
let scope_id =
ctx.insert_scope_below_expression(expr, ScopeFlags::Arrow | ScopeFlags::Function);

let kind = FormalParameterKind::ArrowFormalParameters;
let params = ctx.ast.formal_parameters(SPAN, kind, ctx.ast.vec(), NONE);
let statements =
ctx.ast.vec1(ctx.ast.statement_return(SPAN, Some(ctx.ast.move_expression(expr))));
let body = ctx.ast.function_body(SPAN, ctx.ast.vec(), statements);
let scope_id = ctx.current_scope_id();
let arrow = ctx.ast.alloc_arrow_function_expression_with_scope_id(
SPAN, false, false, NONE, params, NONE, body, scope_id,
);
Expand Down Expand Up @@ -306,7 +312,7 @@ impl<'a> OptionalChaining<'a, '_> {
// To insert the temp binding in the correct scope, we wrap the expression with
// an arrow function. During the chain expression transformation, the temp binding
// will be inserted into the arrow function's body.
Self::wrap_arrow_function(expr, ctx)
Self::wrap_arrow_function_iife(expr, ctx)
} else {
self.transform_chain_expression_impl(false, expr, ctx)
}
Expand All @@ -320,7 +326,7 @@ impl<'a> OptionalChaining<'a, '_> {
) {
*expr = if self.is_inside_function_parameter {
// Same as the above `transform_chain_expression` explanation
Self::wrap_arrow_function(expr, ctx)
Self::wrap_arrow_function_iife(expr, ctx)
} else {
// Unfortunately no way to get compiler to see that this branch is provably unreachable.
// We don't want to inline this function, to keep `enter_expression` as small as possible.
Expand Down Expand Up @@ -659,7 +665,6 @@ impl<'a> OptionalChaining<'a, '_> {
let assignment_expression =
Self::create_assignment_expression(temp_binding.create_write_target(ctx), expr, ctx);

let reference = temp_binding.create_read_expression(ctx);
// `left || (binding = expr) === null`
let left = Self::create_logical_expression(
left,
Expand All @@ -670,6 +675,7 @@ impl<'a> OptionalChaining<'a, '_> {
if self.ctx.assumptions.no_document_all {
left
} else {
let reference = temp_binding.create_read_expression(ctx);
// `left || (binding = expr) === null || binding === void 0`
Self::create_logical_expression(left, Self::wrap_void0_check(reference, ctx), ctx)
}
Expand Down
30 changes: 1 addition & 29 deletions tasks/coverage/snapshots/semantic_typescript.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ commit: d85767ab

semantic_typescript Summary:
AST Parsed : 6503/6503 (100.00%)
Positive Passed: 2923/6503 (44.95%)
Positive Passed: 2925/6503 (44.98%)
tasks/coverage/typescript/tests/cases/compiler/2dArrays.ts
semantic error: Symbol reference IDs mismatch for "Cell":
after transform: SymbolId(0): [ReferenceId(1)]
Expand Down Expand Up @@ -36429,34 +36429,6 @@ Unresolved references mismatch:
after transform: []
rebuilt : ["o1", "o2", "o3", "o4", "o5", "o6"]

tasks/coverage/typescript/tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterBindingPattern.ts
semantic error: Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1), ScopeId(2)]
rebuilt : ScopeId(0): [ScopeId(1), ScopeId(2)]
Bindings mismatch:
after transform: ScopeId(2): ["_a", "c"]
rebuilt : ScopeId(3): ["_a"]
Scope parent mismatch:
after transform: ScopeId(2): Some(ScopeId(0))
rebuilt : ScopeId(3): Some(ScopeId(2))
Symbol scope ID mismatch for "c":
after transform: SymbolId(1): ScopeId(2)
rebuilt : SymbolId(1): ScopeId(2)

tasks/coverage/typescript/tests/cases/conformance/expressions/optionalChaining/optionalChainingInParameterInitializer.ts
semantic error: Scope children mismatch:
after transform: ScopeId(0): [ScopeId(1), ScopeId(2)]
rebuilt : ScopeId(0): [ScopeId(1), ScopeId(2)]
Bindings mismatch:
after transform: ScopeId(2): ["_a", "b"]
rebuilt : ScopeId(3): ["_a"]
Scope parent mismatch:
after transform: ScopeId(2): Some(ScopeId(0))
rebuilt : ScopeId(3): Some(ScopeId(2))
Symbol scope ID mismatch for "b":
after transform: SymbolId(1): ScopeId(2)
rebuilt : SymbolId(1): ScopeId(2)

tasks/coverage/typescript/tests/cases/conformance/expressions/optionalChaining/optionalChainingInference.ts
semantic error: Bindings mismatch:
after transform: ScopeId(0): ["b1", "b2", "b3", "b4", "b5", "b6", "b7", "b8", "fnu", "ofnu", "osu", "su", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8"]
Expand Down
Loading

0 comments on commit f413bb5

Please sign in to comment.