eslint-plugin-react-hooks 7.0.0-canary-6160773f-20251023 → 7.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -17648,6 +17648,10 @@ function hasOwnProperty$1(obj, key) {
|
|
|
17648
17648
|
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
17649
17649
|
}
|
|
17650
17650
|
|
|
17651
|
+
const CODEFRAME_LINES_ABOVE = 2;
|
|
17652
|
+
const CODEFRAME_LINES_BELOW = 3;
|
|
17653
|
+
const CODEFRAME_MAX_LINES = 10;
|
|
17654
|
+
const CODEFRAME_ABBREVIATED_SOURCE_LINES = 5;
|
|
17651
17655
|
var ErrorSeverity;
|
|
17652
17656
|
(function (ErrorSeverity) {
|
|
17653
17657
|
ErrorSeverity["Error"] = "Error";
|
|
@@ -17964,7 +17968,7 @@ class CompilerError extends Error {
|
|
|
17964
17968
|
}
|
|
17965
17969
|
}
|
|
17966
17970
|
function printCodeFrame(source, loc, message) {
|
|
17967
|
-
|
|
17971
|
+
const printed = libExports.codeFrameColumns(source, {
|
|
17968
17972
|
start: {
|
|
17969
17973
|
line: loc.start.line,
|
|
17970
17974
|
column: loc.start.column + 1,
|
|
@@ -17975,7 +17979,19 @@ function printCodeFrame(source, loc, message) {
|
|
|
17975
17979
|
},
|
|
17976
17980
|
}, {
|
|
17977
17981
|
message,
|
|
17982
|
+
linesAbove: CODEFRAME_LINES_ABOVE,
|
|
17983
|
+
linesBelow: CODEFRAME_LINES_BELOW,
|
|
17978
17984
|
});
|
|
17985
|
+
const lines = printed.split(/\r?\n/);
|
|
17986
|
+
if (loc.end.line - loc.start.line < CODEFRAME_MAX_LINES) {
|
|
17987
|
+
return printed;
|
|
17988
|
+
}
|
|
17989
|
+
const pipeIndex = lines[0].indexOf('|');
|
|
17990
|
+
return [
|
|
17991
|
+
...lines.slice(0, CODEFRAME_LINES_ABOVE + CODEFRAME_ABBREVIATED_SOURCE_LINES),
|
|
17992
|
+
' '.repeat(pipeIndex) + '…',
|
|
17993
|
+
...lines.slice(-(CODEFRAME_LINES_BELOW + CODEFRAME_ABBREVIATED_SOURCE_LINES)),
|
|
17994
|
+
].join('\n');
|
|
17979
17995
|
}
|
|
17980
17996
|
function printErrorSummary(category, message) {
|
|
17981
17997
|
let heading;
|
|
@@ -32096,6 +32112,7 @@ const EnvironmentConfigSchema = v4.z.object({
|
|
|
32096
32112
|
validateNoSetStateInRender: v4.z.boolean().default(true),
|
|
32097
32113
|
validateNoSetStateInEffects: v4.z.boolean().default(false),
|
|
32098
32114
|
validateNoDerivedComputationsInEffects: v4.z.boolean().default(false),
|
|
32115
|
+
validateNoDerivedComputationsInEffects_exp: v4.z.boolean().default(false),
|
|
32099
32116
|
validateNoJSXInTryStatements: v4.z.boolean().default(false),
|
|
32100
32117
|
validateStaticComponents: v4.z.boolean().default(false),
|
|
32101
32118
|
validateMemoizedEffectDependencies: v4.z.boolean().default(false),
|
|
@@ -52038,7 +52055,7 @@ function validateNoDerivedComputationsInEffects(fn) {
|
|
|
52038
52055
|
});
|
|
52039
52056
|
return (_a = locals.get(dep.identifier.id)) !== null && _a !== void 0 ? _a : dep.identifier.id;
|
|
52040
52057
|
});
|
|
52041
|
-
validateEffect(effectFunction.loweredFunc.func, dependencies, errors);
|
|
52058
|
+
validateEffect$1(effectFunction.loweredFunc.func, dependencies, errors);
|
|
52042
52059
|
}
|
|
52043
52060
|
}
|
|
52044
52061
|
}
|
|
@@ -52048,7 +52065,7 @@ function validateNoDerivedComputationsInEffects(fn) {
|
|
|
52048
52065
|
throw errors;
|
|
52049
52066
|
}
|
|
52050
52067
|
}
|
|
52051
|
-
function validateEffect(effectFunction, effectDeps, errors) {
|
|
52068
|
+
function validateEffect$1(effectFunction, effectDeps, errors) {
|
|
52052
52069
|
for (const operand of effectFunction.context) {
|
|
52053
52070
|
if (isSetStateType(operand.identifier)) {
|
|
52054
52071
|
continue;
|
|
@@ -52161,6 +52178,339 @@ function validateEffect(effectFunction, effectDeps, errors) {
|
|
|
52161
52178
|
}
|
|
52162
52179
|
}
|
|
52163
52180
|
|
|
52181
|
+
class DerivationCache {
|
|
52182
|
+
constructor() {
|
|
52183
|
+
this.hasChanges = false;
|
|
52184
|
+
this.cache = new Map();
|
|
52185
|
+
}
|
|
52186
|
+
snapshot() {
|
|
52187
|
+
const hasChanges = this.hasChanges;
|
|
52188
|
+
this.hasChanges = false;
|
|
52189
|
+
return hasChanges;
|
|
52190
|
+
}
|
|
52191
|
+
addDerivationEntry(derivedVar, sourcesIds, typeOfValue) {
|
|
52192
|
+
var _a, _b;
|
|
52193
|
+
let newValue = {
|
|
52194
|
+
place: derivedVar,
|
|
52195
|
+
sourcesIds: new Set(),
|
|
52196
|
+
typeOfValue: typeOfValue !== null && typeOfValue !== void 0 ? typeOfValue : 'ignored',
|
|
52197
|
+
};
|
|
52198
|
+
if (sourcesIds !== undefined) {
|
|
52199
|
+
for (const id of sourcesIds) {
|
|
52200
|
+
const sourcePlace = (_a = this.cache.get(id)) === null || _a === void 0 ? void 0 : _a.place;
|
|
52201
|
+
if (sourcePlace === undefined) {
|
|
52202
|
+
continue;
|
|
52203
|
+
}
|
|
52204
|
+
if (sourcePlace.identifier.name === null ||
|
|
52205
|
+
((_b = sourcePlace.identifier.name) === null || _b === void 0 ? void 0 : _b.kind) === 'promoted') {
|
|
52206
|
+
newValue.sourcesIds.add(derivedVar.identifier.id);
|
|
52207
|
+
}
|
|
52208
|
+
else {
|
|
52209
|
+
newValue.sourcesIds.add(sourcePlace.identifier.id);
|
|
52210
|
+
}
|
|
52211
|
+
}
|
|
52212
|
+
}
|
|
52213
|
+
if (newValue.sourcesIds.size === 0) {
|
|
52214
|
+
newValue.sourcesIds.add(derivedVar.identifier.id);
|
|
52215
|
+
}
|
|
52216
|
+
const existingValue = this.cache.get(derivedVar.identifier.id);
|
|
52217
|
+
if (existingValue === undefined ||
|
|
52218
|
+
!this.isDerivationEqual(existingValue, newValue)) {
|
|
52219
|
+
this.cache.set(derivedVar.identifier.id, newValue);
|
|
52220
|
+
this.hasChanges = true;
|
|
52221
|
+
}
|
|
52222
|
+
}
|
|
52223
|
+
isDerivationEqual(a, b) {
|
|
52224
|
+
if (a.typeOfValue !== b.typeOfValue) {
|
|
52225
|
+
return false;
|
|
52226
|
+
}
|
|
52227
|
+
if (a.sourcesIds.size !== b.sourcesIds.size) {
|
|
52228
|
+
return false;
|
|
52229
|
+
}
|
|
52230
|
+
for (const id of a.sourcesIds) {
|
|
52231
|
+
if (!b.sourcesIds.has(id)) {
|
|
52232
|
+
return false;
|
|
52233
|
+
}
|
|
52234
|
+
}
|
|
52235
|
+
return true;
|
|
52236
|
+
}
|
|
52237
|
+
}
|
|
52238
|
+
function validateNoDerivedComputationsInEffects_exp(fn) {
|
|
52239
|
+
const functions = new Map();
|
|
52240
|
+
const derivationCache = new DerivationCache();
|
|
52241
|
+
const errors = new CompilerError();
|
|
52242
|
+
const effects = new Set();
|
|
52243
|
+
const setStateCache = new Map();
|
|
52244
|
+
const effectSetStateCache = new Map();
|
|
52245
|
+
const context = {
|
|
52246
|
+
functions,
|
|
52247
|
+
errors,
|
|
52248
|
+
derivationCache,
|
|
52249
|
+
effects,
|
|
52250
|
+
setStateCache,
|
|
52251
|
+
effectSetStateCache,
|
|
52252
|
+
};
|
|
52253
|
+
if (fn.fnType === 'Hook') {
|
|
52254
|
+
for (const param of fn.params) {
|
|
52255
|
+
if (param.kind === 'Identifier') {
|
|
52256
|
+
context.derivationCache.cache.set(param.identifier.id, {
|
|
52257
|
+
place: param,
|
|
52258
|
+
sourcesIds: new Set([param.identifier.id]),
|
|
52259
|
+
typeOfValue: 'fromProps',
|
|
52260
|
+
});
|
|
52261
|
+
context.derivationCache.hasChanges = true;
|
|
52262
|
+
}
|
|
52263
|
+
}
|
|
52264
|
+
}
|
|
52265
|
+
else if (fn.fnType === 'Component') {
|
|
52266
|
+
const props = fn.params[0];
|
|
52267
|
+
if (props != null && props.kind === 'Identifier') {
|
|
52268
|
+
context.derivationCache.cache.set(props.identifier.id, {
|
|
52269
|
+
place: props,
|
|
52270
|
+
sourcesIds: new Set([props.identifier.id]),
|
|
52271
|
+
typeOfValue: 'fromProps',
|
|
52272
|
+
});
|
|
52273
|
+
context.derivationCache.hasChanges = true;
|
|
52274
|
+
}
|
|
52275
|
+
}
|
|
52276
|
+
let isFirstPass = true;
|
|
52277
|
+
do {
|
|
52278
|
+
for (const block of fn.body.blocks.values()) {
|
|
52279
|
+
recordPhiDerivations(block, context);
|
|
52280
|
+
for (const instr of block.instructions) {
|
|
52281
|
+
recordInstructionDerivations(instr, context, isFirstPass);
|
|
52282
|
+
}
|
|
52283
|
+
}
|
|
52284
|
+
isFirstPass = false;
|
|
52285
|
+
} while (context.derivationCache.snapshot());
|
|
52286
|
+
for (const effect of effects) {
|
|
52287
|
+
validateEffect(effect, context);
|
|
52288
|
+
}
|
|
52289
|
+
if (errors.hasAnyErrors()) {
|
|
52290
|
+
throw errors;
|
|
52291
|
+
}
|
|
52292
|
+
}
|
|
52293
|
+
function recordPhiDerivations(block, context) {
|
|
52294
|
+
for (const phi of block.phis) {
|
|
52295
|
+
let typeOfValue = 'ignored';
|
|
52296
|
+
let sourcesIds = new Set();
|
|
52297
|
+
for (const operand of phi.operands.values()) {
|
|
52298
|
+
const operandMetadata = context.derivationCache.cache.get(operand.identifier.id);
|
|
52299
|
+
if (operandMetadata === undefined) {
|
|
52300
|
+
continue;
|
|
52301
|
+
}
|
|
52302
|
+
typeOfValue = joinValue(typeOfValue, operandMetadata.typeOfValue);
|
|
52303
|
+
sourcesIds.add(operand.identifier.id);
|
|
52304
|
+
}
|
|
52305
|
+
if (typeOfValue !== 'ignored') {
|
|
52306
|
+
context.derivationCache.addDerivationEntry(phi.place, sourcesIds, typeOfValue);
|
|
52307
|
+
}
|
|
52308
|
+
}
|
|
52309
|
+
}
|
|
52310
|
+
function joinValue(lvalueType, valueType) {
|
|
52311
|
+
if (lvalueType === 'ignored')
|
|
52312
|
+
return valueType;
|
|
52313
|
+
if (valueType === 'ignored')
|
|
52314
|
+
return lvalueType;
|
|
52315
|
+
if (lvalueType === valueType)
|
|
52316
|
+
return lvalueType;
|
|
52317
|
+
return 'fromPropsAndState';
|
|
52318
|
+
}
|
|
52319
|
+
function recordInstructionDerivations(instr, context, isFirstPass) {
|
|
52320
|
+
let typeOfValue = 'ignored';
|
|
52321
|
+
const sources = new Set();
|
|
52322
|
+
const { lvalue, value } = instr;
|
|
52323
|
+
if (value.kind === 'FunctionExpression') {
|
|
52324
|
+
context.functions.set(lvalue.identifier.id, value);
|
|
52325
|
+
for (const [, block] of value.loweredFunc.func.body.blocks) {
|
|
52326
|
+
for (const instr of block.instructions) {
|
|
52327
|
+
recordInstructionDerivations(instr, context, isFirstPass);
|
|
52328
|
+
}
|
|
52329
|
+
}
|
|
52330
|
+
}
|
|
52331
|
+
else if (value.kind === 'CallExpression' || value.kind === 'MethodCall') {
|
|
52332
|
+
const callee = value.kind === 'CallExpression' ? value.callee : value.property;
|
|
52333
|
+
if (isUseEffectHookType(callee.identifier) &&
|
|
52334
|
+
value.args.length === 2 &&
|
|
52335
|
+
value.args[0].kind === 'Identifier' &&
|
|
52336
|
+
value.args[1].kind === 'Identifier') {
|
|
52337
|
+
const effectFunction = context.functions.get(value.args[0].identifier.id);
|
|
52338
|
+
if (effectFunction != null) {
|
|
52339
|
+
context.effects.add(effectFunction.loweredFunc.func);
|
|
52340
|
+
}
|
|
52341
|
+
}
|
|
52342
|
+
else if (isUseStateType(lvalue.identifier) && value.args.length > 0) {
|
|
52343
|
+
const stateValueSource = value.args[0];
|
|
52344
|
+
if (stateValueSource.kind === 'Identifier') {
|
|
52345
|
+
sources.add(stateValueSource.identifier.id);
|
|
52346
|
+
}
|
|
52347
|
+
typeOfValue = joinValue(typeOfValue, 'fromState');
|
|
52348
|
+
}
|
|
52349
|
+
}
|
|
52350
|
+
for (const operand of eachInstructionOperand(instr)) {
|
|
52351
|
+
if (isSetStateType(operand.identifier) &&
|
|
52352
|
+
operand.loc !== GeneratedSource &&
|
|
52353
|
+
isFirstPass) {
|
|
52354
|
+
if (context.setStateCache.has(operand.loc.identifierName)) {
|
|
52355
|
+
context.setStateCache.get(operand.loc.identifierName).push(operand);
|
|
52356
|
+
}
|
|
52357
|
+
else {
|
|
52358
|
+
context.setStateCache.set(operand.loc.identifierName, [operand]);
|
|
52359
|
+
}
|
|
52360
|
+
}
|
|
52361
|
+
const operandMetadata = context.derivationCache.cache.get(operand.identifier.id);
|
|
52362
|
+
if (operandMetadata === undefined) {
|
|
52363
|
+
continue;
|
|
52364
|
+
}
|
|
52365
|
+
typeOfValue = joinValue(typeOfValue, operandMetadata.typeOfValue);
|
|
52366
|
+
for (const id of operandMetadata.sourcesIds) {
|
|
52367
|
+
sources.add(id);
|
|
52368
|
+
}
|
|
52369
|
+
}
|
|
52370
|
+
if (typeOfValue === 'ignored') {
|
|
52371
|
+
return;
|
|
52372
|
+
}
|
|
52373
|
+
for (const lvalue of eachInstructionLValue(instr)) {
|
|
52374
|
+
context.derivationCache.addDerivationEntry(lvalue, sources, typeOfValue);
|
|
52375
|
+
}
|
|
52376
|
+
for (const operand of eachInstructionOperand(instr)) {
|
|
52377
|
+
switch (operand.effect) {
|
|
52378
|
+
case Effect.Capture:
|
|
52379
|
+
case Effect.Store:
|
|
52380
|
+
case Effect.ConditionallyMutate:
|
|
52381
|
+
case Effect.ConditionallyMutateIterator:
|
|
52382
|
+
case Effect.Mutate: {
|
|
52383
|
+
if (isMutable(instr, operand)) {
|
|
52384
|
+
context.derivationCache.addDerivationEntry(operand, sources, typeOfValue);
|
|
52385
|
+
}
|
|
52386
|
+
break;
|
|
52387
|
+
}
|
|
52388
|
+
case Effect.Freeze:
|
|
52389
|
+
case Effect.Read: {
|
|
52390
|
+
break;
|
|
52391
|
+
}
|
|
52392
|
+
case Effect.Unknown: {
|
|
52393
|
+
CompilerError.invariant(false, {
|
|
52394
|
+
reason: 'Unexpected unknown effect',
|
|
52395
|
+
description: null,
|
|
52396
|
+
details: [
|
|
52397
|
+
{
|
|
52398
|
+
kind: 'error',
|
|
52399
|
+
loc: operand.loc,
|
|
52400
|
+
message: 'Unexpected unknown effect',
|
|
52401
|
+
},
|
|
52402
|
+
],
|
|
52403
|
+
});
|
|
52404
|
+
}
|
|
52405
|
+
default: {
|
|
52406
|
+
assertExhaustive$1(operand.effect, `Unexpected effect kind \`${operand.effect}\``);
|
|
52407
|
+
}
|
|
52408
|
+
}
|
|
52409
|
+
}
|
|
52410
|
+
}
|
|
52411
|
+
function validateEffect(effectFunction, context) {
|
|
52412
|
+
const seenBlocks = new Set();
|
|
52413
|
+
const effectDerivedSetStateCalls = [];
|
|
52414
|
+
const globals = new Set();
|
|
52415
|
+
for (const block of effectFunction.body.blocks.values()) {
|
|
52416
|
+
for (const pred of block.preds) {
|
|
52417
|
+
if (!seenBlocks.has(pred)) {
|
|
52418
|
+
return;
|
|
52419
|
+
}
|
|
52420
|
+
}
|
|
52421
|
+
for (const instr of block.instructions) {
|
|
52422
|
+
if (isUseRefType(instr.lvalue.identifier)) {
|
|
52423
|
+
return;
|
|
52424
|
+
}
|
|
52425
|
+
for (const operand of eachInstructionOperand(instr)) {
|
|
52426
|
+
if (isSetStateType(operand.identifier) &&
|
|
52427
|
+
operand.loc !== GeneratedSource) {
|
|
52428
|
+
if (context.effectSetStateCache.has(operand.loc.identifierName)) {
|
|
52429
|
+
context.effectSetStateCache
|
|
52430
|
+
.get(operand.loc.identifierName)
|
|
52431
|
+
.push(operand);
|
|
52432
|
+
}
|
|
52433
|
+
else {
|
|
52434
|
+
context.effectSetStateCache.set(operand.loc.identifierName, [
|
|
52435
|
+
operand,
|
|
52436
|
+
]);
|
|
52437
|
+
}
|
|
52438
|
+
}
|
|
52439
|
+
}
|
|
52440
|
+
if (instr.value.kind === 'CallExpression' &&
|
|
52441
|
+
isSetStateType(instr.value.callee.identifier) &&
|
|
52442
|
+
instr.value.args.length === 1 &&
|
|
52443
|
+
instr.value.args[0].kind === 'Identifier') {
|
|
52444
|
+
const argMetadata = context.derivationCache.cache.get(instr.value.args[0].identifier.id);
|
|
52445
|
+
if (argMetadata !== undefined) {
|
|
52446
|
+
effectDerivedSetStateCalls.push({
|
|
52447
|
+
value: instr.value,
|
|
52448
|
+
loc: instr.value.callee.loc,
|
|
52449
|
+
sourceIds: argMetadata.sourcesIds,
|
|
52450
|
+
typeOfValue: argMetadata.typeOfValue,
|
|
52451
|
+
});
|
|
52452
|
+
}
|
|
52453
|
+
}
|
|
52454
|
+
else if (instr.value.kind === 'CallExpression') {
|
|
52455
|
+
const calleeMetadata = context.derivationCache.cache.get(instr.value.callee.identifier.id);
|
|
52456
|
+
if (calleeMetadata !== undefined &&
|
|
52457
|
+
(calleeMetadata.typeOfValue === 'fromProps' ||
|
|
52458
|
+
calleeMetadata.typeOfValue === 'fromPropsAndState')) {
|
|
52459
|
+
return;
|
|
52460
|
+
}
|
|
52461
|
+
if (globals.has(instr.value.callee.identifier.id)) {
|
|
52462
|
+
return;
|
|
52463
|
+
}
|
|
52464
|
+
}
|
|
52465
|
+
else if (instr.value.kind === 'LoadGlobal') {
|
|
52466
|
+
globals.add(instr.lvalue.identifier.id);
|
|
52467
|
+
for (const operand of eachInstructionOperand(instr)) {
|
|
52468
|
+
globals.add(operand.identifier.id);
|
|
52469
|
+
}
|
|
52470
|
+
}
|
|
52471
|
+
}
|
|
52472
|
+
seenBlocks.add(block.id);
|
|
52473
|
+
}
|
|
52474
|
+
for (const derivedSetStateCall of effectDerivedSetStateCalls) {
|
|
52475
|
+
if (derivedSetStateCall.loc !== GeneratedSource &&
|
|
52476
|
+
context.effectSetStateCache.has(derivedSetStateCall.loc.identifierName) &&
|
|
52477
|
+
context.setStateCache.has(derivedSetStateCall.loc.identifierName) &&
|
|
52478
|
+
context.effectSetStateCache.get(derivedSetStateCall.loc.identifierName)
|
|
52479
|
+
.length ===
|
|
52480
|
+
context.setStateCache.get(derivedSetStateCall.loc.identifierName)
|
|
52481
|
+
.length -
|
|
52482
|
+
1) {
|
|
52483
|
+
const derivedDepsStr = Array.from(derivedSetStateCall.sourceIds)
|
|
52484
|
+
.map(sourceId => {
|
|
52485
|
+
var _a;
|
|
52486
|
+
const sourceMetadata = context.derivationCache.cache.get(sourceId);
|
|
52487
|
+
return (_a = sourceMetadata === null || sourceMetadata === void 0 ? void 0 : sourceMetadata.place.identifier.name) === null || _a === void 0 ? void 0 : _a.value;
|
|
52488
|
+
})
|
|
52489
|
+
.filter(Boolean)
|
|
52490
|
+
.join(', ');
|
|
52491
|
+
let description;
|
|
52492
|
+
if (derivedSetStateCall.typeOfValue === 'fromProps') {
|
|
52493
|
+
description = `From props: [${derivedDepsStr}]`;
|
|
52494
|
+
}
|
|
52495
|
+
else if (derivedSetStateCall.typeOfValue === 'fromState') {
|
|
52496
|
+
description = `From local state: [${derivedDepsStr}]`;
|
|
52497
|
+
}
|
|
52498
|
+
else {
|
|
52499
|
+
description = `From props and local state: [${derivedDepsStr}]`;
|
|
52500
|
+
}
|
|
52501
|
+
context.errors.pushDiagnostic(CompilerDiagnostic.create({
|
|
52502
|
+
description: `Derived values (${description}) should be computed during render, rather than in effects. Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user`,
|
|
52503
|
+
category: ErrorCategory.EffectDerivationsOfState,
|
|
52504
|
+
reason: 'You might not need an effect. Derive values in render, not effects.',
|
|
52505
|
+
}).withDetails({
|
|
52506
|
+
kind: 'error',
|
|
52507
|
+
loc: derivedSetStateCall.value.callee.loc,
|
|
52508
|
+
message: 'This should be computed during render, not in an effect',
|
|
52509
|
+
}));
|
|
52510
|
+
}
|
|
52511
|
+
}
|
|
52512
|
+
}
|
|
52513
|
+
|
|
52164
52514
|
function nameAnonymousFunctions(fn) {
|
|
52165
52515
|
if (fn.id == null) {
|
|
52166
52516
|
return;
|
|
@@ -52402,6 +52752,9 @@ function runWithEnvironment(func, env) {
|
|
|
52402
52752
|
if (env.config.validateNoDerivedComputationsInEffects) {
|
|
52403
52753
|
validateNoDerivedComputationsInEffects(hir);
|
|
52404
52754
|
}
|
|
52755
|
+
if (env.config.validateNoDerivedComputationsInEffects_exp) {
|
|
52756
|
+
validateNoDerivedComputationsInEffects_exp(hir);
|
|
52757
|
+
}
|
|
52405
52758
|
if (env.config.validateNoSetStateInEffects) {
|
|
52406
52759
|
env.logErrors(validateNoSetStateInEffects(hir, env));
|
|
52407
52760
|
}
|
|
@@ -17639,6 +17639,10 @@ function hasOwnProperty$1(obj, key) {
|
|
|
17639
17639
|
return Object.prototype.hasOwnProperty.call(obj, key);
|
|
17640
17640
|
}
|
|
17641
17641
|
|
|
17642
|
+
const CODEFRAME_LINES_ABOVE = 2;
|
|
17643
|
+
const CODEFRAME_LINES_BELOW = 3;
|
|
17644
|
+
const CODEFRAME_MAX_LINES = 10;
|
|
17645
|
+
const CODEFRAME_ABBREVIATED_SOURCE_LINES = 5;
|
|
17642
17646
|
var ErrorSeverity;
|
|
17643
17647
|
(function (ErrorSeverity) {
|
|
17644
17648
|
ErrorSeverity["Error"] = "Error";
|
|
@@ -17955,7 +17959,7 @@ class CompilerError extends Error {
|
|
|
17955
17959
|
}
|
|
17956
17960
|
}
|
|
17957
17961
|
function printCodeFrame(source, loc, message) {
|
|
17958
|
-
|
|
17962
|
+
const printed = libExports.codeFrameColumns(source, {
|
|
17959
17963
|
start: {
|
|
17960
17964
|
line: loc.start.line,
|
|
17961
17965
|
column: loc.start.column + 1,
|
|
@@ -17966,7 +17970,19 @@ function printCodeFrame(source, loc, message) {
|
|
|
17966
17970
|
},
|
|
17967
17971
|
}, {
|
|
17968
17972
|
message,
|
|
17973
|
+
linesAbove: CODEFRAME_LINES_ABOVE,
|
|
17974
|
+
linesBelow: CODEFRAME_LINES_BELOW,
|
|
17969
17975
|
});
|
|
17976
|
+
const lines = printed.split(/\r?\n/);
|
|
17977
|
+
if (loc.end.line - loc.start.line < CODEFRAME_MAX_LINES) {
|
|
17978
|
+
return printed;
|
|
17979
|
+
}
|
|
17980
|
+
const pipeIndex = lines[0].indexOf('|');
|
|
17981
|
+
return [
|
|
17982
|
+
...lines.slice(0, CODEFRAME_LINES_ABOVE + CODEFRAME_ABBREVIATED_SOURCE_LINES),
|
|
17983
|
+
' '.repeat(pipeIndex) + '…',
|
|
17984
|
+
...lines.slice(-(CODEFRAME_LINES_BELOW + CODEFRAME_ABBREVIATED_SOURCE_LINES)),
|
|
17985
|
+
].join('\n');
|
|
17970
17986
|
}
|
|
17971
17987
|
function printErrorSummary(category, message) {
|
|
17972
17988
|
let heading;
|
|
@@ -31923,6 +31939,7 @@ const EnvironmentConfigSchema = v4.z.object({
|
|
|
31923
31939
|
validateNoSetStateInRender: v4.z.boolean().default(true),
|
|
31924
31940
|
validateNoSetStateInEffects: v4.z.boolean().default(false),
|
|
31925
31941
|
validateNoDerivedComputationsInEffects: v4.z.boolean().default(false),
|
|
31942
|
+
validateNoDerivedComputationsInEffects_exp: v4.z.boolean().default(false),
|
|
31926
31943
|
validateNoJSXInTryStatements: v4.z.boolean().default(false),
|
|
31927
31944
|
validateStaticComponents: v4.z.boolean().default(false),
|
|
31928
31945
|
validateMemoizedEffectDependencies: v4.z.boolean().default(false),
|
|
@@ -51865,7 +51882,7 @@ function validateNoDerivedComputationsInEffects(fn) {
|
|
|
51865
51882
|
});
|
|
51866
51883
|
return (_a = locals.get(dep.identifier.id)) !== null && _a !== void 0 ? _a : dep.identifier.id;
|
|
51867
51884
|
});
|
|
51868
|
-
validateEffect(effectFunction.loweredFunc.func, dependencies, errors);
|
|
51885
|
+
validateEffect$1(effectFunction.loweredFunc.func, dependencies, errors);
|
|
51869
51886
|
}
|
|
51870
51887
|
}
|
|
51871
51888
|
}
|
|
@@ -51875,7 +51892,7 @@ function validateNoDerivedComputationsInEffects(fn) {
|
|
|
51875
51892
|
throw errors;
|
|
51876
51893
|
}
|
|
51877
51894
|
}
|
|
51878
|
-
function validateEffect(effectFunction, effectDeps, errors) {
|
|
51895
|
+
function validateEffect$1(effectFunction, effectDeps, errors) {
|
|
51879
51896
|
for (const operand of effectFunction.context) {
|
|
51880
51897
|
if (isSetStateType(operand.identifier)) {
|
|
51881
51898
|
continue;
|
|
@@ -51988,6 +52005,339 @@ function validateEffect(effectFunction, effectDeps, errors) {
|
|
|
51988
52005
|
}
|
|
51989
52006
|
}
|
|
51990
52007
|
|
|
52008
|
+
class DerivationCache {
|
|
52009
|
+
constructor() {
|
|
52010
|
+
this.hasChanges = false;
|
|
52011
|
+
this.cache = new Map();
|
|
52012
|
+
}
|
|
52013
|
+
snapshot() {
|
|
52014
|
+
const hasChanges = this.hasChanges;
|
|
52015
|
+
this.hasChanges = false;
|
|
52016
|
+
return hasChanges;
|
|
52017
|
+
}
|
|
52018
|
+
addDerivationEntry(derivedVar, sourcesIds, typeOfValue) {
|
|
52019
|
+
var _a, _b;
|
|
52020
|
+
let newValue = {
|
|
52021
|
+
place: derivedVar,
|
|
52022
|
+
sourcesIds: new Set(),
|
|
52023
|
+
typeOfValue: typeOfValue !== null && typeOfValue !== void 0 ? typeOfValue : 'ignored',
|
|
52024
|
+
};
|
|
52025
|
+
if (sourcesIds !== undefined) {
|
|
52026
|
+
for (const id of sourcesIds) {
|
|
52027
|
+
const sourcePlace = (_a = this.cache.get(id)) === null || _a === void 0 ? void 0 : _a.place;
|
|
52028
|
+
if (sourcePlace === undefined) {
|
|
52029
|
+
continue;
|
|
52030
|
+
}
|
|
52031
|
+
if (sourcePlace.identifier.name === null ||
|
|
52032
|
+
((_b = sourcePlace.identifier.name) === null || _b === void 0 ? void 0 : _b.kind) === 'promoted') {
|
|
52033
|
+
newValue.sourcesIds.add(derivedVar.identifier.id);
|
|
52034
|
+
}
|
|
52035
|
+
else {
|
|
52036
|
+
newValue.sourcesIds.add(sourcePlace.identifier.id);
|
|
52037
|
+
}
|
|
52038
|
+
}
|
|
52039
|
+
}
|
|
52040
|
+
if (newValue.sourcesIds.size === 0) {
|
|
52041
|
+
newValue.sourcesIds.add(derivedVar.identifier.id);
|
|
52042
|
+
}
|
|
52043
|
+
const existingValue = this.cache.get(derivedVar.identifier.id);
|
|
52044
|
+
if (existingValue === undefined ||
|
|
52045
|
+
!this.isDerivationEqual(existingValue, newValue)) {
|
|
52046
|
+
this.cache.set(derivedVar.identifier.id, newValue);
|
|
52047
|
+
this.hasChanges = true;
|
|
52048
|
+
}
|
|
52049
|
+
}
|
|
52050
|
+
isDerivationEqual(a, b) {
|
|
52051
|
+
if (a.typeOfValue !== b.typeOfValue) {
|
|
52052
|
+
return false;
|
|
52053
|
+
}
|
|
52054
|
+
if (a.sourcesIds.size !== b.sourcesIds.size) {
|
|
52055
|
+
return false;
|
|
52056
|
+
}
|
|
52057
|
+
for (const id of a.sourcesIds) {
|
|
52058
|
+
if (!b.sourcesIds.has(id)) {
|
|
52059
|
+
return false;
|
|
52060
|
+
}
|
|
52061
|
+
}
|
|
52062
|
+
return true;
|
|
52063
|
+
}
|
|
52064
|
+
}
|
|
52065
|
+
function validateNoDerivedComputationsInEffects_exp(fn) {
|
|
52066
|
+
const functions = new Map();
|
|
52067
|
+
const derivationCache = new DerivationCache();
|
|
52068
|
+
const errors = new CompilerError();
|
|
52069
|
+
const effects = new Set();
|
|
52070
|
+
const setStateCache = new Map();
|
|
52071
|
+
const effectSetStateCache = new Map();
|
|
52072
|
+
const context = {
|
|
52073
|
+
functions,
|
|
52074
|
+
errors,
|
|
52075
|
+
derivationCache,
|
|
52076
|
+
effects,
|
|
52077
|
+
setStateCache,
|
|
52078
|
+
effectSetStateCache,
|
|
52079
|
+
};
|
|
52080
|
+
if (fn.fnType === 'Hook') {
|
|
52081
|
+
for (const param of fn.params) {
|
|
52082
|
+
if (param.kind === 'Identifier') {
|
|
52083
|
+
context.derivationCache.cache.set(param.identifier.id, {
|
|
52084
|
+
place: param,
|
|
52085
|
+
sourcesIds: new Set([param.identifier.id]),
|
|
52086
|
+
typeOfValue: 'fromProps',
|
|
52087
|
+
});
|
|
52088
|
+
context.derivationCache.hasChanges = true;
|
|
52089
|
+
}
|
|
52090
|
+
}
|
|
52091
|
+
}
|
|
52092
|
+
else if (fn.fnType === 'Component') {
|
|
52093
|
+
const props = fn.params[0];
|
|
52094
|
+
if (props != null && props.kind === 'Identifier') {
|
|
52095
|
+
context.derivationCache.cache.set(props.identifier.id, {
|
|
52096
|
+
place: props,
|
|
52097
|
+
sourcesIds: new Set([props.identifier.id]),
|
|
52098
|
+
typeOfValue: 'fromProps',
|
|
52099
|
+
});
|
|
52100
|
+
context.derivationCache.hasChanges = true;
|
|
52101
|
+
}
|
|
52102
|
+
}
|
|
52103
|
+
let isFirstPass = true;
|
|
52104
|
+
do {
|
|
52105
|
+
for (const block of fn.body.blocks.values()) {
|
|
52106
|
+
recordPhiDerivations(block, context);
|
|
52107
|
+
for (const instr of block.instructions) {
|
|
52108
|
+
recordInstructionDerivations(instr, context, isFirstPass);
|
|
52109
|
+
}
|
|
52110
|
+
}
|
|
52111
|
+
isFirstPass = false;
|
|
52112
|
+
} while (context.derivationCache.snapshot());
|
|
52113
|
+
for (const effect of effects) {
|
|
52114
|
+
validateEffect(effect, context);
|
|
52115
|
+
}
|
|
52116
|
+
if (errors.hasAnyErrors()) {
|
|
52117
|
+
throw errors;
|
|
52118
|
+
}
|
|
52119
|
+
}
|
|
52120
|
+
function recordPhiDerivations(block, context) {
|
|
52121
|
+
for (const phi of block.phis) {
|
|
52122
|
+
let typeOfValue = 'ignored';
|
|
52123
|
+
let sourcesIds = new Set();
|
|
52124
|
+
for (const operand of phi.operands.values()) {
|
|
52125
|
+
const operandMetadata = context.derivationCache.cache.get(operand.identifier.id);
|
|
52126
|
+
if (operandMetadata === undefined) {
|
|
52127
|
+
continue;
|
|
52128
|
+
}
|
|
52129
|
+
typeOfValue = joinValue(typeOfValue, operandMetadata.typeOfValue);
|
|
52130
|
+
sourcesIds.add(operand.identifier.id);
|
|
52131
|
+
}
|
|
52132
|
+
if (typeOfValue !== 'ignored') {
|
|
52133
|
+
context.derivationCache.addDerivationEntry(phi.place, sourcesIds, typeOfValue);
|
|
52134
|
+
}
|
|
52135
|
+
}
|
|
52136
|
+
}
|
|
52137
|
+
function joinValue(lvalueType, valueType) {
|
|
52138
|
+
if (lvalueType === 'ignored')
|
|
52139
|
+
return valueType;
|
|
52140
|
+
if (valueType === 'ignored')
|
|
52141
|
+
return lvalueType;
|
|
52142
|
+
if (lvalueType === valueType)
|
|
52143
|
+
return lvalueType;
|
|
52144
|
+
return 'fromPropsAndState';
|
|
52145
|
+
}
|
|
52146
|
+
function recordInstructionDerivations(instr, context, isFirstPass) {
|
|
52147
|
+
let typeOfValue = 'ignored';
|
|
52148
|
+
const sources = new Set();
|
|
52149
|
+
const { lvalue, value } = instr;
|
|
52150
|
+
if (value.kind === 'FunctionExpression') {
|
|
52151
|
+
context.functions.set(lvalue.identifier.id, value);
|
|
52152
|
+
for (const [, block] of value.loweredFunc.func.body.blocks) {
|
|
52153
|
+
for (const instr of block.instructions) {
|
|
52154
|
+
recordInstructionDerivations(instr, context, isFirstPass);
|
|
52155
|
+
}
|
|
52156
|
+
}
|
|
52157
|
+
}
|
|
52158
|
+
else if (value.kind === 'CallExpression' || value.kind === 'MethodCall') {
|
|
52159
|
+
const callee = value.kind === 'CallExpression' ? value.callee : value.property;
|
|
52160
|
+
if (isUseEffectHookType(callee.identifier) &&
|
|
52161
|
+
value.args.length === 2 &&
|
|
52162
|
+
value.args[0].kind === 'Identifier' &&
|
|
52163
|
+
value.args[1].kind === 'Identifier') {
|
|
52164
|
+
const effectFunction = context.functions.get(value.args[0].identifier.id);
|
|
52165
|
+
if (effectFunction != null) {
|
|
52166
|
+
context.effects.add(effectFunction.loweredFunc.func);
|
|
52167
|
+
}
|
|
52168
|
+
}
|
|
52169
|
+
else if (isUseStateType(lvalue.identifier) && value.args.length > 0) {
|
|
52170
|
+
const stateValueSource = value.args[0];
|
|
52171
|
+
if (stateValueSource.kind === 'Identifier') {
|
|
52172
|
+
sources.add(stateValueSource.identifier.id);
|
|
52173
|
+
}
|
|
52174
|
+
typeOfValue = joinValue(typeOfValue, 'fromState');
|
|
52175
|
+
}
|
|
52176
|
+
}
|
|
52177
|
+
for (const operand of eachInstructionOperand(instr)) {
|
|
52178
|
+
if (isSetStateType(operand.identifier) &&
|
|
52179
|
+
operand.loc !== GeneratedSource &&
|
|
52180
|
+
isFirstPass) {
|
|
52181
|
+
if (context.setStateCache.has(operand.loc.identifierName)) {
|
|
52182
|
+
context.setStateCache.get(operand.loc.identifierName).push(operand);
|
|
52183
|
+
}
|
|
52184
|
+
else {
|
|
52185
|
+
context.setStateCache.set(operand.loc.identifierName, [operand]);
|
|
52186
|
+
}
|
|
52187
|
+
}
|
|
52188
|
+
const operandMetadata = context.derivationCache.cache.get(operand.identifier.id);
|
|
52189
|
+
if (operandMetadata === undefined) {
|
|
52190
|
+
continue;
|
|
52191
|
+
}
|
|
52192
|
+
typeOfValue = joinValue(typeOfValue, operandMetadata.typeOfValue);
|
|
52193
|
+
for (const id of operandMetadata.sourcesIds) {
|
|
52194
|
+
sources.add(id);
|
|
52195
|
+
}
|
|
52196
|
+
}
|
|
52197
|
+
if (typeOfValue === 'ignored') {
|
|
52198
|
+
return;
|
|
52199
|
+
}
|
|
52200
|
+
for (const lvalue of eachInstructionLValue(instr)) {
|
|
52201
|
+
context.derivationCache.addDerivationEntry(lvalue, sources, typeOfValue);
|
|
52202
|
+
}
|
|
52203
|
+
for (const operand of eachInstructionOperand(instr)) {
|
|
52204
|
+
switch (operand.effect) {
|
|
52205
|
+
case Effect.Capture:
|
|
52206
|
+
case Effect.Store:
|
|
52207
|
+
case Effect.ConditionallyMutate:
|
|
52208
|
+
case Effect.ConditionallyMutateIterator:
|
|
52209
|
+
case Effect.Mutate: {
|
|
52210
|
+
if (isMutable(instr, operand)) {
|
|
52211
|
+
context.derivationCache.addDerivationEntry(operand, sources, typeOfValue);
|
|
52212
|
+
}
|
|
52213
|
+
break;
|
|
52214
|
+
}
|
|
52215
|
+
case Effect.Freeze:
|
|
52216
|
+
case Effect.Read: {
|
|
52217
|
+
break;
|
|
52218
|
+
}
|
|
52219
|
+
case Effect.Unknown: {
|
|
52220
|
+
CompilerError.invariant(false, {
|
|
52221
|
+
reason: 'Unexpected unknown effect',
|
|
52222
|
+
description: null,
|
|
52223
|
+
details: [
|
|
52224
|
+
{
|
|
52225
|
+
kind: 'error',
|
|
52226
|
+
loc: operand.loc,
|
|
52227
|
+
message: 'Unexpected unknown effect',
|
|
52228
|
+
},
|
|
52229
|
+
],
|
|
52230
|
+
});
|
|
52231
|
+
}
|
|
52232
|
+
default: {
|
|
52233
|
+
assertExhaustive$1(operand.effect, `Unexpected effect kind \`${operand.effect}\``);
|
|
52234
|
+
}
|
|
52235
|
+
}
|
|
52236
|
+
}
|
|
52237
|
+
}
|
|
52238
|
+
function validateEffect(effectFunction, context) {
|
|
52239
|
+
const seenBlocks = new Set();
|
|
52240
|
+
const effectDerivedSetStateCalls = [];
|
|
52241
|
+
const globals = new Set();
|
|
52242
|
+
for (const block of effectFunction.body.blocks.values()) {
|
|
52243
|
+
for (const pred of block.preds) {
|
|
52244
|
+
if (!seenBlocks.has(pred)) {
|
|
52245
|
+
return;
|
|
52246
|
+
}
|
|
52247
|
+
}
|
|
52248
|
+
for (const instr of block.instructions) {
|
|
52249
|
+
if (isUseRefType(instr.lvalue.identifier)) {
|
|
52250
|
+
return;
|
|
52251
|
+
}
|
|
52252
|
+
for (const operand of eachInstructionOperand(instr)) {
|
|
52253
|
+
if (isSetStateType(operand.identifier) &&
|
|
52254
|
+
operand.loc !== GeneratedSource) {
|
|
52255
|
+
if (context.effectSetStateCache.has(operand.loc.identifierName)) {
|
|
52256
|
+
context.effectSetStateCache
|
|
52257
|
+
.get(operand.loc.identifierName)
|
|
52258
|
+
.push(operand);
|
|
52259
|
+
}
|
|
52260
|
+
else {
|
|
52261
|
+
context.effectSetStateCache.set(operand.loc.identifierName, [
|
|
52262
|
+
operand,
|
|
52263
|
+
]);
|
|
52264
|
+
}
|
|
52265
|
+
}
|
|
52266
|
+
}
|
|
52267
|
+
if (instr.value.kind === 'CallExpression' &&
|
|
52268
|
+
isSetStateType(instr.value.callee.identifier) &&
|
|
52269
|
+
instr.value.args.length === 1 &&
|
|
52270
|
+
instr.value.args[0].kind === 'Identifier') {
|
|
52271
|
+
const argMetadata = context.derivationCache.cache.get(instr.value.args[0].identifier.id);
|
|
52272
|
+
if (argMetadata !== undefined) {
|
|
52273
|
+
effectDerivedSetStateCalls.push({
|
|
52274
|
+
value: instr.value,
|
|
52275
|
+
loc: instr.value.callee.loc,
|
|
52276
|
+
sourceIds: argMetadata.sourcesIds,
|
|
52277
|
+
typeOfValue: argMetadata.typeOfValue,
|
|
52278
|
+
});
|
|
52279
|
+
}
|
|
52280
|
+
}
|
|
52281
|
+
else if (instr.value.kind === 'CallExpression') {
|
|
52282
|
+
const calleeMetadata = context.derivationCache.cache.get(instr.value.callee.identifier.id);
|
|
52283
|
+
if (calleeMetadata !== undefined &&
|
|
52284
|
+
(calleeMetadata.typeOfValue === 'fromProps' ||
|
|
52285
|
+
calleeMetadata.typeOfValue === 'fromPropsAndState')) {
|
|
52286
|
+
return;
|
|
52287
|
+
}
|
|
52288
|
+
if (globals.has(instr.value.callee.identifier.id)) {
|
|
52289
|
+
return;
|
|
52290
|
+
}
|
|
52291
|
+
}
|
|
52292
|
+
else if (instr.value.kind === 'LoadGlobal') {
|
|
52293
|
+
globals.add(instr.lvalue.identifier.id);
|
|
52294
|
+
for (const operand of eachInstructionOperand(instr)) {
|
|
52295
|
+
globals.add(operand.identifier.id);
|
|
52296
|
+
}
|
|
52297
|
+
}
|
|
52298
|
+
}
|
|
52299
|
+
seenBlocks.add(block.id);
|
|
52300
|
+
}
|
|
52301
|
+
for (const derivedSetStateCall of effectDerivedSetStateCalls) {
|
|
52302
|
+
if (derivedSetStateCall.loc !== GeneratedSource &&
|
|
52303
|
+
context.effectSetStateCache.has(derivedSetStateCall.loc.identifierName) &&
|
|
52304
|
+
context.setStateCache.has(derivedSetStateCall.loc.identifierName) &&
|
|
52305
|
+
context.effectSetStateCache.get(derivedSetStateCall.loc.identifierName)
|
|
52306
|
+
.length ===
|
|
52307
|
+
context.setStateCache.get(derivedSetStateCall.loc.identifierName)
|
|
52308
|
+
.length -
|
|
52309
|
+
1) {
|
|
52310
|
+
const derivedDepsStr = Array.from(derivedSetStateCall.sourceIds)
|
|
52311
|
+
.map(sourceId => {
|
|
52312
|
+
var _a;
|
|
52313
|
+
const sourceMetadata = context.derivationCache.cache.get(sourceId);
|
|
52314
|
+
return (_a = sourceMetadata === null || sourceMetadata === void 0 ? void 0 : sourceMetadata.place.identifier.name) === null || _a === void 0 ? void 0 : _a.value;
|
|
52315
|
+
})
|
|
52316
|
+
.filter(Boolean)
|
|
52317
|
+
.join(', ');
|
|
52318
|
+
let description;
|
|
52319
|
+
if (derivedSetStateCall.typeOfValue === 'fromProps') {
|
|
52320
|
+
description = `From props: [${derivedDepsStr}]`;
|
|
52321
|
+
}
|
|
52322
|
+
else if (derivedSetStateCall.typeOfValue === 'fromState') {
|
|
52323
|
+
description = `From local state: [${derivedDepsStr}]`;
|
|
52324
|
+
}
|
|
52325
|
+
else {
|
|
52326
|
+
description = `From props and local state: [${derivedDepsStr}]`;
|
|
52327
|
+
}
|
|
52328
|
+
context.errors.pushDiagnostic(CompilerDiagnostic.create({
|
|
52329
|
+
description: `Derived values (${description}) should be computed during render, rather than in effects. Using an effect triggers an additional render which can hurt performance and user experience, potentially briefly showing stale values to the user`,
|
|
52330
|
+
category: ErrorCategory.EffectDerivationsOfState,
|
|
52331
|
+
reason: 'You might not need an effect. Derive values in render, not effects.',
|
|
52332
|
+
}).withDetails({
|
|
52333
|
+
kind: 'error',
|
|
52334
|
+
loc: derivedSetStateCall.value.callee.loc,
|
|
52335
|
+
message: 'This should be computed during render, not in an effect',
|
|
52336
|
+
}));
|
|
52337
|
+
}
|
|
52338
|
+
}
|
|
52339
|
+
}
|
|
52340
|
+
|
|
51991
52341
|
function nameAnonymousFunctions(fn) {
|
|
51992
52342
|
if (fn.id == null) {
|
|
51993
52343
|
return;
|
|
@@ -52229,6 +52579,9 @@ function runWithEnvironment(func, env) {
|
|
|
52229
52579
|
if (env.config.validateNoDerivedComputationsInEffects) {
|
|
52230
52580
|
validateNoDerivedComputationsInEffects(hir);
|
|
52231
52581
|
}
|
|
52582
|
+
if (env.config.validateNoDerivedComputationsInEffects_exp) {
|
|
52583
|
+
validateNoDerivedComputationsInEffects_exp(hir);
|
|
52584
|
+
}
|
|
52232
52585
|
if (env.config.validateNoSetStateInEffects) {
|
|
52233
52586
|
env.logErrors(validateNoSetStateInEffects(hir, env));
|
|
52234
52587
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-react-hooks",
|
|
3
3
|
"description": "ESLint rules for React Hooks",
|
|
4
|
-
"version": "7.0.
|
|
4
|
+
"version": "7.0.1",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
7
7
|
"url": "https://github.com/facebook/react.git",
|
|
@@ -65,4 +65,4 @@
|
|
|
65
65
|
"jest": "^29.5.0",
|
|
66
66
|
"typescript": "^5.4.3"
|
|
67
67
|
}
|
|
68
|
-
}
|
|
68
|
+
}
|