dillon1000/react
Commit
Browse files Fix block scoping of declarations with early return
I addressed some of the cases that lead to this invariant but there were still
more. In this case, we have scopes like this:
```
scope @1 declarations=[t$0] {
let t$0 = ArrayExpression []
if (...) {
return null;
}
}
scope @2 deps=[t$0] declarations=[t$1] {
let t$1 = Jsx children=[t$0] ...
}
```
Because scope 1 has an early return, PropagateEarlyReturns wraps its contents in
a label and converts the returns to breaks:
```
scope @1 declarations=[t$0] earlyReturn={t$2} {
let t$2
bb0: {
let t$0 = ArrayExpression []
if (...) {
t$2 = null;
break bb0;
}
}
}
scope @2 deps=[t$0] declarations=[t$1] {
let t$1 = Jsx children=[t$0] ...
}
```
But then MergeReactiveScopesThatInvalidateTogether smushes them together:
```
scope @1 declarations=[t$1] earlyReturn={t$2} {
let t$2
bb0: {
let t$0 = ArrayExpression [] // <--- Oops! We're inside a block now
if (...) {
t$2 = null;
break bb0;
}
}
let t$1 = Jsx children=[t$0] ...
}
```
Note that the `t$0` binding is now created inside the labeled block, so it's no
longer accessible to the Jsx instruction which follows the labeled block. This
isn't an issue with promoting temporaries or propagating outputs, but a simple
issue of the labeled block (used for early return) introducing a new block
scope. The solution here is to simply reorder the passes so that we transform
for early returns after other optimizations. This means the jsx element will
basically move inside the labeled block, solving the scoping issue:
```
scope @1 declarations=[t$1] earlyReturn={t$2} {
let t$2
bb0: {
let t$0 = ArrayExpression [] // ok, same block scope as its use
if (...) {
t$2 = null;
break bb0;
}
let t$1 = Jsx children=[t$0] // note this moved inside the labeled block
}
}
```Changed paths7 files
First-parent comparisoncompiler/packages/babel-plugin-react-forget/src/Entrypoint/Pipeline.ts ModifiedM compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/CodegenReactiveFunction.ts ModifiedM compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/PrintReactiveFunction.ts ModifiedM compiler/packages/babel-plugin-react-forget/src/ReactiveScopes/PruneUnusedScopes.ts ModifiedD compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-repro-no-value-for-temporary-reactive-scope-with-early-return.expect.md DeletedA compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro-no-value-for-temporary-reactive-scope-with-early-return.expect.md AddedR compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/error.todo-repro-no-value-for-temporary-reactive-scope-with-early-return.js →compiler/packages/babel-plugin-react-forget/src/__tests__/fixtures/compiler/repro-no-value-for-temporary-reactive-scope-with-early-return.js RenamedPatch
Files changed
Rendering syntax-highlighted changes…