Skip to content

Commit 23f5a8a

Browse files
committed
.
1 parent f508edc commit 23f5a8a

File tree

4 files changed

+44
-3
lines changed

4 files changed

+44
-3
lines changed

compiler/packages/babel-plugin-react-compiler/src/HIR/Environment.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -650,6 +650,14 @@ export const EnvironmentConfigSchema = z.object({
650650
* useMemo(() => { ... }, [...]);
651651
*/
652652
validateNoVoidUseMemo: z.boolean().default(false),
653+
654+
/**
655+
* A list of function identifier names that should never be skipped by
656+
* memoization/flattening optimizations. Calls to any identifier with a name
657+
* in this list behave like the `use` operator in terms of never being
658+
* skipped, and may be called conditionally.
659+
*/
660+
neverSkipFunctionName: z.array(z.string()).default([]),
653661
});
654662

655663
export type EnvironmentConfig = z.infer<typeof EnvironmentConfigSchema>;

compiler/packages/babel-plugin-react-compiler/src/HIR/HIR.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1915,6 +1915,34 @@ export function isUseOperator(id: Identifier): boolean {
19151915
);
19161916
}
19171917

1918+
/**
1919+
* Treat any call with a neverSkip identifier name similar to the `use` operator:
1920+
* - It may be called conditionally.
1921+
* - It should never be skipped by memoization/flattening logic.
1922+
*/
1923+
export function isNeverSkipIdentifier(
1924+
env: Environment,
1925+
id: Identifier,
1926+
): boolean {
1927+
const list = env.config.neverSkipFunctionName;
1928+
if (list == null || list.length === 0) {
1929+
return false;
1930+
}
1931+
if (id.name != null && list.includes(id.name.value)) {
1932+
return true;
1933+
}
1934+
const loc = id.loc as any;
1935+
if (
1936+
loc &&
1937+
typeof loc !== 'symbol' &&
1938+
typeof loc.identifierName === 'string' &&
1939+
list.includes(loc.identifierName)
1940+
) {
1941+
return true;
1942+
}
1943+
return false;
1944+
}
1945+
19181946
export function getHookKindForType(
19191947
env: Environment,
19201948
type: Type,

compiler/packages/babel-plugin-react-compiler/src/Inference/InferReactivePlaces.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
isStableType,
2222
isStableTypeContainer,
2323
isUseOperator,
24+
isNeverSkipIdentifier,
2425
} from '../HIR';
2526
import {PostDominator} from '../HIR/Dominator';
2627
import {
@@ -302,13 +303,15 @@ export function inferReactivePlaces(fn: HIRFunction): void {
302303
if (
303304
value.kind === 'CallExpression' &&
304305
(getHookKind(fn.env, value.callee.identifier) != null ||
305-
isUseOperator(value.callee.identifier))
306+
isUseOperator(value.callee.identifier) ||
307+
isNeverSkipIdentifier(fn.env, value.callee.identifier))
306308
) {
307309
hasReactiveInput = true;
308310
} else if (
309311
value.kind === 'MethodCall' &&
310312
(getHookKind(fn.env, value.property.identifier) != null ||
311-
isUseOperator(value.property.identifier))
313+
isUseOperator(value.property.identifier) ||
314+
isNeverSkipIdentifier(fn.env, value.property.identifier))
312315
) {
313316
hasReactiveInput = true;
314317
}

compiler/packages/babel-plugin-react-compiler/src/ReactiveScopes/FlattenScopesWithHooksOrUseHIR.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
PrunedScopeTerminal,
1414
getHookKind,
1515
isUseOperator,
16+
isNeverSkipIdentifier,
1617
} from '../HIR';
1718
import {retainWhere} from '../Utils/utils';
1819

@@ -53,7 +54,8 @@ export function flattenScopesWithHooksOrUseHIR(fn: HIRFunction): void {
5354
value.kind === 'MethodCall' ? value.property : value.callee;
5455
if (
5556
getHookKind(fn.env, callee.identifier) != null ||
56-
isUseOperator(callee.identifier)
57+
isUseOperator(callee.identifier) ||
58+
isNeverSkipIdentifier(fn.env, callee.identifier)
5759
) {
5860
prune.push(...activeScopes.map(entry => entry.block));
5961
activeScopes.length = 0;

0 commit comments

Comments
 (0)