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.
Files changed (2) hide show
  1. package/dist/index.js +43 -31
  2. 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 isCreateContextCallee = (callee) => {
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
- const binding = getImportBindingForName(callee, callee.name);
26290
- return binding !== null && binding.exportedName === "createContext" && CONTEXT_MODULES.includes(binding.source);
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") && !callee.computed) {
26293
- const namespaceIdentifier = callee.object;
26294
- const propertyIdentifier = callee.property;
26295
- if (!isNodeOfType(namespaceIdentifier, "Identifier")) return false;
26296
- if (!isNodeOfType(propertyIdentifier, "Identifier")) return false;
26297
- if (propertyIdentifier.name !== "createContext") return false;
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 (!isCreateContextCallee(node.callee)) return;
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;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oxlint-plugin-react-doctor",
3
- "version": "0.7.5-dev.3afd146",
3
+ "version": "0.7.5-dev.0654849",
4
4
  "description": "React Doctor rules for oxlint.",
5
5
  "keywords": [
6
6
  "accessibility",