From 89e2305e614d19625a65ac03fdca64c1b0583f7a Mon Sep 17 00:00:00 2001 From: Sathya Gunsasekaran Date: Tue, 6 Aug 2024 16:32:49 +0100 Subject: [PATCH] [compiler] Add lowerContextAccess pass *This is only for internal profiling, not intended to ship.* This pass is intended to be used with https://github.com/facebook/react/pull/30407. This pass synthesizes selector functions by collecting immediately destructured context acesses. We bailout for other types of context access. This pass lowers context access to use a selector function by passing the synthesized selector function as the second argument. ghstack-source-id: 61ef1a29e98e3b5a2e5d70e5870956ba5fa6bd8d Pull Request resolved: https://github.com/facebook/react/pull/30548 --- .../src/Entrypoint/Pipeline.ts | 5 + .../src/Optimization/LowerContextAccess.ts | 257 ++++++++++++++++++ .../lower-context-acess-multiple.expect.md | 43 +++ .../compiler/lower-context-acess-multiple.js | 6 + .../lower-context-selector-simple.expect.md | 36 +++ .../compiler/lower-context-selector-simple.js | 5 + ...ntext-access-array-destructuring.expect.md | 33 +++ ...ower-context-access-array-destructuring.js | 5 + ...text-access-destructure-multiple.expect.md | 37 +++ ...wer-context-access-destructure-multiple.js | 7 + ...r-context-access-mixed-array-obj.expect.md | 37 +++ ...do.lower-context-access-mixed-array-obj.js | 7 + ...text-access-nested-destructuring.expect.md | 37 +++ ...wer-context-access-nested-destructuring.js | 8 + ...wer-context-access-property-load.expect.md | 37 +++ ...todo.lower-context-access-property-load.js | 7 + .../packages/snap/src/SproutTodoFilter.ts | 8 + 17 files changed, 575 insertions(+) create mode 100644 compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lower-context-acess-multiple.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lower-context-acess-multiple.js create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lower-context-selector-simple.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lower-context-selector-simple.js create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-array-destructuring.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-array-destructuring.js create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-destructure-multiple.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-destructure-multiple.js create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-mixed-array-obj.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-mixed-array-obj.js create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-nested-destructuring.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-nested-destructuring.js create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-property-load.expect.md create mode 100644 compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-property-load.js diff --git a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts index acee95955502f..d515de2900eb5 100644 --- a/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts +++ b/compiler/packages/babel-plugin-react-compiler/src/Entrypoint/Pipeline.ts @@ -98,6 +98,7 @@ import { } from '../Validation'; import {validateLocalsNotReassignedAfterRender} from '../Validation/ValidateLocalsNotReassignedAfterRender'; import {outlineFunctions} from '../Optimization/OutlineFunctions'; +import {lowerContextAccess} from '../Optimization/LowerContextAccess'; export type CompilerPipelineValue = | {kind: 'ast'; name: string; value: CodegenFunction} @@ -199,6 +200,10 @@ function* runWithEnvironment( validateNoCapitalizedCalls(hir); } + if (env.config.enableLowerContextAccess) { + lowerContextAccess(hir); + } + analyseFunctions(hir); yield log({kind: 'hir', name: 'AnalyseFunctions', value: hir}); diff --git a/compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts b/compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts new file mode 100644 index 0000000000000..3a61bc55710c0 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/Optimization/LowerContextAccess.ts @@ -0,0 +1,257 @@ +/** + * Copyright (c) Meta Platforms, Inc. and affiliates. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { + ArrayExpression, + BasicBlock, + CallExpression, + Destructure, + Environment, + GeneratedSource, + HIRFunction, + IdentifierId, + Instruction, + LoadLocal, + Place, + PropertyLoad, + isUseContextHookType, + makeBlockId, + makeInstructionId, + markInstructionIds, + promoteTemporary, + reversePostorderBlocks, +} from '../HIR'; +import {createTemporaryPlace} from '../HIR/HIRBuilder'; +import {enterSSA} from '../SSA'; +import {inferTypes} from '../TypeInference'; + +export function lowerContextAccess(fn: HIRFunction): void { + const contextAccess: Map = new Map(); + const contextKeys: Map> = new Map(); + + // collect context access and keys + for (const [, block] of fn.body.blocks) { + for (const instr of block.instructions) { + const {value, lvalue} = instr; + + if ( + value.kind === 'CallExpression' && + isUseContextHookType(value.callee.identifier) + ) { + contextAccess.set(lvalue.identifier.id, value); + continue; + } + + if (value.kind !== 'Destructure') { + continue; + } + + const destructureId = value.value.identifier.id; + if (!contextAccess.has(destructureId)) { + continue; + } + + const keys = getContextKeys(value); + if (keys === null) { + return; + } + + if (contextKeys.has(destructureId)) { + /* + * TODO(gsn): Add support for accessing context over multiple + * statements. + */ + return; + } else { + contextKeys.set(destructureId, keys); + } + } + } + + if (contextAccess.size > 0) { + for (const [, block] of fn.body.blocks) { + let nextInstructions: Array | null = null; + + for (let i = 0; i < block.instructions.length; i++) { + const instr = block.instructions[i]; + const {lvalue, value} = instr; + if ( + value.kind === 'CallExpression' && + isUseContextHookType(value.callee.identifier) && + contextKeys.has(lvalue.identifier.id) + ) { + const keys = contextKeys.get(lvalue.identifier.id)!; + const selectorFnInstr = emitSelectorFn(fn.env, keys); + if (nextInstructions === null) { + nextInstructions = block.instructions.slice(0, i); + } + nextInstructions.push(selectorFnInstr); + + const selectorFn = selectorFnInstr.lvalue; + value.args.push(selectorFn); + } + + if (nextInstructions) { + nextInstructions.push(instr); + } + } + if (nextInstructions) { + block.instructions = nextInstructions; + } + } + markInstructionIds(fn.body); + } +} + +function getContextKeys(value: Destructure): Array | null { + const keys = []; + const pattern = value.lvalue.pattern; + + switch (pattern.kind) { + case 'ArrayPattern': { + return null; + } + + case 'ObjectPattern': { + for (const place of pattern.properties) { + if ( + place.kind !== 'ObjectProperty' || + place.type !== 'property' || + place.key.kind !== 'identifier' || + place.place.identifier.name === null || + place.place.identifier.name.kind !== 'named' + ) { + return null; + } + keys.push(place.key.name); + } + return keys; + } + } +} + +function emitPropertyLoad( + env: Environment, + obj: Place, + property: string, +): {instructions: Array; element: Place} { + const loadObj: LoadLocal = { + kind: 'LoadLocal', + place: obj, + loc: GeneratedSource, + }; + const object: Place = createTemporaryPlace(env, GeneratedSource); + const loadLocalInstr: Instruction = { + lvalue: object, + value: loadObj, + id: makeInstructionId(0), + loc: GeneratedSource, + }; + + const loadProp: PropertyLoad = { + kind: 'PropertyLoad', + object, + property, + loc: GeneratedSource, + }; + const element: Place = createTemporaryPlace(env, GeneratedSource); + const loadPropInstr: Instruction = { + lvalue: element, + value: loadProp, + id: makeInstructionId(0), + loc: GeneratedSource, + }; + return { + instructions: [loadLocalInstr, loadPropInstr], + element: element, + }; +} + +function emitSelectorFn(env: Environment, keys: Array): Instruction { + const obj: Place = createTemporaryPlace(env, GeneratedSource); + promoteTemporary(obj.identifier); + const instr: Array = []; + const elements = []; + for (const key of keys) { + const {instructions, element: prop} = emitPropertyLoad(env, obj, key); + instr.push(...instructions); + elements.push(prop); + } + + const arrayInstr = emitArrayInstr(elements, env); + instr.push(arrayInstr); + + const block: BasicBlock = { + kind: 'block', + id: makeBlockId(0), + instructions: instr, + terminal: { + id: makeInstructionId(0), + kind: 'return', + loc: GeneratedSource, + value: arrayInstr.lvalue, + }, + preds: new Set(), + phis: new Set(), + }; + + const fn: HIRFunction = { + loc: GeneratedSource, + id: null, + fnType: 'Other', + env, + params: [obj], + returnType: null, + context: [], + effects: null, + body: { + entry: block.id, + blocks: new Map([[block.id, block]]), + }, + generator: false, + async: false, + directives: [], + }; + + reversePostorderBlocks(fn.body); + markInstructionIds(fn.body); + enterSSA(fn); + inferTypes(fn); + + const fnInstr: Instruction = { + id: makeInstructionId(0), + value: { + kind: 'FunctionExpression', + name: null, + loweredFunc: { + func: fn, + dependencies: [], + }, + type: 'ArrowFunctionExpression', + loc: GeneratedSource, + }, + lvalue: createTemporaryPlace(env, GeneratedSource), + loc: GeneratedSource, + }; + return fnInstr; +} + +function emitArrayInstr(elements: Array, env: Environment): Instruction { + const array: ArrayExpression = { + kind: 'ArrayExpression', + elements, + loc: GeneratedSource, + }; + const arrayLvalue: Place = createTemporaryPlace(env, GeneratedSource); + const arrayInstr: Instruction = { + id: makeInstructionId(0), + value: array, + lvalue: arrayLvalue, + loc: GeneratedSource, + }; + return arrayInstr; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lower-context-acess-multiple.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lower-context-acess-multiple.expect.md new file mode 100644 index 0000000000000..0f9124536c55f --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lower-context-acess-multiple.expect.md @@ -0,0 +1,43 @@ + +## Input + +```javascript +// @enableLowerContextAccess +function App() { + const {foo} = useContext(MyContext); + const {bar} = useContext(MyContext); + return ; +} + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; // @enableLowerContextAccess +function App() { + const $ = _c(3); + const { foo } = useContext(MyContext, _temp); + const { bar } = useContext(MyContext, _temp2); + let t0; + if ($[0] !== foo || $[1] !== bar) { + t0 = ; + $[0] = foo; + $[1] = bar; + $[2] = t0; + } else { + t0 = $[2]; + } + return t0; +} +function _temp2(t0) { + return [t0.bar]; +} +function _temp(t0) { + return [t0.foo]; +} + +``` + +### Eval output +(kind: exception) Fixture not implemented \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lower-context-acess-multiple.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lower-context-acess-multiple.js new file mode 100644 index 0000000000000..8d2894152213d --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lower-context-acess-multiple.js @@ -0,0 +1,6 @@ +// @enableLowerContextAccess +function App() { + const {foo} = useContext(MyContext); + const {bar} = useContext(MyContext); + return ; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lower-context-selector-simple.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lower-context-selector-simple.expect.md new file mode 100644 index 0000000000000..8109cb5b81f02 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lower-context-selector-simple.expect.md @@ -0,0 +1,36 @@ + +## Input + +```javascript +// @enableLowerContextAccess +function App() { + const {foo, bar} = useContext(MyContext); + return ; +} + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; // @enableLowerContextAccess +function App() { + const $ = _c(3); + const { foo, bar } = useContext(MyContext, _temp); + let t0; + if ($[0] !== foo || $[1] !== bar) { + t0 = ; + $[0] = foo; + $[1] = bar; + $[2] = t0; + } else { + t0 = $[2]; + } + return t0; +} +function _temp(t0) { + return [t0.foo, t0.bar]; +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lower-context-selector-simple.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lower-context-selector-simple.js new file mode 100644 index 0000000000000..e24d653858752 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/lower-context-selector-simple.js @@ -0,0 +1,5 @@ +// @enableLowerContextAccess +function App() { + const {foo, bar} = useContext(MyContext); + return ; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-array-destructuring.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-array-destructuring.expect.md new file mode 100644 index 0000000000000..0ebd7989a4e7a --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-array-destructuring.expect.md @@ -0,0 +1,33 @@ + +## Input + +```javascript +// @enableLowerContextAccess +function App() { + const [foo, bar] = useContext(MyContext); + return ; +} + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; // @enableLowerContextAccess +function App() { + const $ = _c(3); + const [foo, bar] = useContext(MyContext); + let t0; + if ($[0] !== foo || $[1] !== bar) { + t0 = ; + $[0] = foo; + $[1] = bar; + $[2] = t0; + } else { + t0 = $[2]; + } + return t0; +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-array-destructuring.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-array-destructuring.js new file mode 100644 index 0000000000000..b1f60bf8e7d97 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-array-destructuring.js @@ -0,0 +1,5 @@ +// @enableLowerContextAccess +function App() { + const [foo, bar] = useContext(MyContext); + return ; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-destructure-multiple.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-destructure-multiple.expect.md new file mode 100644 index 0000000000000..21322ed17864c --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-destructure-multiple.expect.md @@ -0,0 +1,37 @@ + +## Input + +```javascript +// @enableLowerContextAccess +function App() { + const context = useContext(MyContext); + const {foo} = context; + const {bar} = context; + return ; +} + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; // @enableLowerContextAccess +function App() { + const $ = _c(3); + const context = useContext(MyContext); + const { foo } = context; + const { bar } = context; + let t0; + if ($[0] !== foo || $[1] !== bar) { + t0 = ; + $[0] = foo; + $[1] = bar; + $[2] = t0; + } else { + t0 = $[2]; + } + return t0; +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-destructure-multiple.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-destructure-multiple.js new file mode 100644 index 0000000000000..18115b49b1f3b --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-destructure-multiple.js @@ -0,0 +1,7 @@ +// @enableLowerContextAccess +function App() { + const context = useContext(MyContext); + const {foo} = context; + const {bar} = context; + return ; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-mixed-array-obj.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-mixed-array-obj.expect.md new file mode 100644 index 0000000000000..5217fbd6168e3 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-mixed-array-obj.expect.md @@ -0,0 +1,37 @@ + +## Input + +```javascript +// @enableLowerContextAccess +function App() { + const context = useContext(MyContext); + const [foo] = context; + const {bar} = context; + return ; +} + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; // @enableLowerContextAccess +function App() { + const $ = _c(3); + const context = useContext(MyContext); + const [foo] = context; + const { bar } = context; + let t0; + if ($[0] !== foo || $[1] !== bar) { + t0 = ; + $[0] = foo; + $[1] = bar; + $[2] = t0; + } else { + t0 = $[2]; + } + return t0; +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-mixed-array-obj.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-mixed-array-obj.js new file mode 100644 index 0000000000000..2eefdcd76f9fd --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-mixed-array-obj.js @@ -0,0 +1,7 @@ +// @enableLowerContextAccess +function App() { + const context = useContext(MyContext); + const [foo] = context; + const {bar} = context; + return ; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-nested-destructuring.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-nested-destructuring.expect.md new file mode 100644 index 0000000000000..8f4ec58c6de89 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-nested-destructuring.expect.md @@ -0,0 +1,37 @@ + +## Input + +```javascript +// @enableLowerContextAccess +function App() { + const { + joe: {foo}, + bar, + } = useContext(MyContext); + return ; +} + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; // @enableLowerContextAccess +function App() { + const $ = _c(3); + const { joe: t0, bar } = useContext(MyContext); + const { foo } = t0; + let t1; + if ($[0] !== foo || $[1] !== bar) { + t1 = ; + $[0] = foo; + $[1] = bar; + $[2] = t1; + } else { + t1 = $[2]; + } + return t1; +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-nested-destructuring.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-nested-destructuring.js new file mode 100644 index 0000000000000..ceecaaaaffb43 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-nested-destructuring.js @@ -0,0 +1,8 @@ +// @enableLowerContextAccess +function App() { + const { + joe: {foo}, + bar, + } = useContext(MyContext); + return ; +} diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-property-load.expect.md b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-property-load.expect.md new file mode 100644 index 0000000000000..67350a6ee0340 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-property-load.expect.md @@ -0,0 +1,37 @@ + +## Input + +```javascript +// @enableLowerContextAccess +function App() { + const context = useContext(MyContext); + const foo = context.foo; + const bar = context.bar; + return ; +} + +``` + +## Code + +```javascript +import { c as _c } from "react/compiler-runtime"; // @enableLowerContextAccess +function App() { + const $ = _c(3); + const context = useContext(MyContext); + const foo = context.foo; + const bar = context.bar; + let t0; + if ($[0] !== foo || $[1] !== bar) { + t0 = ; + $[0] = foo; + $[1] = bar; + $[2] = t0; + } else { + t0 = $[2]; + } + return t0; +} + +``` + \ No newline at end of file diff --git a/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-property-load.js b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-property-load.js new file mode 100644 index 0000000000000..9bc2bfadda871 --- /dev/null +++ b/compiler/packages/babel-plugin-react-compiler/src/__tests__/fixtures/compiler/todo.lower-context-access-property-load.js @@ -0,0 +1,7 @@ +// @enableLowerContextAccess +function App() { + const context = useContext(MyContext); + const foo = context.foo; + const bar = context.bar; + return ; +} diff --git a/compiler/packages/snap/src/SproutTodoFilter.ts b/compiler/packages/snap/src/SproutTodoFilter.ts index 8e7a50a629977..7bf35a4adb610 100644 --- a/compiler/packages/snap/src/SproutTodoFilter.ts +++ b/compiler/packages/snap/src/SproutTodoFilter.ts @@ -502,6 +502,14 @@ const skipFilter = new Set([ // needs to be executed as a module 'meta-property', + + // needs context lowering support in React + 'todo.lower-context-access-property-load', + 'todo.lower-context-access-nested-destructuring', + 'todo.lower-context-access-mixed-array-obj', + 'todo.lower-context-access-destructure-multiple', + 'todo.lower-context-access-array-destructuring', + 'lower-context-selector-simple', ]); export default skipFilter;