oxlint-plugin-react-doctor 0.9.2-dev.3bc63ea → 0.9.2-dev.444e177
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.
- package/dist/index.js +31 -422
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -388,7 +388,7 @@ const SOURCE_FILE_PATTERN = /\.(?:[cm]?[jt]sx?)$/i;
|
|
|
388
388
|
const SCRIPT_SOURCE_FILE_PATTERN = /\.(?:[cm]?[jt]sx?|py|php)$/i;
|
|
389
389
|
const DATABASE_SOURCE_FILE_PATTERN = /\.(?:[cm]?[jt]sx?|py)$/i;
|
|
390
390
|
const SERVER_CONTEXT_PATTERN = /(?:^|\/)(?:api|backend|server|servers|middleware|route|routes|functions|lambdas|workers)(?:\/|$)|(?:^|\/)[^/]+\.server\.[cm]?[jt]sx?$/i;
|
|
391
|
-
const TEST_CONTEXT_PATTERN = /(?:^|\/)(?:__fixtures__|__mocks__|__tests__|__integration__|fixtures|mocks|test|tests|testdata|test-data|e2e|playwright|cypress|specs?)(?:\/|$)
|
|
391
|
+
const TEST_CONTEXT_PATTERN = /(?:^|\/)(?:__fixtures__|__mocks__|__tests__|__integration__|fixtures|mocks|test|tests|testdata|test-data|e2e|playwright|cypress|specs?)(?:\/|$)|\.(?:test|spec|e2e|e2e-spec|integration-test|fixture|fixtures|stories|story)\.[cm]?[jt]sx?$|(?:^|\/)(?:playwright|cypress|vitest|jest|karma)[^/]*\.conf(?:ig)?\.[cm]?[jt]s$|(?:^|\/)(?:test_[^/]+|[^/]+_test|conftest)\.py$|\.env\.[^/]*(?:test|e2e)[^/]*$/i;
|
|
392
392
|
const BUILD_CONFIG_FILE_PATTERN = /(?:^|\/)(?:vite|next|nuxt|astro|remix|webpack|rollup|rspack|rsbuild|esbuild|tsup|metro|expo|babel|tailwind|postcss|svelte|farm|parcel|snowpack)[^/]*\.config\.[cm]?[jt]sx?$/i;
|
|
393
393
|
const BUILD_SCRIPT_CONTEXT_PATTERN = /(?:^|\/)scripts(?:\/|$)/i;
|
|
394
394
|
const DEMO_CONTEXT_PATTERN = /(?:^|\/)(?:examples?|tutorials?|demos?|samples?|playgrounds?)(?:\/|$)/i;
|
|
@@ -5887,7 +5887,6 @@ const isInlineFunctionExpression = (node) => Boolean(node && (isNodeOfType(node,
|
|
|
5887
5887
|
//#endregion
|
|
5888
5888
|
//#region src/plugin/rules/js-performance/async-await-in-loop.ts
|
|
5889
5889
|
const LOOP_STATEMENT_TYPES$1 = new Set(LOOP_TYPES);
|
|
5890
|
-
const ORDERED_OUTPUT_INSERTION_METHOD_NAMES = new Set(["push", "unshift"]);
|
|
5891
5890
|
const findFirstAwaitOutsideNestedFunctions = (block, skipNestedLoops = false) => {
|
|
5892
5891
|
let firstAwait = null;
|
|
5893
5892
|
walkAst(block, (child) => {
|
|
@@ -5954,151 +5953,7 @@ const isAwaitingManualPromiseWait = (awaitNode) => {
|
|
|
5954
5953
|
});
|
|
5955
5954
|
return isWaitLike;
|
|
5956
5955
|
};
|
|
5957
|
-
const
|
|
5958
|
-
let current = node;
|
|
5959
|
-
while (isNodeOfType(current, "MemberExpression")) current = current.object;
|
|
5960
|
-
return isNodeOfType(current, "Identifier") ? current.name : null;
|
|
5961
|
-
};
|
|
5962
|
-
const isScopeWithinFunction = (candidateScope, functionScope) => {
|
|
5963
|
-
let currentScope = candidateScope;
|
|
5964
|
-
while (currentScope) {
|
|
5965
|
-
if (currentScope === functionScope) return true;
|
|
5966
|
-
currentScope = currentScope.parent;
|
|
5967
|
-
}
|
|
5968
|
-
return false;
|
|
5969
|
-
};
|
|
5970
|
-
const isSymbolDirectlyReturned = (symbol, callerFunction) => Boolean(callerFunction) && symbol.references.some((reference) => {
|
|
5971
|
-
const expressionRoot = findTransparentExpressionRoot(reference.identifier);
|
|
5972
|
-
const parent = expressionRoot.parent;
|
|
5973
|
-
return isNodeOfType(parent, "ReturnStatement") && parent.argument === expressionRoot && findEnclosingFunction$1(parent) === callerFunction;
|
|
5974
|
-
});
|
|
5975
|
-
const collectPatternBindingSymbolIds = (pattern, scopes, target) => {
|
|
5976
|
-
if (isNodeOfType(pattern, "Identifier")) {
|
|
5977
|
-
const symbol = scopes.symbolFor(pattern);
|
|
5978
|
-
if (symbol) target.add(symbol.id);
|
|
5979
|
-
return;
|
|
5980
|
-
}
|
|
5981
|
-
if (isNodeOfType(pattern, "ObjectPattern")) {
|
|
5982
|
-
for (const property of pattern.properties ?? []) if (isNodeOfType(property, "Property") && property.value) collectPatternBindingSymbolIds(property.value, scopes, target);
|
|
5983
|
-
else if (isNodeOfType(property, "RestElement") && property.argument) collectPatternBindingSymbolIds(property.argument, scopes, target);
|
|
5984
|
-
return;
|
|
5985
|
-
}
|
|
5986
|
-
if (isNodeOfType(pattern, "ArrayPattern")) {
|
|
5987
|
-
for (const element of pattern.elements ?? []) if (element) collectPatternBindingSymbolIds(element, scopes, target);
|
|
5988
|
-
return;
|
|
5989
|
-
}
|
|
5990
|
-
if (isNodeOfType(pattern, "AssignmentPattern") && pattern.left) collectPatternBindingSymbolIds(pattern.left, scopes, target);
|
|
5991
|
-
};
|
|
5992
|
-
const collectReferencedSymbolIds = (expression, scopes) => {
|
|
5993
|
-
const referencedSymbolIds = /* @__PURE__ */ new Set();
|
|
5994
|
-
walkAst(expression, (child) => {
|
|
5995
|
-
if (child !== expression && isFunctionLike$1(child)) return false;
|
|
5996
|
-
if (!isNodeOfType(child, "Identifier")) return;
|
|
5997
|
-
const symbol = scopes.symbolFor(child);
|
|
5998
|
-
if (symbol) referencedSymbolIds.add(symbol.id);
|
|
5999
|
-
});
|
|
6000
|
-
return referencedSymbolIds;
|
|
6001
|
-
};
|
|
6002
|
-
const collectAwaitDerivedSymbolIds = (block, scopes) => {
|
|
6003
|
-
const awaitDerivedSymbolIds = /* @__PURE__ */ new Set();
|
|
6004
|
-
const bindingDependencies = [];
|
|
6005
|
-
walkAst(block, (child) => {
|
|
6006
|
-
if (child !== block && isFunctionLike$1(child)) return false;
|
|
6007
|
-
if (isNodeOfType(child, "VariableDeclarator") && child.id && child.init) {
|
|
6008
|
-
const declaredSymbolIds = /* @__PURE__ */ new Set();
|
|
6009
|
-
collectPatternBindingSymbolIds(child.id, scopes, declaredSymbolIds);
|
|
6010
|
-
if (containsDirectAwait(child.init)) for (const symbolId of declaredSymbolIds) awaitDerivedSymbolIds.add(symbolId);
|
|
6011
|
-
const referencedSymbolIds = collectReferencedSymbolIds(child.init, scopes);
|
|
6012
|
-
for (const declaredSymbolId of declaredSymbolIds) bindingDependencies.push({
|
|
6013
|
-
declaredSymbolId,
|
|
6014
|
-
referencedSymbolIds
|
|
6015
|
-
});
|
|
6016
|
-
return;
|
|
6017
|
-
}
|
|
6018
|
-
if (isNodeOfType(child, "AssignmentExpression") && child.left) {
|
|
6019
|
-
const assignedSymbolIds = /* @__PURE__ */ new Set();
|
|
6020
|
-
collectPatternBindingSymbolIds(child.left, scopes, assignedSymbolIds);
|
|
6021
|
-
if (containsDirectAwait(child.right)) for (const symbolId of assignedSymbolIds) awaitDerivedSymbolIds.add(symbolId);
|
|
6022
|
-
const referencedSymbolIds = collectReferencedSymbolIds(child.right, scopes);
|
|
6023
|
-
for (const assignedSymbolId of assignedSymbolIds) bindingDependencies.push({
|
|
6024
|
-
declaredSymbolId: assignedSymbolId,
|
|
6025
|
-
referencedSymbolIds
|
|
6026
|
-
});
|
|
6027
|
-
}
|
|
6028
|
-
});
|
|
6029
|
-
let didGrow = true;
|
|
6030
|
-
while (didGrow) {
|
|
6031
|
-
didGrow = false;
|
|
6032
|
-
for (const { declaredSymbolId, referencedSymbolIds } of bindingDependencies) {
|
|
6033
|
-
if (awaitDerivedSymbolIds.has(declaredSymbolId)) continue;
|
|
6034
|
-
for (const referencedSymbolId of referencedSymbolIds) {
|
|
6035
|
-
if (!awaitDerivedSymbolIds.has(referencedSymbolId)) continue;
|
|
6036
|
-
awaitDerivedSymbolIds.add(declaredSymbolId);
|
|
6037
|
-
didGrow = true;
|
|
6038
|
-
break;
|
|
6039
|
-
}
|
|
6040
|
-
}
|
|
6041
|
-
}
|
|
6042
|
-
return awaitDerivedSymbolIds;
|
|
6043
|
-
};
|
|
6044
|
-
const getSimpleParameterIdentifier = (parameter) => {
|
|
6045
|
-
if (isNodeOfType(parameter, "Identifier")) return parameter;
|
|
6046
|
-
if (isNodeOfType(parameter, "AssignmentPattern") && isNodeOfType(parameter.left, "Identifier")) return parameter.left;
|
|
6047
|
-
return null;
|
|
6048
|
-
};
|
|
6049
|
-
const doesAwaitedLocalCallInsertAwaitDerivedOutput = (awaitNode, context) => {
|
|
6050
|
-
if (!isNodeOfType(awaitNode, "AwaitExpression")) return false;
|
|
6051
|
-
const callExpression = awaitNode.argument;
|
|
6052
|
-
if (!isNodeOfType(callExpression, "CallExpression")) return false;
|
|
6053
|
-
const localFunction = resolveStaticLocalCallFunction(callExpression, context.scopes);
|
|
6054
|
-
if (!isFunctionLike$1(localFunction)) return false;
|
|
6055
|
-
const callerFunction = findEnclosingFunction$1(callExpression);
|
|
6056
|
-
const functionScope = context.scopes.ownScopeFor(localFunction);
|
|
6057
|
-
if (!functionScope) return false;
|
|
6058
|
-
const awaitDerivedSymbolIds = collectAwaitDerivedSymbolIds(localFunction.body, context.scopes);
|
|
6059
|
-
const externallyReachableParameterSymbolIds = /* @__PURE__ */ new Set();
|
|
6060
|
-
for (const [parameterIndex, parameter] of localFunction.params.entries()) {
|
|
6061
|
-
const parameterIdentifier = getSimpleParameterIdentifier(parameter);
|
|
6062
|
-
if (!parameterIdentifier) continue;
|
|
6063
|
-
const argument = callExpression.arguments[parameterIndex];
|
|
6064
|
-
if (!isNodeOfType(argument, "Identifier")) continue;
|
|
6065
|
-
const parameterSymbol = context.scopes.symbolFor(parameterIdentifier);
|
|
6066
|
-
const argumentSymbol = context.scopes.symbolFor(argument);
|
|
6067
|
-
if (parameterSymbol && argumentSymbol && (isSymbolDirectlyReturned(argumentSymbol, callerFunction) || argumentSymbol.id === parameterSymbol.id)) externallyReachableParameterSymbolIds.add(parameterSymbol.id);
|
|
6068
|
-
}
|
|
6069
|
-
let doesInsertAwaitDerivedOutput = false;
|
|
6070
|
-
walkAst(localFunction.body, (child) => {
|
|
6071
|
-
if (doesInsertAwaitDerivedOutput) return false;
|
|
6072
|
-
if (child !== localFunction.body && isFunctionLike$1(child)) return false;
|
|
6073
|
-
if (!isNodeOfType(child, "CallExpression")) return;
|
|
6074
|
-
const callee = child.callee;
|
|
6075
|
-
if (!isNodeOfType(callee, "MemberExpression") || callee.computed || !isNodeOfType(callee.property, "Identifier") || !ORDERED_OUTPUT_INSERTION_METHOD_NAMES.has(callee.property.name)) return;
|
|
6076
|
-
let doesMutationConsumeAwaitedValue = false;
|
|
6077
|
-
for (const mutationArgument of child.arguments ?? []) {
|
|
6078
|
-
if (containsDirectAwait(mutationArgument)) {
|
|
6079
|
-
doesMutationConsumeAwaitedValue = true;
|
|
6080
|
-
break;
|
|
6081
|
-
}
|
|
6082
|
-
const referencedSymbolIds = collectReferencedSymbolIds(mutationArgument, context.scopes);
|
|
6083
|
-
for (const referencedSymbolId of referencedSymbolIds) if (awaitDerivedSymbolIds.has(referencedSymbolId)) {
|
|
6084
|
-
doesMutationConsumeAwaitedValue = true;
|
|
6085
|
-
break;
|
|
6086
|
-
}
|
|
6087
|
-
if (doesMutationConsumeAwaitedValue) break;
|
|
6088
|
-
}
|
|
6089
|
-
if (!doesMutationConsumeAwaitedValue) return;
|
|
6090
|
-
let receiverIdentifier = callee.object;
|
|
6091
|
-
while (isNodeOfType(receiverIdentifier, "MemberExpression")) receiverIdentifier = receiverIdentifier.object;
|
|
6092
|
-
if (!isNodeOfType(receiverIdentifier, "Identifier")) return;
|
|
6093
|
-
const receiverSymbol = context.scopes.symbolFor(receiverIdentifier);
|
|
6094
|
-
if (receiverSymbol && (externallyReachableParameterSymbolIds.has(receiverSymbol.id) || !isScopeWithinFunction(receiverSymbol.scope, functionScope) && isSymbolDirectlyReturned(receiverSymbol, callerFunction))) {
|
|
6095
|
-
doesInsertAwaitDerivedOutput = true;
|
|
6096
|
-
return false;
|
|
6097
|
-
}
|
|
6098
|
-
});
|
|
6099
|
-
return doesInsertAwaitDerivedOutput;
|
|
6100
|
-
};
|
|
6101
|
-
const isIntentionallySequentialAwait = (awaitNode, context) => isAwaitingPossiblyMutatedMemberCall(awaitNode, context) || isAwaitingSleepLikeCall(awaitNode, context) || isAwaitingPromiseConcurrencyCall(awaitNode) || isAwaitingManualPromiseWait(awaitNode) || doesAwaitedLocalCallInsertAwaitDerivedOutput(awaitNode, context);
|
|
5956
|
+
const isIntentionallySequentialAwait = (awaitNode, context) => isAwaitingPossiblyMutatedMemberCall(awaitNode, context) || isAwaitingSleepLikeCall(awaitNode, context) || isAwaitingPromiseConcurrencyCall(awaitNode) || isAwaitingManualPromiseWait(awaitNode);
|
|
6102
5957
|
const collectPatternIdentifiers = (pattern, target) => {
|
|
6103
5958
|
if (isNodeOfType(pattern, "Identifier")) target.add(pattern.name);
|
|
6104
5959
|
else if (isNodeOfType(pattern, "ObjectPattern")) {
|
|
@@ -6244,6 +6099,11 @@ const loopBodyHasAwaitDependentEarlyExit = (block, loopLabelName) => {
|
|
|
6244
6099
|
});
|
|
6245
6100
|
return hasAwaitDependentExit;
|
|
6246
6101
|
};
|
|
6102
|
+
const getRootObjectIdentifierName = (node) => {
|
|
6103
|
+
let current = node;
|
|
6104
|
+
while (isNodeOfType(current, "MemberExpression")) current = current.object;
|
|
6105
|
+
return isNodeOfType(current, "Identifier") ? current.name : null;
|
|
6106
|
+
};
|
|
6247
6107
|
const MUTATING_ARRAY_METHOD_NAMES$2 = new Set([
|
|
6248
6108
|
...ARRAY_MUTATION_METHOD_NAMES,
|
|
6249
6109
|
"pop",
|
|
@@ -30674,8 +30534,7 @@ const STRING_TYPED_PROPERTY_NAMES = new Set([
|
|
|
30674
30534
|
"code",
|
|
30675
30535
|
"label",
|
|
30676
30536
|
"slug",
|
|
30677
|
-
"prefix"
|
|
30678
|
-
"__html"
|
|
30537
|
+
"prefix"
|
|
30679
30538
|
]);
|
|
30680
30539
|
const STRING_TYPED_IDENTIFIER_SUFFIXES = [
|
|
30681
30540
|
"Text",
|
|
@@ -30793,25 +30652,13 @@ const STRING_TYPED_IDENTIFIER_NAMES = new Set([
|
|
|
30793
30652
|
"title"
|
|
30794
30653
|
]);
|
|
30795
30654
|
const STRING_RETURNING_CALLEE_PREFIX_PATTERN = /^(?:normalize|format|stringify|serialize)/;
|
|
30796
|
-
const FRESH_ARRAY_METHOD_NAMES$2 = new Set([
|
|
30797
|
-
"concat",
|
|
30798
|
-
"filter",
|
|
30799
|
-
"flat",
|
|
30800
|
-
"flatMap",
|
|
30801
|
-
"map",
|
|
30802
|
-
"slice",
|
|
30803
|
-
"split"
|
|
30804
|
-
]);
|
|
30805
30655
|
const isLikelyStringReceiver = (receiver) => {
|
|
30806
30656
|
if (!receiver) return false;
|
|
30807
|
-
const unwrappedReceiver = stripParenExpression(receiver);
|
|
30808
|
-
if (unwrappedReceiver !== receiver) return isLikelyStringReceiver(unwrappedReceiver);
|
|
30809
30657
|
if (isNodeOfType(receiver, "Literal") && typeof receiver.value === "string") return true;
|
|
30810
30658
|
if (isNodeOfType(receiver, "TemplateLiteral")) return true;
|
|
30811
30659
|
if (isNodeOfType(receiver, "CallExpression") && isNodeOfType(receiver.callee, "Identifier") && receiver.callee.name === "String") return true;
|
|
30812
30660
|
if (isNodeOfType(receiver, "CallExpression") && isNodeOfType(receiver.callee, "MemberExpression") && isNodeOfType(receiver.callee.property, "Identifier") && STRING_RETURNING_METHODS.has(receiver.callee.property.name)) return true;
|
|
30813
30661
|
if (isNodeOfType(receiver, "CallExpression") && isNodeOfType(receiver.callee, "Identifier") && STRING_RETURNING_CALLEE_PREFIX_PATTERN.test(receiver.callee.name)) return true;
|
|
30814
|
-
if (isNodeOfType(receiver, "CallExpression") && isNodeOfType(receiver.callee, "MemberExpression") && isNodeOfType(receiver.callee.property, "Identifier") && (receiver.callee.property.name === "concat" || receiver.callee.property.name === "slice") && isLikelyStringReceiver(receiver.callee.object)) return true;
|
|
30815
30662
|
if (isNodeOfType(receiver, "MemberExpression") && isNodeOfType(receiver.property, "Identifier")) {
|
|
30816
30663
|
if (STRING_TYPED_PROPERTY_NAMES.has(receiver.property.name)) return true;
|
|
30817
30664
|
}
|
|
@@ -30829,46 +30676,8 @@ const isLikelyStringReceiver = (receiver) => {
|
|
|
30829
30676
|
}
|
|
30830
30677
|
if (isNodeOfType(receiver, "BinaryExpression") && receiver.operator === "+") return isLikelyStringReceiver(receiver.left) || isLikelyStringReceiver(receiver.right);
|
|
30831
30678
|
if (isNodeOfType(receiver, "ConditionalExpression")) return isLikelyStringReceiver(receiver.consequent) && isLikelyStringReceiver(receiver.alternate);
|
|
30832
|
-
if (isNodeOfType(receiver, "LogicalExpression")) return isLikelyStringReceiver(receiver.left) && isLikelyStringReceiver(receiver.right);
|
|
30833
30679
|
return false;
|
|
30834
30680
|
};
|
|
30835
|
-
const isFreshArrayReceiver = (receiver) => {
|
|
30836
|
-
const unwrappedReceiver = stripParenExpression(receiver);
|
|
30837
|
-
if (unwrappedReceiver !== receiver) return isFreshArrayReceiver(unwrappedReceiver);
|
|
30838
|
-
if (!isNodeOfType(receiver, "CallExpression") || !isNodeOfType(receiver.callee, "MemberExpression") || !isNodeOfType(receiver.callee.property, "Identifier")) return false;
|
|
30839
|
-
if (!FRESH_ARRAY_METHOD_NAMES$2.has(receiver.callee.property.name)) return false;
|
|
30840
|
-
if (receiver.callee.property.name === "split") return isLikelyStringReceiver(receiver.callee.object);
|
|
30841
|
-
const sourceReceiver = stripParenExpression(receiver.callee.object);
|
|
30842
|
-
return isKnownNativeArrayReceiver(sourceReceiver) || isFreshArrayReceiver(sourceReceiver);
|
|
30843
|
-
};
|
|
30844
|
-
const isSmallRestHelperOmissionList = (node) => {
|
|
30845
|
-
if (!node) return false;
|
|
30846
|
-
const candidate = stripParenExpression(node);
|
|
30847
|
-
if (!isNodeOfType(candidate, "ArrayExpression")) return false;
|
|
30848
|
-
const elements = candidate.elements ?? [];
|
|
30849
|
-
return elements.length <= 8 && elements.every((element) => element === null || !isNodeOfType(element, "SpreadElement"));
|
|
30850
|
-
};
|
|
30851
|
-
const isTypeScriptRestHelperLookup = (lookupCall, receiver, scopes) => {
|
|
30852
|
-
if (!isNodeOfType(receiver, "Identifier")) return false;
|
|
30853
|
-
const enclosingFunction = findEnclosingFunction$1(lookupCall);
|
|
30854
|
-
if (!isNodeOfType(enclosingFunction, "FunctionExpression") || !isNodeOfType(enclosingFunction.params?.[1], "Identifier") || enclosingFunction.params[1].name !== receiver.name) return false;
|
|
30855
|
-
let bindingIdentifier = null;
|
|
30856
|
-
let ancestor = enclosingFunction.parent;
|
|
30857
|
-
while (ancestor && !isFunctionLike$1(ancestor)) {
|
|
30858
|
-
if (isNodeOfType(ancestor, "VariableDeclarator") && isNodeOfType(ancestor.id, "Identifier") && ancestor.id.name === "__rest") {
|
|
30859
|
-
bindingIdentifier = ancestor.id;
|
|
30860
|
-
break;
|
|
30861
|
-
}
|
|
30862
|
-
ancestor = ancestor.parent;
|
|
30863
|
-
}
|
|
30864
|
-
if (!bindingIdentifier) return false;
|
|
30865
|
-
const helperSymbol = scopes.symbolFor(bindingIdentifier);
|
|
30866
|
-
if (!helperSymbol || helperSymbol.references.length === 0) return false;
|
|
30867
|
-
return helperSymbol.references.every((reference) => {
|
|
30868
|
-
const callExpression = reference.identifier.parent;
|
|
30869
|
-
return isNodeOfType(callExpression, "CallExpression") && callExpression.callee === reference.identifier && isSmallRestHelperOmissionList(callExpression.arguments?.[1]);
|
|
30870
|
-
});
|
|
30871
|
-
};
|
|
30872
30681
|
const INDEX_LIKE_IDENTIFIER_NAMES = new Set([
|
|
30873
30682
|
"i",
|
|
30874
30683
|
"j",
|
|
@@ -31465,8 +31274,6 @@ const jsSetMapLookups = defineRule({
|
|
|
31465
31274
|
const query = node.arguments[0];
|
|
31466
31275
|
if (methodName === "indexOf" && !isKnownSafeIndexOfQuery(query) && (isKnownUnsafeIndexOfQuery(query, receiver) || isKnownUnsafeIndexOfReceiver(receiver))) return;
|
|
31467
31276
|
if (isLikelyStringReceiver(receiver)) return;
|
|
31468
|
-
if (isFreshArrayReceiver(receiver)) return;
|
|
31469
|
-
if (isTypeScriptRestHelperLookup(node, receiver, context.scopes)) return;
|
|
31470
31277
|
if (isSmallInlineLiteralArray(receiver)) return;
|
|
31471
31278
|
if (isScreamingSnakeCaseConstantReceiver(receiver)) return;
|
|
31472
31279
|
if (isSmallFixedListMember(receiver)) return;
|
|
@@ -46908,101 +46715,6 @@ const isLoopCounterDeclarator = (declarator, referenceNode, indexName) => {
|
|
|
46908
46715
|
}
|
|
46909
46716
|
return isBindingReassignedOrMutated(referenceNode, indexName);
|
|
46910
46717
|
};
|
|
46911
|
-
const findEnclosingWhileLoop = (node) => {
|
|
46912
|
-
let current = node.parent;
|
|
46913
|
-
while (current) {
|
|
46914
|
-
if (isNodeOfType(current, "WhileStatement") || isNodeOfType(current, "DoWhileStatement")) return current;
|
|
46915
|
-
if (isFunctionLike$1(current) || isNodeOfType(current, "Program")) return null;
|
|
46916
|
-
current = current.parent;
|
|
46917
|
-
}
|
|
46918
|
-
return null;
|
|
46919
|
-
};
|
|
46920
|
-
const isStaticMemberChain = (expression) => {
|
|
46921
|
-
const candidate = stripParenExpression(expression);
|
|
46922
|
-
if (isNodeOfType(candidate, "Identifier") || isNodeOfType(candidate, "ThisExpression")) return true;
|
|
46923
|
-
return Boolean(isNodeOfType(candidate, "MemberExpression") && !candidate.computed && isNodeOfType(candidate.property, "Identifier") && isStaticMemberChain(candidate.object));
|
|
46924
|
-
};
|
|
46925
|
-
const findLengthBoundCollections = (expression) => {
|
|
46926
|
-
const collections = [];
|
|
46927
|
-
walkAst(expression, (child) => {
|
|
46928
|
-
if (isNodeOfType(child, "MemberExpression") && !child.computed && isStaticMemberChain(child.object) && isNodeOfType(child.property, "Identifier") && child.property.name === "length") collections.push(child.object);
|
|
46929
|
-
});
|
|
46930
|
-
return collections;
|
|
46931
|
-
};
|
|
46932
|
-
const areSameBoundStaticMemberChains = (first, second) => isStaticMemberChain(first) && isStaticMemberChain(second) && areExpressionsStructurallyEqual(first, second, { areIdentifiersEqual: (firstIdentifier, secondIdentifier) => {
|
|
46933
|
-
if (!isNodeOfType(firstIdentifier, "Identifier") || !isNodeOfType(secondIdentifier, "Identifier") || firstIdentifier.name !== secondIdentifier.name) return false;
|
|
46934
|
-
const firstBinding = findVariableInitializer(firstIdentifier, firstIdentifier.name);
|
|
46935
|
-
const secondBinding = findVariableInitializer(secondIdentifier, secondIdentifier.name);
|
|
46936
|
-
return firstBinding?.bindingIdentifier === secondBinding?.bindingIdentifier;
|
|
46937
|
-
} });
|
|
46938
|
-
const RELATIONAL_BOUND_OPERATORS = new Set([
|
|
46939
|
-
"<",
|
|
46940
|
-
"<=",
|
|
46941
|
-
">",
|
|
46942
|
-
">="
|
|
46943
|
-
]);
|
|
46944
|
-
const loopTestBoundsCounterByLength = (expression, indexName, bindingIdentifier) => {
|
|
46945
|
-
const readsCounter = (candidate) => {
|
|
46946
|
-
let didReadCounter = false;
|
|
46947
|
-
walkAst(candidate, (child) => {
|
|
46948
|
-
if (didReadCounter) return false;
|
|
46949
|
-
if (isNodeOfType(child, "Identifier") && child.name === indexName && findVariableInitializer(child, indexName)?.bindingIdentifier === bindingIdentifier) {
|
|
46950
|
-
didReadCounter = true;
|
|
46951
|
-
return false;
|
|
46952
|
-
}
|
|
46953
|
-
});
|
|
46954
|
-
return didReadCounter;
|
|
46955
|
-
};
|
|
46956
|
-
const readsLength = (candidate) => {
|
|
46957
|
-
let didReadLength = false;
|
|
46958
|
-
walkAst(candidate, (child) => {
|
|
46959
|
-
if (didReadLength) return false;
|
|
46960
|
-
if (isNodeOfType(child, "MemberExpression") && !child.computed && isNodeOfType(child.property, "Identifier") && child.property.name === "length") {
|
|
46961
|
-
didReadLength = true;
|
|
46962
|
-
return false;
|
|
46963
|
-
}
|
|
46964
|
-
});
|
|
46965
|
-
return didReadLength;
|
|
46966
|
-
};
|
|
46967
|
-
let didFindLengthBound = false;
|
|
46968
|
-
walkAst(expression, (child) => {
|
|
46969
|
-
if (didFindLengthBound) return false;
|
|
46970
|
-
if (!isNodeOfType(child, "BinaryExpression") || !RELATIONAL_BOUND_OPERATORS.has(child.operator)) return;
|
|
46971
|
-
if (readsCounter(child.left) && readsLength(child.right) || readsCounter(child.right) && readsLength(child.left)) {
|
|
46972
|
-
didFindLengthBound = true;
|
|
46973
|
-
return false;
|
|
46974
|
-
}
|
|
46975
|
-
});
|
|
46976
|
-
return didFindLengthBound;
|
|
46977
|
-
};
|
|
46978
|
-
const isDataIndexedWhileLoopCounter = (referenceNode, bindingIdentifier, indexName) => {
|
|
46979
|
-
if (!INDEX_PARAMETER_NAMES.has(indexName)) return false;
|
|
46980
|
-
const loop = findEnclosingWhileLoop(referenceNode);
|
|
46981
|
-
if (!loop) return false;
|
|
46982
|
-
let doesTestReadCounter = false;
|
|
46983
|
-
walkAst(loop.test, (child) => {
|
|
46984
|
-
if (doesTestReadCounter) return false;
|
|
46985
|
-
if (!isNodeOfType(child, "Identifier") || child.name !== indexName) return;
|
|
46986
|
-
if (findVariableInitializer(child, indexName)?.bindingIdentifier === bindingIdentifier) {
|
|
46987
|
-
doesTestReadCounter = true;
|
|
46988
|
-
return false;
|
|
46989
|
-
}
|
|
46990
|
-
});
|
|
46991
|
-
if (!doesTestReadCounter) return false;
|
|
46992
|
-
const lengthBoundCollections = findLengthBoundCollections(loop.test);
|
|
46993
|
-
if (lengthBoundCollections.length === 0) return false;
|
|
46994
|
-
let didFindIndexedCollectionRead = false;
|
|
46995
|
-
walkAst(loop.body, (child) => {
|
|
46996
|
-
if (didFindIndexedCollectionRead) return false;
|
|
46997
|
-
if (isFunctionLike$1(child)) return false;
|
|
46998
|
-
if (!isNodeOfType(child, "MemberExpression") || !child.computed || !isNodeOfType(child.property, "Identifier") || child.property.name !== indexName) return;
|
|
46999
|
-
if (findVariableInitializer(child.property, indexName)?.bindingIdentifier === bindingIdentifier && lengthBoundCollections.some((collection) => areSameBoundStaticMemberChains(collection, child.object))) {
|
|
47000
|
-
didFindIndexedCollectionRead = true;
|
|
47001
|
-
return false;
|
|
47002
|
-
}
|
|
47003
|
-
});
|
|
47004
|
-
return didFindIndexedCollectionRead;
|
|
47005
|
-
};
|
|
47006
46718
|
/**
|
|
47007
46719
|
* Resolves whether an identifier is PROVABLY the positional array
|
|
47008
46720
|
* index, by classifying its binding. Per the official rule prompt,
|
|
@@ -47053,12 +46765,6 @@ const resolvePositionalIndexBinding = (identifierNode, depth) => {
|
|
|
47053
46765
|
}
|
|
47054
46766
|
const declarator = binding.bindingIdentifier.parent;
|
|
47055
46767
|
if (declarator && isNodeOfType(declarator, "VariableDeclarator") && declarator.id === binding.bindingIdentifier && declarator.init) {
|
|
47056
|
-
if (isDataIndexedWhileLoopCounter(identifierNode, binding.bindingIdentifier, identifierNode.name)) return {
|
|
47057
|
-
iteratorCall: null,
|
|
47058
|
-
bindingFunction: null,
|
|
47059
|
-
indexParameterPosition: null,
|
|
47060
|
-
isDataIndexedLoopCounter: true
|
|
47061
|
-
};
|
|
47062
46768
|
const initializer = stripParenExpression(declarator.init);
|
|
47063
46769
|
if (isNodeOfType(initializer, "Literal") && typeof initializer.value === "number") {
|
|
47064
46770
|
if (!INDEX_PARAMETER_NAMES.has(identifierNode.name)) return null;
|
|
@@ -47093,101 +46799,6 @@ const iteratorCallExemptsIndexKey = (iteratorCall) => {
|
|
|
47093
46799
|
const receiver = iteratorCall.callee.object;
|
|
47094
46800
|
return isStaticPlaceholderReceiver(receiver) || isFixedMemoReceiver(receiver) || isStaticDefaultLiteralReceiver(receiver) || isStringDerivedReceiver(receiver);
|
|
47095
46801
|
};
|
|
47096
|
-
const isReactNamespaceIdentifier = (node) => {
|
|
47097
|
-
if (!isNodeOfType(node, "Identifier")) return false;
|
|
47098
|
-
const importBinding = getImportBindingForName(node, node.name);
|
|
47099
|
-
const visibleBinding = findVariableInitializer(node, node.name);
|
|
47100
|
-
if (!importBinding) return node.name === "React" && !visibleBinding;
|
|
47101
|
-
return visibleBinding?.initializer?.type.startsWith("Import") === true && importBinding.source === "react" && (importBinding.isNamespace || importBinding.exportedName === "default");
|
|
47102
|
-
};
|
|
47103
|
-
const isReactChildrenObject = (node) => {
|
|
47104
|
-
const candidate = stripParenExpression(node);
|
|
47105
|
-
if (isNodeOfType(candidate, "Identifier")) {
|
|
47106
|
-
const importBinding = getImportBindingForName(candidate, candidate.name);
|
|
47107
|
-
const visibleBinding = findVariableInitializer(candidate, candidate.name);
|
|
47108
|
-
return Boolean(visibleBinding?.initializer?.type === "ImportSpecifier" && importBinding?.source === "react" && importBinding.exportedName === "Children");
|
|
47109
|
-
}
|
|
47110
|
-
return Boolean(isNodeOfType(candidate, "MemberExpression") && !candidate.computed && isReactNamespaceIdentifier(candidate.object) && isNodeOfType(candidate.property, "Identifier") && candidate.property.name === "Children");
|
|
47111
|
-
};
|
|
47112
|
-
const isReactChildrenToArrayCall = (node) => {
|
|
47113
|
-
const candidate = stripParenExpression(node);
|
|
47114
|
-
if (!isNodeOfType(candidate, "CallExpression") || !isNodeOfType(candidate.callee, "MemberExpression") || candidate.callee.computed || !isReactChildrenObject(candidate.callee.object) || !isNodeOfType(candidate.callee.property, "Identifier") || candidate.callee.property.name !== "toArray") return false;
|
|
47115
|
-
const normalizedValueNode = candidate.arguments?.[0];
|
|
47116
|
-
const normalizedValue = normalizedValueNode ? stripParenExpression(normalizedValueNode) : null;
|
|
47117
|
-
if (!normalizedValue || !isNodeOfType(normalizedValue, "Identifier") || normalizedValue.name !== "children") return false;
|
|
47118
|
-
const normalizedBinding = findVariableInitializer(normalizedValue, normalizedValue.name);
|
|
47119
|
-
return Boolean(normalizedBinding && findEnclosingParameter(normalizedBinding.bindingIdentifier));
|
|
47120
|
-
};
|
|
47121
|
-
const isSameIdentifier = (first, second) => {
|
|
47122
|
-
const firstIdentifier = stripParenExpression(first);
|
|
47123
|
-
const secondIdentifier = stripParenExpression(second);
|
|
47124
|
-
if (!isNodeOfType(firstIdentifier, "Identifier") || !isNodeOfType(secondIdentifier, "Identifier") || firstIdentifier.name !== secondIdentifier.name) return false;
|
|
47125
|
-
const firstBinding = findVariableInitializer(firstIdentifier, firstIdentifier.name);
|
|
47126
|
-
const secondBinding = findVariableInitializer(secondIdentifier, secondIdentifier.name);
|
|
47127
|
-
return firstBinding?.bindingIdentifier === secondBinding?.bindingIdentifier;
|
|
47128
|
-
};
|
|
47129
|
-
const isReactChildrenArrayNormalization = (node) => {
|
|
47130
|
-
const candidate = stripParenExpression(node);
|
|
47131
|
-
if (!isNodeOfType(candidate, "ConditionalExpression")) return false;
|
|
47132
|
-
const test = stripParenExpression(candidate.test);
|
|
47133
|
-
if (!isNodeOfType(test, "CallExpression") || !isNodeOfType(test.callee, "MemberExpression") || test.callee.computed || !isNodeOfType(test.callee.object, "Identifier") || test.callee.object.name !== "Array" || findVariableInitializer(test.callee.object, "Array") || !isNodeOfType(test.callee.property, "Identifier") || test.callee.property.name !== "isArray") return false;
|
|
47134
|
-
const testedValueNode = test.arguments?.[0];
|
|
47135
|
-
if (!testedValueNode) return false;
|
|
47136
|
-
const testedValue = stripParenExpression(testedValueNode);
|
|
47137
|
-
if (!isNodeOfType(testedValue, "Identifier")) return false;
|
|
47138
|
-
const testedBinding = findVariableInitializer(testedValue, testedValue.name);
|
|
47139
|
-
if (testedValue.name !== "children" || !testedBinding || !findEnclosingParameter(testedBinding.bindingIdentifier)) return false;
|
|
47140
|
-
const branchWrapsTestedValue = (branch) => {
|
|
47141
|
-
const unwrappedBranch = stripParenExpression(branch);
|
|
47142
|
-
return isNodeOfType(unwrappedBranch, "ArrayExpression") && unwrappedBranch.elements?.length === 1 && Boolean(unwrappedBranch.elements[0] && isSameIdentifier(unwrappedBranch.elements[0], testedValue));
|
|
47143
|
-
};
|
|
47144
|
-
return isSameIdentifier(candidate.consequent, testedValue) && branchWrapsTestedValue(candidate.alternate) || isSameIdentifier(candidate.alternate, testedValue) && branchWrapsTestedValue(candidate.consequent);
|
|
47145
|
-
};
|
|
47146
|
-
const isMutatedEmptyArrayBinding = (identifierNode, depth) => {
|
|
47147
|
-
const binding = findVariableInitializer(identifierNode, identifierNode.name);
|
|
47148
|
-
const initializer = binding?.initializer ? stripParenExpression(binding.initializer) : null;
|
|
47149
|
-
if (!binding || !initializer || !isNodeOfType(initializer, "ArrayExpression") || initializer.elements?.length !== 0) return false;
|
|
47150
|
-
const program = findProgramRoot(identifierNode);
|
|
47151
|
-
if (!program) return false;
|
|
47152
|
-
let didFindReactChildPush = false;
|
|
47153
|
-
walkAst(program, (child) => {
|
|
47154
|
-
if (didFindReactChildPush) return false;
|
|
47155
|
-
if (!isNodeOfType(child, "CallExpression") || !isNodeOfType(child.callee, "MemberExpression") || child.callee.computed || !isNodeOfType(child.callee.object, "Identifier") || child.callee.object.name !== identifierNode.name || !isNodeOfType(child.callee.property, "Identifier") || child.callee.property.name !== "push") return;
|
|
47156
|
-
if (findVariableInitializer(child.callee.object, identifierNode.name)?.bindingIdentifier === binding.bindingIdentifier && (child.arguments ?? []).some((argument) => {
|
|
47157
|
-
const candidate = stripParenExpression(argument);
|
|
47158
|
-
if (!(isNodeOfType(candidate, "Identifier") || isNodeOfType(candidate, "JSXElement") || isNodeOfType(candidate, "JSXFragment"))) return false;
|
|
47159
|
-
let doesCarryReactChild = false;
|
|
47160
|
-
walkAst(candidate, (argumentChild) => {
|
|
47161
|
-
if (doesCarryReactChild) return false;
|
|
47162
|
-
if (!isNodeOfType(argumentChild, "Identifier")) return;
|
|
47163
|
-
const declarator = findVariableInitializer(argumentChild, argumentChild.name)?.bindingIdentifier.parent;
|
|
47164
|
-
const declaration = declarator?.parent;
|
|
47165
|
-
const forOfStatement = declaration?.parent;
|
|
47166
|
-
if (declarator && isNodeOfType(declarator, "VariableDeclarator") && declaration && isNodeOfType(declaration, "VariableDeclaration") && forOfStatement && isNodeOfType(forOfStatement, "ForOfStatement") && forOfStatement.left === declaration && isDynamicReactChildrenExpression(forOfStatement.right, depth + 1)) {
|
|
47167
|
-
doesCarryReactChild = true;
|
|
47168
|
-
return false;
|
|
47169
|
-
}
|
|
47170
|
-
});
|
|
47171
|
-
return doesCarryReactChild;
|
|
47172
|
-
})) {
|
|
47173
|
-
didFindReactChildPush = true;
|
|
47174
|
-
return false;
|
|
47175
|
-
}
|
|
47176
|
-
});
|
|
47177
|
-
return didFindReactChildPush;
|
|
47178
|
-
};
|
|
47179
|
-
const isDynamicReactChildrenExpression = (expression, depth) => {
|
|
47180
|
-
if (depth > TYPE_RESOLUTION_DEPTH_LIMIT$2) return false;
|
|
47181
|
-
const candidate = stripParenExpression(expression);
|
|
47182
|
-
if (isReactChildrenToArrayCall(candidate) || isReactChildrenArrayNormalization(candidate)) return true;
|
|
47183
|
-
if (isNodeOfType(candidate, "Identifier")) {
|
|
47184
|
-
if (isMutatedEmptyArrayBinding(candidate, depth)) return true;
|
|
47185
|
-
const binding = findVariableInitializer(candidate, candidate.name);
|
|
47186
|
-
return Boolean(binding?.initializer && isDynamicReactChildrenExpression(binding.initializer, depth + 1));
|
|
47187
|
-
}
|
|
47188
|
-
if (isNodeOfType(candidate, "CallExpression") && isNodeOfType(candidate.callee, "MemberExpression") && !candidate.callee.computed && isNodeOfType(candidate.callee.property, "Identifier") && candidate.callee.property.name === "filter") return isDynamicReactChildrenExpression(candidate.callee.object, depth + 1);
|
|
47189
|
-
return false;
|
|
47190
|
-
};
|
|
47191
46802
|
const resolveKeyTemplateLiteral = (expression) => {
|
|
47192
46803
|
const node = stripParenExpression(expression);
|
|
47193
46804
|
if (isNodeOfType(node, "TemplateLiteral")) return node;
|
|
@@ -47240,19 +46851,28 @@ const findBareItemNamesReferencedByTemplate = (template, itemNames) => {
|
|
|
47240
46851
|
}
|
|
47241
46852
|
return referencedItemNames;
|
|
47242
46853
|
};
|
|
47243
|
-
const
|
|
46854
|
+
const forLoopTestReadsDataLength = (test) => {
|
|
46855
|
+
let didFindLengthRead = false;
|
|
46856
|
+
walkAst(test, (child) => {
|
|
46857
|
+
if (didFindLengthRead) return false;
|
|
46858
|
+
if (isNodeOfType(child, "MemberExpression") && isNodeOfType(child.property, "Identifier") && child.property.name === "length") {
|
|
46859
|
+
didFindLengthRead = true;
|
|
46860
|
+
return false;
|
|
46861
|
+
}
|
|
46862
|
+
});
|
|
46863
|
+
return didFindLengthRead;
|
|
46864
|
+
};
|
|
46865
|
+
const isNumericForLoopCounter = (attributeNode, indexName) => {
|
|
47244
46866
|
const binding = findVariableInitializer(attributeNode, indexName);
|
|
47245
46867
|
if (!binding) return false;
|
|
47246
46868
|
const declarator = binding.bindingIdentifier.parent;
|
|
47247
46869
|
if (!declarator || !isNodeOfType(declarator, "VariableDeclarator")) return false;
|
|
47248
46870
|
const declaration = declarator.parent;
|
|
47249
46871
|
if (!declaration || !isNodeOfType(declaration, "VariableDeclaration")) return false;
|
|
47250
|
-
if (!declarator.init || !isNodeOfType(declarator.init, "Literal") || typeof declarator.init.value !== "number") return false;
|
|
47251
46872
|
const forStatement = declaration.parent;
|
|
47252
|
-
if (forStatement
|
|
47253
|
-
|
|
47254
|
-
|
|
47255
|
-
return !loopTestBoundsCounterByLength(whileLoop.test, indexName, binding.bindingIdentifier);
|
|
46873
|
+
if (!forStatement || !isNodeOfType(forStatement, "ForStatement") || forStatement.init !== declaration || !declarator.init || !isNodeOfType(declarator.init, "Literal") || typeof declarator.init.value !== "number") return false;
|
|
46874
|
+
if (forStatement.test && forLoopTestReadsDataLength(forStatement.test)) return false;
|
|
46875
|
+
return true;
|
|
47256
46876
|
};
|
|
47257
46877
|
const EMPTY_NAME_SET$1 = /* @__PURE__ */ new Set();
|
|
47258
46878
|
const findIteratorItemNamesOfBinding = (binding) => {
|
|
@@ -47286,11 +46906,11 @@ const collectDerivedRowContentNames = (bindingFunction, itemNames) => {
|
|
|
47286
46906
|
* observable harm; anything stateful — form controls, media, custom
|
|
47287
46907
|
* components, unknown calls — keeps the diagnostic.
|
|
47288
46908
|
*/
|
|
47289
|
-
const fragmentHasStatefulChildren = (openingElement, itemNames, derivedNames
|
|
46909
|
+
const fragmentHasStatefulChildren = (openingElement, itemNames, derivedNames) => {
|
|
47290
46910
|
const jsxElement = openingElement.parent;
|
|
47291
46911
|
if (!jsxElement || !isNodeOfType(jsxElement, "JSXElement")) return false;
|
|
47292
46912
|
const children = jsxElement.children ?? [];
|
|
47293
|
-
const bareIdentifierNames = children.some((child) => isNodeOfType(child, "JSXElement")) ? derivedNames :
|
|
46913
|
+
const bareIdentifierNames = children.some((child) => isNodeOfType(child, "JSXElement")) ? derivedNames : new Set([...derivedNames, ...itemNames]);
|
|
47294
46914
|
return children.some((child) => containsStatefulDescendant(child, {
|
|
47295
46915
|
memberRootNames: itemNames,
|
|
47296
46916
|
allowAnyMemberRead: true,
|
|
@@ -47298,15 +46918,6 @@ const fragmentHasStatefulChildren = (openingElement, itemNames, derivedNames, ar
|
|
|
47298
46918
|
callCalleeRootNames: itemNames
|
|
47299
46919
|
}));
|
|
47300
46920
|
};
|
|
47301
|
-
const elementHasDirectItemChild = (openingElement, itemNames) => {
|
|
47302
|
-
const jsxElement = openingElement.parent;
|
|
47303
|
-
if (!jsxElement || !isNodeOfType(jsxElement, "JSXElement")) return false;
|
|
47304
|
-
return (jsxElement.children ?? []).some((child) => {
|
|
47305
|
-
if (!isNodeOfType(child, "JSXExpressionContainer")) return false;
|
|
47306
|
-
const expression = stripParenExpression(child.expression);
|
|
47307
|
-
return isNodeOfType(expression, "Identifier") && itemNames.has(expression.name);
|
|
47308
|
-
});
|
|
47309
|
-
};
|
|
47310
46921
|
const callbackFiltersRows = (bindingFunction) => {
|
|
47311
46922
|
if (!bindingFunction) return false;
|
|
47312
46923
|
let didFindNullReturn = false;
|
|
@@ -47358,21 +46969,19 @@ const noArrayIndexAsKey = defineRule({
|
|
|
47358
46969
|
const indexUse = findPositionalIndexUse(node.value.expression, 0);
|
|
47359
46970
|
if (!indexUse) return;
|
|
47360
46971
|
const indexName = indexUse.identifier.name;
|
|
47361
|
-
if (
|
|
46972
|
+
if (isNumericForLoopCounter(node, indexName)) return;
|
|
47362
46973
|
if (indexUse.binding.iteratorCall && iteratorCallExemptsIndexKey(indexUse.binding.iteratorCall)) return;
|
|
47363
46974
|
const keyTemplate = resolveKeyTemplateLiteral(node.value.expression);
|
|
47364
46975
|
if (keyTemplate && templateHasOuterMemberIdentity(keyTemplate, indexUse.binding.bindingFunction)) return;
|
|
47365
|
-
if (hasAriaHiddenAncestor(node)
|
|
46976
|
+
if (hasAriaHiddenAncestor(node)) return;
|
|
47366
46977
|
const itemNames = findIteratorItemNamesOfBinding(indexUse.binding);
|
|
47367
46978
|
const derivedNames = collectDerivedRowContentNames(indexUse.binding.bindingFunction, itemNames);
|
|
47368
|
-
const iteratorCallee = indexUse.binding.iteratorCall?.callee;
|
|
47369
|
-
const hasDynamicReactChildren = Boolean(iteratorCallee && isNodeOfType(iteratorCallee, "MemberExpression") && isDynamicReactChildrenExpression(iteratorCallee.object, 0));
|
|
47370
46979
|
const openingElement = node.parent;
|
|
47371
46980
|
if (openingElement && isNodeOfType(openingElement, "JSXOpeningElement")) {
|
|
47372
46981
|
const elementName = openingElement.name;
|
|
47373
46982
|
if (isNodeOfType(elementName, "JSXIdentifier")) {
|
|
47374
46983
|
if (elementName.name === "Fragment") {
|
|
47375
|
-
if (!fragmentHasStatefulChildren(openingElement, itemNames, derivedNames
|
|
46984
|
+
if (!fragmentHasStatefulChildren(openingElement, itemNames, derivedNames)) return;
|
|
47376
46985
|
} else if (PURE_SVG_PRIMITIVE_TAGS.has(elementName.name)) {
|
|
47377
46986
|
if (!callbackFiltersRows(indexUse.binding.bindingFunction)) return;
|
|
47378
46987
|
} else if (STATELESS_HTML_LEAF_TAGS.has(elementName.name)) {
|
|
@@ -47380,14 +46989,14 @@ const noArrayIndexAsKey = defineRule({
|
|
|
47380
46989
|
if (jsxElement && isNodeOfType(jsxElement, "JSXElement")) {
|
|
47381
46990
|
const isInlineTextRun = INLINE_TEXT_LEAF_TAGS.has(elementName.name);
|
|
47382
46991
|
const primitiveItemNames = keyTemplate ? findBareItemNamesReferencedByTemplate(keyTemplate, itemNames) : EMPTY_NAME_SET$1;
|
|
47383
|
-
if (!
|
|
46992
|
+
if (!containsStatefulDescendant(jsxElement, {
|
|
47384
46993
|
memberRootNames: isInlineTextRun ? itemNames : EMPTY_NAME_SET$1,
|
|
47385
46994
|
bareIdentifierNames: primitiveItemNames.size > 0 ? new Set([...derivedNames, ...primitiveItemNames]) : derivedNames
|
|
47386
|
-
}))
|
|
46995
|
+
})) return;
|
|
47387
46996
|
}
|
|
47388
46997
|
}
|
|
47389
46998
|
}
|
|
47390
|
-
if (isNodeOfType(elementName, "JSXMemberExpression") && isNodeOfType(elementName.object, "JSXIdentifier") && isNodeOfType(elementName.property, "JSXIdentifier") && elementName.object.name === "React" && elementName.property.name === "Fragment" && !fragmentHasStatefulChildren(openingElement, itemNames, derivedNames
|
|
46999
|
+
if (isNodeOfType(elementName, "JSXMemberExpression") && isNodeOfType(elementName.object, "JSXIdentifier") && isNodeOfType(elementName.property, "JSXIdentifier") && elementName.object.name === "React" && elementName.property.name === "Fragment" && !fragmentHasStatefulChildren(openingElement, itemNames, derivedNames)) return;
|
|
47391
47000
|
}
|
|
47392
47001
|
context.report({
|
|
47393
47002
|
node,
|