oxlint-plugin-react-doctor 0.7.2-dev.6ae8e46 → 0.7.2-dev.9b59d96

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 +26 -63
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -8980,24 +8980,6 @@ const isAstDescendant = (inner, outer) => {
8980
8980
  return false;
8981
8981
  };
8982
8982
  //#endregion
8983
- //#region src/plugin/utils/is-imported-from-non-react-module.ts
8984
- const isImportedFromNonReactModule = (contextNode, localIdentifierName) => {
8985
- const importSource = getImportSourceForName(contextNode, localIdentifierName);
8986
- if (importSource === null) return false;
8987
- return !REACT_RUNTIME_MODULE_SOURCES.has(importSource);
8988
- };
8989
- //#endregion
8990
- //#region src/plugin/utils/is-non-react-effect-event-callee.ts
8991
- const resolvesToLocalNonImportBinding = (identifier, scopes) => {
8992
- const symbol = scopes.referenceFor(identifier)?.resolvedSymbol;
8993
- return Boolean(symbol && symbol.kind !== "import");
8994
- };
8995
- const isNonReactEffectEventCallee = (callee, contextNode, scopes) => {
8996
- if (isNodeOfType(callee, "Identifier")) return isImportedFromNonReactModule(contextNode, callee.name) || resolvesToLocalNonImportBinding(callee, scopes);
8997
- if (isNodeOfType(callee, "MemberExpression") && !callee.computed && isNodeOfType(callee.object, "Identifier")) return isImportedFromNonReactModule(contextNode, callee.object.name);
8998
- return false;
8999
- };
9000
- //#endregion
9001
8983
  //#region src/plugin/rules/react-builtins/exhaustive-deps-symbol-stability.ts
