oxlint-plugin-react-doctor 0.7.5-dev.3afd146 → 0.7.5-dev.654849
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 +43 -31
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -7618,7 +7618,7 @@ const isCreateClassLikeCall = (node) => {
|
|
|
7618
7618
|
if (isNodeOfType(callee, "MemberExpression")) return getStaticMemberName$2(callee) === "createClass";
|
|
7619
7619
|
return false;
|
|
7620
7620
|
};
|
|
7621
|
-
const isCreateContextCall = (node) => {
|
|
7621
|
+
const isCreateContextCall$1 = (node) => {
|
|
7622
7622
|
if (!isNodeOfType(node, "CallExpression")) return false;
|
|
7623
7623
|
const callee = node.callee;
|
|
7624
7624
|
if (isNodeOfType(callee, "Identifier")) return callee.name === "createContext";
|
|
@@ -7795,7 +7795,7 @@ const displayName = defineRule({
|
|
|
7795
7795
|
}
|
|
7796
7796
|
},
|
|
7797
7797
|
CallExpression(node) {
|
|
7798
|
-
if (settings.checkContextObjects && isReactVersionAtLeast$1(settings.reactVersion, 16, 3) && isCreateContextCall(node)) {
|
|
7798
|
+
if (settings.checkContextObjects && isReactVersionAtLeast$1(settings.reactVersion, 16, 3) && isCreateContextCall$1(node)) {
|
|
7799
7799
|
const assignedName = getAssignedName(node);
|
|
7800
7800
|
if (assignedName) {
|
|
7801
7801
|
const programRoot = findProgramRoot(node);
|
|
@@ -26277,6 +26277,19 @@ const noCloneElement = defineRule({
|
|
|
26277
26277
|
} })
|
|
26278
26278
|
});
|
|
26279
26279
|
//#endregion
|
|
26280
|
+
//#region src/plugin/utils/get-call-method-name.ts
|
|
26281
|
+
/**
|
|
26282
|
+
* Returns the static method name of a call's callee when it's a
|
|
26283
|
+
* non-computed MemberExpression (`obj.method` → `"method"`), or
|
|
26284
|
+
* `null` otherwise. Used by `no-pass-data-to-parent` and
|
|
26285
|
+
* `no-pass-live-state-to-parent` to match the receiver-bound
|
|
26286
|
+
* method-call shape against an allow/block list.
|
|
26287
|
+
*/
|
|
26288
|
+
const getCallMethodName = (callee) => {
|
|
26289
|
+
if (isNodeOfType(callee, "MemberExpression") && !callee.computed && isNodeOfType(callee.property, "Identifier")) return callee.property.name;
|
|
26290
|
+
return null;
|
|
26291
|
+
};
|
|
26292
|
+
//#endregion
|
|
26280
26293
|
//#region src/plugin/rules/state-and-effects/no-create-context-in-render.ts
|
|
26281
26294
|
const MESSAGE$31 = "createContext() builds a new context every render, so every consumer gets cut off & resets.";
|
|
26282
26295
|
const CONTEXT_MODULES = [
|
|
@@ -26284,23 +26297,35 @@ const CONTEXT_MODULES = [
|
|
|
26284
26297
|
"use-context-selector",
|
|
26285
26298
|
"react-tracked"
|
|
26286
26299
|
];
|
|
26287
|
-
const
|
|
26300
|
+
const getSupportedContextImportSource = (symbol) => {
|
|
26301
|
+
if (symbol?.kind !== "import") return null;
|
|
26302
|
+
const importDeclaration = symbol.declarationNode.parent;
|
|
26303
|
+
if (!importDeclaration || !isNodeOfType(importDeclaration, "ImportDeclaration") || typeof importDeclaration.source.value !== "string" || !CONTEXT_MODULES.includes(importDeclaration.source.value)) return null;
|
|
26304
|
+
return importDeclaration.source.value;
|
|
26305
|
+
};
|
|
26306
|
+
const isSupportedNamespaceSymbol = (symbol) => getSupportedContextImportSource(symbol) !== null && Boolean(symbol && (isNodeOfType(symbol.declarationNode, "ImportDefaultSpecifier") || isNodeOfType(symbol.declarationNode, "ImportNamespaceSpecifier")));
|
|
26307
|
+
const isDestructuredCreateContextBinding = (identifier, scopes) => {
|
|
26308
|
+
if (!isNodeOfType(identifier, "Identifier")) return false;
|
|
26309
|
+
const symbol = scopes.symbolFor(identifier);
|
|
26310
|
+
if (symbol?.kind !== "const" || !symbol.initializer || !isNodeOfType(symbol.declarationNode, "VariableDeclarator") || !isNodeOfType(symbol.declarationNode.id, "ObjectPattern")) return false;
|
|
26311
|
+
const property = symbol.bindingIdentifier.parent;
|
|
26312
|
+
if (!property || !isNodeOfType(property, "Property") || getStaticPropertyKeyName(property, { allowComputedString: true }) !== "createContext") return false;
|
|
26313
|
+
const initializer = stripParenExpression(symbol.initializer);
|
|
26314
|
+
return isNodeOfType(initializer, "Identifier") && isSupportedNamespaceSymbol(resolveConstIdentifierAlias(initializer, scopes));
|
|
26315
|
+
};
|
|
26316
|
+
const isCreateContextCall = (node, scopes) => {
|
|
26317
|
+
const callee = stripParenExpression(node.callee);
|
|
26288
26318
|
if (isNodeOfType(callee, "Identifier")) {
|
|
26289
|
-
|
|
26290
|
-
|
|
26319
|
+
if (isDestructuredCreateContextBinding(callee, scopes)) return true;
|
|
26320
|
+
const symbol = resolveConstIdentifierAlias(callee, scopes);
|
|
26321
|
+
return getSupportedContextImportSource(symbol) !== null && Boolean(symbol && getImportedName(symbol.declarationNode) === "createContext");
|
|
26291
26322
|
}
|
|
26292
|
-
if (isNodeOfType(callee, "MemberExpression")
|
|
26293
|
-
|
|
26294
|
-
|
|
26295
|
-
|
|
26296
|
-
|
|
26297
|
-
|
|
26298
|
-
const namespaceName = namespaceIdentifier.name;
|
|
26299
|
-
if (isCanonicalReactNamespaceName(namespaceName)) return true;
|
|
26300
|
-
const importSource = getImportSourceForName(namespaceIdentifier, namespaceName);
|
|
26301
|
-
return importSource !== null && CONTEXT_MODULES.includes(importSource);
|
|
26302
|
-
}
|
|
26303
|
-
return false;
|
|
26323
|
+
if (!isNodeOfType(callee, "MemberExpression")) return false;
|
|
26324
|
+
if ((getCallMethodName(callee) ?? (callee.computed && isNodeOfType(callee.property, "Literal") && typeof callee.property.value === "string" ? callee.property.value : null)) !== "createContext") return false;
|
|
26325
|
+
const receiver = stripParenExpression(callee.object);
|
|
26326
|
+
if (!isNodeOfType(receiver, "Identifier")) return false;
|
|
26327
|
+
if (receiver.name === "React" && scopes.isGlobalReference(receiver)) return true;
|
|
26328
|
+
return isSupportedNamespaceSymbol(resolveConstIdentifierAlias(receiver, scopes));
|
|
26304
26329
|
};
|
|
26305
26330
|
const noCreateContextInRender = defineRule({
|
|
26306
26331
|
id: "no-create-context-in-render",
|
|
@@ -26309,7 +26334,7 @@ const noCreateContextInRender = defineRule({
|
|
|
26309
26334
|
category: "Correctness",
|
|
26310
26335
|
recommendation: "Move `createContext(...)` outside the component, to the top level of the file, so it stays the same on every render.",
|
|
26311
26336
|
create: (context) => ({ CallExpression(node) {
|
|
26312
|
-
if (!
|
|
26337
|
+
if (!isCreateContextCall(node, context.scopes)) return;
|
|
26313
26338
|
const componentOrHookName = enclosingComponentOrHookName(node);
|
|
26314
26339
|
if (!componentOrHookName) return;
|
|
26315
26340
|
context.report({
|
|
@@ -34574,19 +34599,6 @@ const DATA_SINK_METHOD_NAMES = new Set([
|
|
|
34574
34599
|
"deserialize"
|
|
34575
34600
|
]);
|
|
34576
34601
|
//#endregion
|
|
34577
|
-
//#region src/plugin/utils/get-call-method-name.ts
|
|
34578
|
-
/**
|
|
34579
|
-
* Returns the static method name of a call's callee when it's a
|
|
34580
|
-
* non-computed MemberExpression (`obj.method` → `"method"`), or
|
|
34581
|
-
* `null` otherwise. Used by `no-pass-data-to-parent` and
|
|
34582
|
-
* `no-pass-live-state-to-parent` to match the receiver-bound
|
|
34583
|
-
* method-call shape against an allow/block list.
|
|
34584
|
-
*/
|
|
34585
|
-
const getCallMethodName = (callee) => {
|
|
34586
|
-
if (isNodeOfType(callee, "MemberExpression") && !callee.computed && isNodeOfType(callee.property, "Identifier")) return callee.property.name;
|
|
34587
|
-
return null;
|
|
34588
|
-
};
|
|
34589
|
-
//#endregion
|
|
34590
34602
|
//#region src/plugin/rules/state-and-effects/no-pass-data-to-parent.ts
|
|
34591
34603
|
const isUseStateIdentifier = (identifier) => {
|
|
34592
34604
|
if (!isNodeOfType(identifier, "Identifier")) return false;
|