Skip to content

Commit 20d7ab6

Browse files
committed
logic reasesment
1 parent d16b252 commit 20d7ab6

1 file changed

Lines changed: 60 additions & 66 deletions

File tree

compiler/packages/babel-plugin-react-compiler/src/Validation/ValidateNoSetStateInEffects.ts

Lines changed: 60 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -50,85 +50,79 @@ export function validateNoSetStateInEffects(
5050
const errors = new CompilerError();
5151

5252
// In order to ensure that all HIR components that could contain setState have been iterated,
53-
// we run the reconnaissance logic until a stable number of state functions has been achieved.
54-
// this makes setState HIR analysis order independent.
55-
// We will then handle error on a separate pass.
56-
let iterationSize = Number.MAX_SAFE_INTEGER;
57-
while (iterationSize !== setStateFunctions.size) {
58-
iterationSize = setStateFunctions.size;
59-
for (const [, block] of fn.body.blocks) {
60-
for (const instr of block.instructions) {
61-
switch (instr.value.kind) {
62-
case 'LoadLocal': {
63-
if (setStateFunctions.has(instr.value.place.identifier.id)) {
64-
setStateFunctions.set(
65-
instr.lvalue.identifier.id,
66-
instr.value.place,
67-
);
68-
}
69-
break;
53+
// we fully run the reconnaissance logic, then handle error finding on a separate pass.
54+
// This makes setState HIR error analysis order independent.
55+
for (const [, block] of fn.body.blocks) {
56+
for (const instr of block.instructions) {
57+
switch (instr.value.kind) {
58+
case 'LoadLocal': {
59+
if (setStateFunctions.has(instr.value.place.identifier.id)) {
60+
setStateFunctions.set(
61+
instr.lvalue.identifier.id,
62+
instr.value.place,
63+
);
7064
}
71-
case 'StoreLocal': {
72-
if (setStateFunctions.has(instr.value.value.identifier.id)) {
73-
setStateFunctions.set(
74-
instr.value.lvalue.place.identifier.id,
75-
instr.value.value,
76-
);
77-
setStateFunctions.set(
78-
instr.lvalue.identifier.id,
79-
instr.value.value,
80-
);
81-
}
82-
break;
65+
break;
66+
}
67+
case 'StoreLocal': {
68+
if (setStateFunctions.has(instr.value.value.identifier.id)) {
69+
setStateFunctions.set(
70+
instr.value.lvalue.place.identifier.id,
71+
instr.value.value,
72+
);
73+
setStateFunctions.set(
74+
instr.lvalue.identifier.id,
75+
instr.value.value,
76+
);
8377
}
84-
case 'FunctionExpression': {
85-
if (
86-
// faster-path to check if the function expression references a setState
87-
[...eachInstructionValueOperand(instr.value)].some(
88-
operand =>
89-
isSetStateType(operand.identifier) ||
90-
setStateFunctions.has(operand.identifier.id),
91-
)
92-
) {
93-
const callee = getSetStateCall(
94-
instr.value.loweredFunc.func,
95-
setStateFunctions,
96-
env,
97-
);
98-
if (callee !== null) {
99-
setStateFunctions.set(instr.lvalue.identifier.id, callee);
100-
}
78+
break;
79+
}
80+
case 'FunctionExpression': {
81+
if (
82+
// faster-path to check if the function expression references a setState
83+
[...eachInstructionValueOperand(instr.value)].some(
84+
operand =>
85+
isSetStateType(operand.identifier) ||
86+
setStateFunctions.has(operand.identifier.id),
87+
)
88+
) {
89+
const callee = getSetStateCall(
90+
instr.value.loweredFunc.func,
91+
setStateFunctions,
92+
env,
93+
);
94+
if (callee !== null) {
95+
setStateFunctions.set(instr.lvalue.identifier.id, callee);
10196
}
102-
break;
10397
}
104-
case 'MethodCall':
105-
case 'CallExpression': {
106-
const callee =
107-
instr.value.kind === 'MethodCall'
108-
? instr.value.property
109-
: instr.value.callee;
98+
break;
99+
}
100+
case 'MethodCall':
101+
case 'CallExpression': {
102+
const callee =
103+
instr.value.kind === 'MethodCall'
104+
? instr.value.property
105+
: instr.value.callee;
110106

111-
if (isUseEffectEventType(callee.identifier)) {
112-
const arg = instr.value.args[0];
113-
if (arg !== undefined && arg.kind === 'Identifier') {
114-
const setState = setStateFunctions.get(arg.identifier.id);
115-
if (setState !== undefined) {
116-
/**
117-
* This effect event function calls setState synchonously,
118-
* treat it as a setState function for transitive tracking
119-
*/
120-
setStateFunctions.set(instr.lvalue.identifier.id, setState);
121-
}
107+
if (isUseEffectEventType(callee.identifier)) {
108+
const arg = instr.value.args[0];
109+
if (arg !== undefined && arg.kind === 'Identifier') {
110+
const setState = setStateFunctions.get(arg.identifier.id);
111+
if (setState !== undefined) {
112+
/**
113+
* This effect event function calls setState synchonously,
114+
* treat it as a setState function for transitive tracking
115+
*/
116+
setStateFunctions.set(instr.lvalue.identifier.id, setState);
122117
}
123118
}
124-
break;
125119
}
120+
break;
126121
}
127122
}
128123
}
129124
}
130125

131-
// Report errors in second pass to ensure HIR has been fully evaluated at error reporting time.
132126
for (const [, block] of fn.body.blocks) {
133127
for (const instr of block.instructions) {
134128
if (

0 commit comments

Comments
 (0)