9002
8984
  /**
9003
8985
  * Symbol-stability helpers consumed by the `exhaustive-deps` rule.
@@ -9062,11 +9044,10 @@ const symbolHasStableHookOrigin = (symbol) => {
9062
9044
  }
9063
9045
  return false;
9064
9046
  };
9065
- const symbolHasUseEffectEventOrigin = (symbol, scopes) => {
9047
+ const symbolHasUseEffectEventOrigin = (symbol) => {
9066
9048
  const initializer = symbol.initializer ? unwrapExpression$3(symbol.initializer) : null;
9067
9049
  if (!initializer || !isNodeOfType(initializer, "CallExpression")) return false;
9068
- if (getHookName(initializer.callee) !== "useEffectEvent") return false;
9069
- return !isNonReactEffectEventCallee(initializer.callee, initializer, scopes);
9050
+ return getHookName(initializer.callee) === "useEffectEvent";
9070
9051
  };
9071
9052
  const getFunctionValueNode = (symbol) => {
9072
9053
  if (symbol.kind === "function" && isNodeOfType(symbol.declarationNode, "FunctionDeclaration")) return symbol.declarationNode;
@@ -9803,7 +9784,7 @@ If the missing value is recreated every render, move it inside the hook or stabi
9803
9784
  if (isLiteralOrEmptyTemplate(stripped)) continue;
9804
9785
  if (isNodeOfType(stripped, "Identifier")) {
9805
9786
  const depSymbol = context.scopes.symbolFor(stripped);
9806
- if (depSymbol && symbolHasUseEffectEventOrigin(depSymbol, context.scopes)) {
9787
+ if (depSymbol && symbolHasUseEffectEventOrigin(depSymbol)) {
9807
9788
  context.report({
9808
9789
  node: elementNode,
9809
9790
  message: buildEffectEventDepMessage()
@@ -25779,33 +25760,6 @@ const initializerMarksPlainState = (initializerArgument) => {
25779
25760
  }
25780
25761
  return producesPlainStateValue(unwrapped);
25781
25762
  };
25782
- const producesOpaqueInstanceValue = (expression) => {
25783
- if (isNodeOfType(expression, "NewExpression")) return true;
25784
- return isNodeOfType(expression, "CallExpression") && isNodeOfType(expression.callee, "MemberExpression") && !isPlainDataProducerCall(expression);
25785
- };
25786
- const collectSetterValueObservations = (componentBody, setterNames) => {
25787
- const plainFedSetterNames = /* @__PURE__ */ new Set();
25788
- const opaqueFedSetterNames = /* @__PURE__ */ new Set();
25789
- walkAst(componentBody, (node) => {
25790
- if (!isNodeOfType(node, "CallExpression")) return;
25791
- if (!isNodeOfType(node.callee, "Identifier")) return;
25792
- const setterName = node.callee.name;
25793
- if (!setterNames.has(setterName)) return;
25794
- const argument = node.arguments?.[0];
25795
- if (!argument) return;
25796
- const unwrapped = stripParenExpression(argument);
25797
- if (isNullOrUndefinedExpression(unwrapped)) return;
25798
- if (producesPlainStateValue(unwrapped)) {
25799
- plainFedSetterNames.add(setterName);
25800
- return;
25801
- }
25802
- if (producesOpaqueInstanceValue(unwrapped)) opaqueFedSetterNames.add(setterName);
25803
- });
25804
- return {
25805
- plainFedSetterNames,
25806
- opaqueFedSetterNames
25807
- };
25808
- };
25809
25763
  const collectCallbackRefSetterNames = (componentBody) => {
25810
25764
  const callbackRefSetterNames = /* @__PURE__ */ new Set();
25811
25765
  walkAst(componentBody, (node) => {
@@ -25875,15 +25829,11 @@ const noDirectStateMutation = defineRule({
25875
25829
  if (bindings.length === 0) return;
25876
25830
  const stateValueToSetter = new Map(bindings.map((binding) => [binding.valueName, binding.setterName]));
25877
25831
  const callbackRefSetterNames = collectCallbackRefSetterNames(componentBody);
25878
- const setterValueObservations = collectSetterValueObservations(componentBody, new Set(bindings.map((binding) => binding.setterName)));
25879
25832
  const plainObjectStateValueNames = /* @__PURE__ */ new Set();
25880
25833
  for (const binding of bindings) {
25881
25834
  if (callbackRefSetterNames.has(binding.setterName)) continue;
25882
25835
  if (!isNodeOfType(binding.declarator.init, "CallExpression")) continue;
25883
- const initializerArgument = binding.declarator.init.arguments?.[0];
25884
- if (!initializerMarksPlainState(initializerArgument)) continue;
25885
- if ((!initializerArgument || isNullOrUndefinedExpression(stripParenExpression(initializerArgument))) && setterValueObservations.opaqueFedSetterNames.has(binding.setterName) && !setterValueObservations.plainFedSetterNames.has(binding.setterName)) continue;
25886
- plainObjectStateValueNames.add(binding.valueName);
25836
+ if (initializerMarksPlainState(binding.declarator.init.arguments?.[0])) plainObjectStateValueNames.add(binding.valueName);
25887
25837
  }
25888
25838
  const visitMutationCandidate = (child, currentlyShadowed) => {
25889
25839
  if (isNodeOfType(child, "AssignmentExpression")) {
@@ -26664,6 +26614,13 @@ const noEffectEventHandler = defineRule({
26664
26614
  }
26665
26615
  });
26666
26616
  //#endregion
26617
+ //#region src/plugin/utils/is-imported-from-non-react-module.ts
26618
+ const isImportedFromNonReactModule = (contextNode, localIdentifierName) => {
26619
+ const importSource = getImportSourceForName(contextNode, localIdentifierName);
26620
+ if (importSource === null) return false;
26621
+ return !REACT_RUNTIME_MODULE_SOURCES.has(importSource);
26622
+ };
26623
+ //#endregion
26667
26624
  //#region src/plugin/rules/state-and-effects/no-effect-event-in-deps.ts
26668
26625
  const createComponentBindingStackTracker = (callbacks) => {
26669
26626
  const componentBindingStack = [];
@@ -26717,7 +26674,12 @@ const noEffectEventInDeps = defineRule({
26717
26674
  const initializer = declaratorNode.init;
26718
26675
  if (!initializer || !isNodeOfType(initializer, "CallExpression")) return;
26719
26676
  if (!isHookCall$2(initializer, "useEffectEvent")) return;
26720
- if (isNonReactEffectEventCallee(initializer.callee, declaratorNode, context.scopes)) return;
26677
+ if (isNodeOfType(initializer.callee, "Identifier")) {
26678
+ if (isImportedFromNonReactModule(declaratorNode, initializer.callee.name)) return;
26679
+ const calleeSymbol = context.scopes.referenceFor(initializer.callee)?.resolvedSymbol;
26680
+ if (calleeSymbol && calleeSymbol.kind !== "import") return;
26681
+ }
26682
+ if (isNodeOfType(initializer.callee, "MemberExpression") && !initializer.callee.computed && isNodeOfType(initializer.callee.object, "Identifier") && isImportedFromNonReactModule(declaratorNode, initializer.callee.object.name)) return;
26721
26683
  componentBindings.addBindingToCurrentFrame(declaratorNode.id.name);
26722
26684
  } });
26723
26685
  return {
@@ -37388,10 +37350,6 @@ const isRouteFactoryCall = (expression) => {
37388
37350
  }
37389
37351
  return false;
37390
37352
  };
37391
- const isConfigOnlyFactoryCall = (call) => call.arguments.every((argument) => {
37392
- const expression = skipTsExpression(argument);
37393
- return isNodeOfType(expression, "ObjectExpression") || isNodeOfType(expression, "Literal") || isNodeOfType(expression, "TemplateLiteral");
37394
- });
37395
37353
  const isReactHocName = (name, state) => state.customHocs.has(name);
37396
37354
  const isHocCallee = (callee, state) => {
37397
37355
  if (isNodeOfType(callee, "Identifier")) return isReactHocName(callee.name, state);
@@ -37624,10 +37582,6 @@ const onlyExportComponents = defineRule({
37624
37582
  return false;
37625
37583
  })();
37626
37584
  if (isHoc && firstArgIsValid) hasReactExport = true;
37627
- else if (!isHoc && isConfigOnlyFactoryCall(stripped)) exports.push({
37628
- kind: "non-component",
37629
- reportNode: stripped
37630
- });
37631
37585
  else context.report({
37632
37586
  node: stripped,
37633
37587
  message: ANONYMOUS_MESSAGE
@@ -48600,6 +48554,15 @@ const isUseEffectEventSymbol = (symbol) => {
48600
48554
  if (!initializer || !isNodeOfType(initializer, "CallExpression")) return false;
48601
48555
  return getHookNameFromCallee(initializer.callee) === "useEffectEvent";
48602
48556
  };
48557
+ const resolvesToLocalNonImportBinding = (identifier, scopes) => {
48558
+ const symbol = scopes.referenceFor(identifier)?.resolvedSymbol;
48559
+ return Boolean(symbol && symbol.kind !== "import");
48560
+ };
48561
+ const isNonReactEffectEventCallee = (callee, contextNode, scopes) => {
48562
+ if (isNodeOfType(callee, "Identifier")) return isImportedFromNonReactModule(contextNode, callee.name) || resolvesToLocalNonImportBinding(callee, scopes);
48563
+ if (isNodeOfType(callee, "MemberExpression") && !callee.computed && isNodeOfType(callee.object, "Identifier")) return isImportedFromNonReactModule(contextNode, callee.object.name);
48564
+ return false;
48565
+ };
48603
48566
  const isNonReactEffectEventSymbol = (symbol, contextNode, scopes) => {
48604
48567
  const initializer = symbol.initializer;
48605
48568
  if (!initializer || !isNodeOfType(initializer, "CallExpression")) return false;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "oxlint-plugin-react-doctor",
3
- "version": "0.7.2-dev.6ae8e46",
3
+ "version": "0.7.2-dev.9b59d96",
4
4
  "description": "React Doctor rules for oxlint.",
5
5
  "keywords": [
6
6
  "accessibility",