diff --git a/packages/core/src/jsx/jsx-attribute.ts b/packages/core/src/jsx/jsx-attribute.ts index 1c74673d37..07b3ca0823 100644 --- a/packages/core/src/jsx/jsx-attribute.ts +++ b/packages/core/src/jsx/jsx-attribute.ts @@ -1,9 +1,9 @@ import type * as AST from "@eslint-react/ast"; import type { RuleContext } from "@eslint-react/kit"; -import * as VAR from "@eslint-react/var"; +import { findProperty, findVariable, getVariableDefinitionNode } from "@eslint-react/var"; import type { Scope } from "@typescript-eslint/scope-manager"; - import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; + import { getAttributeName } from "./jsx-attribute-name"; export function getAttribute(context: RuleContext, attributes: AST.TSESTreeJSXAttributeLike[], initialScope?: Scope) { @@ -18,16 +18,16 @@ export function getAttribute(context: RuleContext, attributes: AST.TSESTreeJSXAt switch (attr.argument.type) { // Case 2: Spread from variable (e.g., {...props}) case T.Identifier: { - const variable = VAR.findVariable(attr.argument.name, initialScope); - const variableNode = VAR.getVariableDefinitionNode(variable, 0); + const variable = findVariable(attr.argument.name, initialScope); + const variableNode = getVariableDefinitionNode(variable, 0); if (variableNode?.type === T.ObjectExpression) { - return VAR.findProperty(name, variableNode.properties, initialScope) != null; + return findProperty(name, variableNode.properties, initialScope) != null; } return false; } // Case 3: Spread from object literal (e.g., {{...{prop: value}}}) case T.ObjectExpression: - return VAR.findProperty(name, attr.argument.properties, initialScope) != null; + return findProperty(name, attr.argument.properties, initialScope) != null; } return false; }); diff --git a/packages/core/src/jsx/jsx-detection.ts b/packages/core/src/jsx/jsx-detection.ts index e70976662f..9670e1e8ca 100644 --- a/packages/core/src/jsx/jsx-detection.ts +++ b/packages/core/src/jsx/jsx-detection.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/strict-boolean-expressions */ import * as AST from "@eslint-react/ast"; import type { unit } from "@eslint-react/eff"; -import * as VAR from "@eslint-react/var"; +import { findVariable, getVariableDefinitionNode } from "@eslint-react/var"; import type { Scope } from "@typescript-eslint/scope-manager"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { TSESTree } from "@typescript-eslint/utils"; @@ -185,9 +185,9 @@ export function isJsxLike( return true; } // Resolve variables to their values and check if they're JSX-like - const variable = VAR.findVariable(name, code.getScope(node)); + const variable = findVariable(name, code.getScope(node)); const variableNode = variable - && VAR.getVariableDefinitionNode(variable, 0); + && getVariableDefinitionNode(variable, 0); return !!variableNode && isJsxLike(code, variableNode, hint); } diff --git a/packages/core/src/utils/is-from-react.ts b/packages/core/src/utils/is-from-react.ts index d4f6cfb4be..d6484befa8 100644 --- a/packages/core/src/utils/is-from-react.ts +++ b/packages/core/src/utils/is-from-react.ts @@ -1,6 +1,6 @@ import * as AST from "@eslint-react/ast"; import { identity } from "@eslint-react/eff"; -import * as VAR from "@eslint-react/var"; +import { findVariable } from "@eslint-react/var"; import type { Scope } from "@typescript-eslint/scope-manager"; import type { TSESTree } from "@typescript-eslint/types"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; @@ -34,7 +34,7 @@ export function isInitializedFromReact( initialScope: Scope, ): boolean { if (name.toLowerCase() === "react") return true; - const latestDef = VAR.findVariable(name, initialScope)?.defs.at(-1); + const latestDef = findVariable(name, initialScope)?.defs.at(-1); if (latestDef == null) return false; const { node, parent } = latestDef; if (node.type === T.VariableDeclarator && node.init != null) { diff --git a/packages/core/src/utils/is-instance-id-equal.ts b/packages/core/src/utils/is-instance-id-equal.ts index cc57feb647..c76d06ee5d 100644 --- a/packages/core/src/utils/is-instance-id-equal.ts +++ b/packages/core/src/utils/is-instance-id-equal.ts @@ -1,12 +1,12 @@ /* eslint-disable jsdoc/require-param */ import * as AST from "@eslint-react/ast"; import type { RuleContext } from "@eslint-react/kit"; -import * as VAR from "@eslint-react/var"; +import { isNodeValueEqual } from "@eslint-react/var"; import type { TSESTree } from "@typescript-eslint/types"; /** @internal */ export function isInstanceIdEqual(context: RuleContext, a: TSESTree.Node, b: TSESTree.Node) { - return AST.isNodeEqual(a, b) || VAR.isNodeValueEqual(a, b, [ + return AST.isNodeEqual(a, b) || isNodeValueEqual(a, b, [ context.sourceCode.getScope(a), context.sourceCode.getScope(b), ]); diff --git a/packages/plugins/eslint-plugin-react-debug/src/rules/class-component.ts b/packages/plugins/eslint-plugin-react-debug/src/rules/class-component.ts index be2f752d24..d5416f175b 100644 --- a/packages/plugins/eslint-plugin-react-debug/src/rules/class-component.ts +++ b/packages/plugins/eslint-plugin-react-debug/src/rules/class-component.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { useComponentCollectorLegacy } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -31,7 +31,7 @@ export default createRule<[], MessageID>({ }); export function create(context: RuleContext): RuleListener { - const { ctx, listeners } = ER.useComponentCollectorLegacy(); + const { ctx, listeners } = useComponentCollectorLegacy(); return { ...listeners, "Program:exit"(program) { diff --git a/packages/plugins/eslint-plugin-react-debug/src/rules/function-component.ts b/packages/plugins/eslint-plugin-react-debug/src/rules/function-component.ts index e2122d8956..9da332a46e 100644 --- a/packages/plugins/eslint-plugin-react-debug/src/rules/function-component.ts +++ b/packages/plugins/eslint-plugin-react-debug/src/rules/function-component.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { ComponentFlag, DEFAULT_COMPONENT_DETECTION_HINT, useComponentCollector } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -32,12 +32,12 @@ export default createRule<[], MessageID>({ }); export function create(context: RuleContext): RuleListener { - const { ctx, listeners } = ER.useComponentCollector( + const { ctx, listeners } = useComponentCollector( context, { collectDisplayName: true, collectHookCalls: true, - hint: ER.DEFAULT_COMPONENT_DETECTION_HINT, + hint: DEFAULT_COMPONENT_DETECTION_HINT, }, ); return { @@ -54,9 +54,9 @@ export function create(context: RuleContext): RuleListener { displayName: displayName == null ? "none" : context.sourceCode.getText(displayName), - forwardRef: (flag & ER.ComponentFlag.ForwardRef) > 0n, + forwardRef: (flag & ComponentFlag.ForwardRef) > 0n, hookCalls: hookCalls.length, - memo: (flag & ER.ComponentFlag.Memo) > 0n, + memo: (flag & ComponentFlag.Memo) > 0n, }), }, }); diff --git a/packages/plugins/eslint-plugin-react-debug/src/rules/hook.ts b/packages/plugins/eslint-plugin-react-debug/src/rules/hook.ts index 1cbe599cc1..770e54ff9e 100644 --- a/packages/plugins/eslint-plugin-react-debug/src/rules/hook.ts +++ b/packages/plugins/eslint-plugin-react-debug/src/rules/hook.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { useHookCollector } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -31,7 +31,7 @@ export default createRule<[], MessageID>({ }); export function create(context: RuleContext): RuleListener { - const { ctx, listeners } = ER.useHookCollector(); + const { ctx, listeners } = useHookCollector(); return { ...listeners, diff --git a/packages/plugins/eslint-plugin-react-debug/src/rules/is-from-react.ts b/packages/plugins/eslint-plugin-react-debug/src/rules/is-from-react.ts index 19a0090e00..4dd791f472 100644 --- a/packages/plugins/eslint-plugin-react-debug/src/rules/is-from-react.ts +++ b/packages/plugins/eslint-plugin-react-debug/src/rules/is-from-react.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isInitializedFromReact } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import { getSettingsFromContext } from "@eslint-react/shared"; import type { Scope } from "@typescript-eslint/scope-manager"; @@ -79,12 +79,12 @@ function isFromReact( case node.parent.type === T.MemberExpression && node.parent.property === node && node.parent.object.type === T.Identifier: - return ER.isInitializedFromReact(node.parent.object.name, importSource, initialScope); + return isInitializedFromReact(node.parent.object.name, importSource, initialScope); case node.parent.type === T.JSXMemberExpression && node.parent.property === node && node.parent.object.type === T.JSXIdentifier: - return ER.isInitializedFromReact(node.parent.object.name, importSource, initialScope); + return isInitializedFromReact(node.parent.object.name, importSource, initialScope); default: - return ER.isInitializedFromReact(name, importSource, initialScope); + return isInitializedFromReact(name, importSource, initialScope); } } diff --git a/packages/plugins/eslint-plugin-react-dom/src/rules/no-dangerously-set-innerhtml-with-children.ts b/packages/plugins/eslint-plugin-react-dom/src/rules/no-dangerously-set-innerhtml-with-children.ts index 8d61df986f..ef7d613e51 100644 --- a/packages/plugins/eslint-plugin-react-dom/src/rules/no-dangerously-set-innerhtml-with-children.ts +++ b/packages/plugins/eslint-plugin-react-dom/src/rules/no-dangerously-set-innerhtml-with-children.ts @@ -1,9 +1,9 @@ -import * as ER from "@eslint-react/core"; +import { hasAttribute, isJsxText } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; +import { AST_NODE_TYPES, type TSESTree } from "@typescript-eslint/types"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; -import { AST_NODE_TYPES, type TSESTree } from "@typescript-eslint/types"; import { createRule } from "../utils"; export const RULE_NAME = "no-dangerously-set-innerhtml-with-children"; @@ -40,8 +40,8 @@ export function create(context: RuleContext): RuleListener { const attributes = node.openingElement.attributes; const initialScope = context.sourceCode.getScope(node); const hasChildren = node.children.some(isSignificantChildren) - || ER.hasAttribute(context, "children", attributes, initialScope); - if (hasChildren && ER.hasAttribute(context, dangerouslySetInnerHTML, attributes, initialScope)) { + || hasAttribute(context, "children", attributes, initialScope); + if (hasChildren && hasAttribute(context, dangerouslySetInnerHTML, attributes, initialScope)) { context.report({ messageId: "noDangerouslySetInnerhtmlWithChildren", node, @@ -66,7 +66,7 @@ function isWhiteSpace(node: TSESTree.JSXText | TSESTree.Literal) { * @returns boolean */ function isPaddingSpaces(node: TSESTree.Node) { - return ER.isJsxText(node) + return isJsxText(node) && isWhiteSpace(node) && node.raw.includes("\n"); } diff --git a/packages/plugins/eslint-plugin-react-dom/src/rules/no-dangerously-set-innerhtml.ts b/packages/plugins/eslint-plugin-react-dom/src/rules/no-dangerously-set-innerhtml.ts index 77b47d98ac..e478b63462 100644 --- a/packages/plugins/eslint-plugin-react-dom/src/rules/no-dangerously-set-innerhtml.ts +++ b/packages/plugins/eslint-plugin-react-dom/src/rules/no-dangerously-set-innerhtml.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { getAttribute } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -35,8 +35,8 @@ export function create(context: RuleContext): RuleListener { if (!context.sourceCode.text.includes(dangerouslySetInnerHTML)) return {}; return { JSXElement(node) { - const getAttribute = ER.getAttribute(context, node.openingElement.attributes, context.sourceCode.getScope(node)); - const attribute = getAttribute(dangerouslySetInnerHTML); + const getAttributeEx = getAttribute(context, node.openingElement.attributes, context.sourceCode.getScope(node)); + const attribute = getAttributeEx(dangerouslySetInnerHTML); if (attribute == null) return; context.report({ messageId: "noDangerouslySetInnerhtml", diff --git a/packages/plugins/eslint-plugin-react-dom/src/rules/no-missing-button-type.ts b/packages/plugins/eslint-plugin-react-dom/src/rules/no-missing-button-type.ts index 786d63eb0c..4a20ed9032 100644 --- a/packages/plugins/eslint-plugin-react-dom/src/rules/no-missing-button-type.ts +++ b/packages/plugins/eslint-plugin-react-dom/src/rules/no-missing-button-type.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { getAttribute, resolveAttributeValue } from "@eslint-react/core"; import type { RuleContext, RuleFeature, RuleSuggest } from "@eslint-react/kit"; import type { RuleFixer, RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -42,8 +42,8 @@ export function create(context: RuleContext): RuleListener { JSXElement(node) { const { domElementType } = resolver.resolve(node); if (domElementType !== "button") return; - const getAttribute = ER.getAttribute(context, node.openingElement.attributes, context.sourceCode.getScope(node)); - const typeAttribute = getAttribute("type"); + const getAttributeEx = getAttribute(context, node.openingElement.attributes, context.sourceCode.getScope(node)); + const typeAttribute = getAttributeEx("type"); if (typeAttribute == null) { context.report({ messageId: "noMissingButtonType", @@ -54,7 +54,7 @@ export function create(context: RuleContext): RuleListener { }); return; } - if (typeof ER.resolveAttributeValue(context, typeAttribute).toStatic("type") === "string") return; + if (typeof resolveAttributeValue(context, typeAttribute).toStatic("type") === "string") return; context.report({ messageId: "noMissingButtonType", node: typeAttribute, diff --git a/packages/plugins/eslint-plugin-react-dom/src/rules/no-missing-iframe-sandbox.ts b/packages/plugins/eslint-plugin-react-dom/src/rules/no-missing-iframe-sandbox.ts index 6ed80d904b..eb8d5c3eb9 100644 --- a/packages/plugins/eslint-plugin-react-dom/src/rules/no-missing-iframe-sandbox.ts +++ b/packages/plugins/eslint-plugin-react-dom/src/rules/no-missing-iframe-sandbox.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { getAttribute, resolveAttributeValue } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -41,8 +41,8 @@ export function create(context: RuleContext): RuleListener { JSXElement(node) { const { domElementType } = resolver.resolve(node); if (domElementType !== "iframe") return; - const getAttribute = ER.getAttribute(context, node.openingElement.attributes, context.sourceCode.getScope(node)); - const sandboxAttribute = getAttribute("sandbox"); + const getAttributeEx = getAttribute(context, node.openingElement.attributes, context.sourceCode.getScope(node)); + const sandboxAttribute = getAttributeEx("sandbox"); if (sandboxAttribute == null) { context.report({ messageId: "noMissingIframeSandbox", @@ -57,7 +57,7 @@ export function create(context: RuleContext): RuleListener { }); return; } - const sandboxAttributeValue = ER.resolveAttributeValue(context, sandboxAttribute); + const sandboxAttributeValue = resolveAttributeValue(context, sandboxAttribute); if (typeof sandboxAttributeValue.toStatic("sandbox") === "string") return; context.report({ messageId: "noMissingIframeSandbox", diff --git a/packages/plugins/eslint-plugin-react-dom/src/rules/no-namespace.ts b/packages/plugins/eslint-plugin-react-dom/src/rules/no-namespace.ts index 9802e2971e..459cd88a3f 100644 --- a/packages/plugins/eslint-plugin-react-dom/src/rules/no-namespace.ts +++ b/packages/plugins/eslint-plugin-react-dom/src/rules/no-namespace.ts @@ -1,7 +1,8 @@ -import * as ER from "@eslint-react/core"; +import { getElementType } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; + import { createRule } from "../utils"; export const RULE_NAME = "no-namespace"; @@ -30,7 +31,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { return { JSXElement(node) { - const name = ER.getElementType(context, node); + const name = getElementType(context, node); if (typeof name !== "string" || !name.includes(":")) { return; } diff --git a/packages/plugins/eslint-plugin-react-dom/src/rules/no-script-url.ts b/packages/plugins/eslint-plugin-react-dom/src/rules/no-script-url.ts index 13be56efd8..2e63d1afff 100644 --- a/packages/plugins/eslint-plugin-react-dom/src/rules/no-script-url.ts +++ b/packages/plugins/eslint-plugin-react-dom/src/rules/no-script-url.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { resolveAttributeValue } from "@eslint-react/core"; import { RE_JAVASCRIPT_PROTOCOL, type RuleContext, type RuleFeature } from "@eslint-react/kit"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; @@ -33,7 +33,7 @@ export function create(context: RuleContext): RuleListener { return { JSXAttribute(node) { if (node.name.type !== T.JSXIdentifier || node.value == null) return; - const value = ER.resolveAttributeValue(context, node).toStatic(); + const value = resolveAttributeValue(context, node).toStatic(); if (typeof value === "string" && RE_JAVASCRIPT_PROTOCOL.test(value)) { context.report({ messageId: "noScriptUrl", diff --git a/packages/plugins/eslint-plugin-react-dom/src/rules/no-string-style-prop.ts b/packages/plugins/eslint-plugin-react-dom/src/rules/no-string-style-prop.ts index 55a75617cb..2871ef1707 100644 --- a/packages/plugins/eslint-plugin-react-dom/src/rules/no-string-style-prop.ts +++ b/packages/plugins/eslint-plugin-react-dom/src/rules/no-string-style-prop.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { getAttribute, isHostElement, resolveAttributeValue } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -31,11 +31,11 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { return { JSXElement(node) { - if (!ER.isHostElement(context, node)) return; - const getAttribute = ER.getAttribute(context, node.openingElement.attributes, context.sourceCode.getScope(node)); - const attribute = getAttribute("style"); + if (!isHostElement(context, node)) return; + const getAttributeEx = getAttribute(context, node.openingElement.attributes, context.sourceCode.getScope(node)); + const attribute = getAttributeEx("style"); if (attribute == null) return; - const attributeValue = ER.resolveAttributeValue(context, attribute); + const attributeValue = resolveAttributeValue(context, attribute); if (typeof attributeValue.toStatic() === "string") { context.report({ messageId: "noStringStyleProp", diff --git a/packages/plugins/eslint-plugin-react-dom/src/rules/no-unsafe-iframe-sandbox.ts b/packages/plugins/eslint-plugin-react-dom/src/rules/no-unsafe-iframe-sandbox.ts index b46ded2fdf..11e9ed1dfb 100644 --- a/packages/plugins/eslint-plugin-react-dom/src/rules/no-unsafe-iframe-sandbox.ts +++ b/packages/plugins/eslint-plugin-react-dom/src/rules/no-unsafe-iframe-sandbox.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { getAttribute, resolveAttributeValue } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -45,10 +45,10 @@ export function create(context: RuleContext): RuleListener { JSXElement(node) { const { domElementType } = resolver.resolve(node); if (domElementType !== "iframe") return; - const getAttribute = ER.getAttribute(context, node.openingElement.attributes, context.sourceCode.getScope(node)); - const sandboxAttribute = getAttribute("sandbox"); + const getAttributeEx = getAttribute(context, node.openingElement.attributes, context.sourceCode.getScope(node)); + const sandboxAttribute = getAttributeEx("sandbox"); if (sandboxAttribute == null) return; - const sandboxValue = ER.resolveAttributeValue(context, sandboxAttribute); + const sandboxValue = resolveAttributeValue(context, sandboxAttribute); const sandboxValueStatic = sandboxValue.toStatic("sandbox"); if (!isSafeSandbox(sandboxValueStatic)) { context.report({ diff --git a/packages/plugins/eslint-plugin-react-dom/src/rules/no-unsafe-target-blank.ts b/packages/plugins/eslint-plugin-react-dom/src/rules/no-unsafe-target-blank.ts index db2e7a556d..d7e2320596 100644 --- a/packages/plugins/eslint-plugin-react-dom/src/rules/no-unsafe-target-blank.ts +++ b/packages/plugins/eslint-plugin-react-dom/src/rules/no-unsafe-target-blank.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { getAttribute, resolveAttributeValue } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { TSESTree } from "@typescript-eslint/types"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; @@ -71,28 +71,28 @@ export function create(context: RuleContext): RuleListener { if (domElementType !== "a") return; // Get access to the component attributes - const getAttributes = ER.getAttribute( + const getAttributeEx = getAttribute( context, node.openingElement.attributes, context.sourceCode.getScope(node), ); // Check if target="_blank" is present - const targetAttribute = getAttributes("target"); + const targetAttribute = getAttributeEx("target"); if (targetAttribute == null) return; - const targetAttributeValue = ER.resolveAttributeValue(context, targetAttribute).toStatic("target"); + const targetAttributeValue = resolveAttributeValue(context, targetAttribute).toStatic("target"); if (targetAttributeValue !== "_blank") return; // Check if href points to an external resource - const hrefAttribute = getAttributes("href"); + const hrefAttribute = getAttributeEx("href"); if (hrefAttribute == null) return; - const hrefAttributeValue = ER.resolveAttributeValue(context, hrefAttribute).toStatic("href"); + const hrefAttributeValue = resolveAttributeValue(context, hrefAttribute).toStatic("href"); if (!isExternalLinkLike(hrefAttributeValue)) return; // Check if rel attribute exists and is secure - const relAttribute = getAttributes("rel"); + const relAttribute = getAttributeEx("rel"); // No rel attribute case - suggest adding one if (relAttribute == null) { @@ -113,7 +113,7 @@ export function create(context: RuleContext): RuleListener { } // Check if existing rel attribute is secure - const relAttributeValue = ER.resolveAttributeValue(context, relAttribute).toStatic("rel"); + const relAttributeValue = resolveAttributeValue(context, relAttribute).toStatic("rel"); if (isSafeRel(relAttributeValue)) return; // Existing rel attribute is not secure - suggest replacing it diff --git a/packages/plugins/eslint-plugin-react-dom/src/rules/no-void-elements-with-children.ts b/packages/plugins/eslint-plugin-react-dom/src/rules/no-void-elements-with-children.ts index 91cf57c07e..ce50de4d6c 100644 --- a/packages/plugins/eslint-plugin-react-dom/src/rules/no-void-elements-with-children.ts +++ b/packages/plugins/eslint-plugin-react-dom/src/rules/no-void-elements-with-children.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { hasAttribute } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -67,8 +67,8 @@ export function create(context: RuleContext): RuleListener { } const { attributes } = node.openingElement; const initialScope = context.sourceCode.getScope(node); - const hasAttribute = (name: string) => ER.hasAttribute(context, name, attributes, initialScope); - if (hasAttribute("children") || hasAttribute("dangerouslySetInnerHTML")) { + const hasAttributeEx = (name: string) => hasAttribute(context, name, attributes, initialScope); + if (hasAttributeEx("children") || hasAttributeEx("dangerouslySetInnerHTML")) { // e.g.
context.report({ messageId: "noVoidElementsWithChildren", diff --git a/packages/plugins/eslint-plugin-react-dom/src/utils/create-jsx-element-resolver.ts b/packages/plugins/eslint-plugin-react-dom/src/utils/create-jsx-element-resolver.ts index 9420a9357b..6628e068fe 100644 --- a/packages/plugins/eslint-plugin-react-dom/src/utils/create-jsx-element-resolver.ts +++ b/packages/plugins/eslint-plugin-react-dom/src/utils/create-jsx-element-resolver.ts @@ -1,8 +1,7 @@ +import { getAttribute, getElementType, resolveAttributeValue } from "@eslint-react/core"; import type { RuleContext } from "@eslint-react/kit"; -import type { TSESTree } from "@typescript-eslint/types"; - -import * as ER from "@eslint-react/core"; import { getSettingsFromContext } from "@eslint-react/shared"; +import type { TSESTree } from "@typescript-eslint/types"; /** * Creates a resolver for JSX elements that determines both the JSX element type @@ -27,7 +26,7 @@ export function createJsxElementResolver(context: RuleContext) { */ resolve(node: TSESTree.JSXElement) { // Get the element name/type (e.g., 'div', 'Button', etc.) - const elementName = ER.getElementType(context, node); + const elementName = getElementType(context, node); // Create the base result with element types const result = { @@ -43,12 +42,12 @@ export function createJsxElementResolver(context: RuleContext) { } // Look for the polymorphic prop (e.g., 'as', 'component') in the element's attributes - const getAttribute = ER.getAttribute(context, node.openingElement.attributes, context.sourceCode.getScope(node)); - const polymorphicProp = getAttribute(polymorphicPropName); + const getAttributeEx = getAttribute(context, node.openingElement.attributes, context.sourceCode.getScope(node)); + const polymorphicProp = getAttributeEx(polymorphicPropName); // If the polymorphic prop exists, try to determine its static value if (polymorphicProp != null) { - const polymorphicPropValue = ER.resolveAttributeValue(context, polymorphicProp); + const polymorphicPropValue = resolveAttributeValue(context, polymorphicProp); const staticValue = polymorphicPropValue.toStatic(polymorphicPropName); // If we have a string value, use it as the DOM element type diff --git a/packages/plugins/eslint-plugin-react-hooks-extra/src/rules/no-direct-set-state-in-use-effect.ts b/packages/plugins/eslint-plugin-react-hooks-extra/src/rules/no-direct-set-state-in-use-effect.ts index 32e4e25d4e..bde4d9a237 100644 --- a/packages/plugins/eslint-plugin-react-hooks-extra/src/rules/no-direct-set-state-in-use-effect.ts +++ b/packages/plugins/eslint-plugin-react-hooks-extra/src/rules/no-direct-set-state-in-use-effect.ts @@ -1,8 +1,8 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isUseCallbackCall, isUseEffectLikeCall, isUseMemoCall, isUseStateCall } from "@eslint-react/core"; import { constVoid, getOrElseUpdate, not } from "@eslint-react/eff"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; -import * as VAR from "@eslint-react/var"; +import { findVariable, getVariableDefinitionNode } from "@eslint-react/var"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { TSESTree } from "@typescript-eslint/utils"; import { getStaticValue } from "@typescript-eslint/utils/ast-utils"; @@ -81,7 +81,7 @@ export function create(context: RuleContext): RuleListener { function isFunctionOfUseEffectSetup(node: TSESTree.Node) { return node.parent?.type === T.CallExpression && node.parent.callee !== node - && ER.isUseEffectLikeCall(node.parent); + && isUseEffectLikeCall(node.parent); } function getCallName(node: TSESTree.Node) { @@ -93,8 +93,8 @@ export function create(context: RuleContext): RuleListener { function getCallKind(node: TSESTree.CallExpression) { return match(node) - .when(ER.isUseStateCall, () => "useState") - .when(ER.isUseEffectLikeCall, () => "useEffect") + .when(isUseStateCall, () => "useState") + .when(isUseEffectLikeCall, () => "useEffect") .when(isSetStateCall, () => "setState") .when(AST.isThenCall, () => "then") .otherwise(() => "other"); @@ -119,11 +119,11 @@ export function create(context: RuleContext): RuleListener { } function isIdFromUseStateCall(topLevelId: TSESTree.Identifier, at?: number) { - const variable = VAR.findVariable(topLevelId, context.sourceCode.getScope(topLevelId)); - const variableNode = VAR.getVariableDefinitionNode(variable, 0); + const variable = findVariable(topLevelId, context.sourceCode.getScope(topLevelId)); + const variableNode = getVariableDefinitionNode(variable, 0); if (variableNode == null) return false; if (variableNode.type !== T.CallExpression) return false; - if (!ER.isUseStateCall(variableNode)) return false; + if (!isUseStateCall(variableNode)) return false; const variableNodeParent = variableNode.parent; if (!("id" in variableNodeParent) || variableNodeParent.id?.type !== T.ArrayPattern) { return true; @@ -250,7 +250,7 @@ export function create(context: RuleContext): RuleListener { // const [state, setState] = useState(); // const set = useMemo(() => setState, []); // useEffect(set, []); - if (!ER.isUseMemoCall(parent)) { + if (!isUseMemoCall(parent)) { break; } const init = AST.findParentNode(parent, isVariableDeclaratorFromHookCall)?.init; @@ -266,7 +266,7 @@ export function create(context: RuleContext): RuleListener { // const [state, setState] = useState(); // const set = useCallback(setState, []); // useEffect(set, []); - if (ER.isUseCallbackCall(node.parent)) { + if (isUseCallbackCall(node.parent)) { const init = AST.findParentNode(node.parent, isVariableDeclaratorFromHookCall)?.init; if (init != null) { getOrElseUpdate(setStateInEffectArg, init, () => []).push(node); @@ -275,7 +275,7 @@ export function create(context: RuleContext): RuleListener { } // const [state, setState] = useState(); // useEffect(setState); - if (ER.isUseEffectLikeCall(node.parent)) { + if (isUseEffectLikeCall(node.parent)) { getOrElseUpdate(setStateInEffectSetup, node.parent, () => []).push(node); } } @@ -286,7 +286,7 @@ export function create(context: RuleContext): RuleListener { id: string | TSESTree.Identifier, initialScope: Scope.Scope, ): TSESTree.CallExpression[] | TSESTree.Identifier[] => { - const node = VAR.getVariableDefinitionNode(VAR.findVariable(id, initialScope), 0); + const node = getVariableDefinitionNode(findVariable(id, initialScope), 0); switch (node?.type) { case T.ArrowFunctionExpression: case T.FunctionDeclaration: diff --git a/packages/plugins/eslint-plugin-react-hooks-extra/src/utils/is-variable-declarator-from-hook-call.ts b/packages/plugins/eslint-plugin-react-hooks-extra/src/utils/is-variable-declarator-from-hook-call.ts index 12e3ecf5ee..c525f3f0c5 100644 --- a/packages/plugins/eslint-plugin-react-hooks-extra/src/utils/is-variable-declarator-from-hook-call.ts +++ b/packages/plugins/eslint-plugin-react-hooks-extra/src/utils/is-variable-declarator-from-hook-call.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isReactHookName } from "@eslint-react/core"; import type { TSESTree } from "@typescript-eslint/types"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; @@ -6,10 +6,10 @@ function isInitFromHookCall(init: TSESTree.Expression | null) { if (init?.type !== T.CallExpression) return false; switch (init.callee.type) { case T.Identifier: - return ER.isReactHookName(init.callee.name); + return isReactHookName(init.callee.name); case T.MemberExpression: return init.callee.property.type === T.Identifier - && ER.isReactHookName(init.callee.property.name); + && isReactHookName(init.callee.property.name); default: return false; } diff --git a/packages/plugins/eslint-plugin-react-naming-convention/src/rules/component-name.ts b/packages/plugins/eslint-plugin-react-naming-convention/src/rules/component-name.ts index 8a81095629..dd10025d82 100644 --- a/packages/plugins/eslint-plugin-react-naming-convention/src/rules/component-name.ts +++ b/packages/plugins/eslint-plugin-react-naming-convention/src/rules/component-name.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { useComponentCollector, useComponentCollectorLegacy } from "@eslint-react/core"; import type { unit } from "@eslint-react/eff"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import { RE_CONSTANT_CASE, RE_PASCAL_CASE, toRegExp } from "@eslint-react/kit"; @@ -82,8 +82,8 @@ export default createRule({ export function create(context: RuleContext): RuleListener { const options = normalizeOptions(context.options); const { rule } = options; - const collector = ER.useComponentCollector(context); - const collectorLegacy = ER.useComponentCollectorLegacy(); + const collector = useComponentCollector(context); + const collectorLegacy = useComponentCollectorLegacy(); return { ...collector.listeners, diff --git a/packages/plugins/eslint-plugin-react-naming-convention/src/rules/context-name.ts b/packages/plugins/eslint-plugin-react-naming-convention/src/rules/context-name.ts index 953f59517d..9247774c7d 100644 --- a/packages/plugins/eslint-plugin-react-naming-convention/src/rules/context-name.ts +++ b/packages/plugins/eslint-plugin-react-naming-convention/src/rules/context-name.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { getInstanceId, isComponentName, isCreateContextCall } from "@eslint-react/core"; import { identity } from "@eslint-react/eff"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; @@ -33,14 +33,14 @@ export function create(context: RuleContext): RuleListener { if (!context.sourceCode.text.includes("createContext")) return {}; return { CallExpression(node) { - if (!ER.isCreateContextCall(context, node)) return; - const id = ER.getInstanceId(node); + if (!isCreateContextCall(context, node)) return; + const id = getInstanceId(node); if (id == null) return; const name = match(id) .with({ type: T.Identifier, name: P.select() }, identity) .with({ type: T.MemberExpression, property: { name: P.select(P.string) } }, identity) .otherwise(() => null); - if (name != null && ER.isComponentName(name) && name.endsWith("Context")) return; + if (name != null && isComponentName(name) && name.endsWith("Context")) return; context.report({ messageId: "invalidContextName", node: id, diff --git a/packages/plugins/eslint-plugin-react-naming-convention/src/rules/use-state.ts b/packages/plugins/eslint-plugin-react-naming-convention/src/rules/use-state.ts index f3177920a0..e3b9449bca 100644 --- a/packages/plugins/eslint-plugin-react-naming-convention/src/rules/use-state.ts +++ b/packages/plugins/eslint-plugin-react-naming-convention/src/rules/use-state.ts @@ -1,11 +1,11 @@ -import * as ER from "@eslint-react/core"; +import { getInstanceId, isUseStateCall } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { TSESTree } from "@typescript-eslint/types"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import { snakeCase } from "string-ts"; - import { match } from "ts-pattern"; + import { createRule } from "../utils"; export const RULE_NAME = "use-state"; @@ -37,7 +37,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { return { CallExpression(node: TSESTree.CallExpression) { - if (!ER.isUseStateCall(node)) { + if (!isUseStateCall(node)) { return; } if (node.parent.type !== T.VariableDeclarator) { @@ -47,7 +47,7 @@ export function create(context: RuleContext): RuleListener { }); return; } - const id = ER.getInstanceId(node); + const id = getInstanceId(node); if (id?.type !== T.ArrayPattern) { context.report({ messageId: "invalidAssignment", diff --git a/packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-event-listener.ts b/packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-event-listener.ts index 885d8dd2ce..9377e9a2de 100644 --- a/packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-event-listener.ts +++ b/packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-event-listener.ts @@ -1,16 +1,21 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { + type ComponentPhaseKind, + ComponentPhaseRelevance, + getPhaseKindOfFunction, + isInversePhase, +} from "@eslint-react/core"; import { unit } from "@eslint-react/eff"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; -import * as VAR from "@eslint-react/var"; +import { findProperty, findVariable, getVariableDefinitionNode, isNodeValueEqual } from "@eslint-react/var"; import type { Scope } from "@typescript-eslint/scope-manager"; import type { TSESTree } from "@typescript-eslint/utils"; import { AST_NODE_TYPES as T } from "@typescript-eslint/utils"; -import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; -import type { EventListenerEntry } from "../types"; - import { getStaticValue } from "@typescript-eslint/utils/ast-utils"; +import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import { P, isMatching, match } from "ts-pattern"; + +import type { EventListenerEntry } from "../types"; import { createRule } from "../utils"; // #region Rule Metadata @@ -28,7 +33,7 @@ export type MessageID = // #region Types -type FunctionKind = ER.ComponentPhaseKind | "other"; +type FunctionKind = ComponentPhaseKind | "other"; type EventMethodKind = "addEventListener" | "removeEventListener"; type EffectMethodKind = "useEffect" | "useInsertionEffect" | "useLayoutEffect"; type LifecycleMethodKind = "componentDidMount" | "componentWillUnmount"; @@ -67,7 +72,7 @@ function getCallKind(node: TSESTree.CallExpression): CallKind { } function getFunctionKind(node: AST.TSESTreeFunction): FunctionKind { - return ER.getPhaseKindOfFunction(node) ?? "other"; + return getPhaseKindOfFunction(node) ?? "other"; } function getSignalValueExpression(node: TSESTree.Node | unit, initialScope: Scope): TSESTree.Node | unit { @@ -75,7 +80,7 @@ function getSignalValueExpression(node: TSESTree.Node | unit, initialScope: Scop switch (node.type) { case T.Identifier: { return getSignalValueExpression( - VAR.getVariableDefinitionNode(VAR.findVariable(node, initialScope), 0), + getVariableDefinitionNode(findVariable(node, initialScope), 0), initialScope, ); } @@ -88,7 +93,7 @@ function getSignalValueExpression(node: TSESTree.Node | unit, initialScope: Scop function getOptions(node: TSESTree.CallExpressionArgument, initialScope: Scope): typeof defaultOptions { function findProp(properties: TSESTree.ObjectExpression["properties"], propName: string) { - return VAR.findProperty(propName, properties, initialScope); + return findProperty(propName, properties, initialScope); } function getPropValue( prop: TSESTree.Property | TSESTree.RestElement | TSESTree.SpreadElement | unit, @@ -112,8 +117,8 @@ function getOptions(node: TSESTree.CallExpressionArgument, initialScope: Scope): function getOpts(node: TSESTree.Node): typeof defaultOptions { switch (node.type) { case T.Identifier: { - const variable = VAR.findVariable(node, initialScope); - const variableNode = VAR.getVariableDefinitionNode(variable, 0); + const variable = findVariable(node, initialScope); + const variableNode = getVariableDefinitionNode(variable, 0); if (variableNode?.type === T.ObjectExpression) { return getOpts(variableNode); } @@ -192,12 +197,12 @@ export function create(context: RuleContext): RuleListener { function isInverseEntry(aEntry: AEntry, rEntry: REntry) { const { type: aType, callee: aCallee, capture: aCapture, listener: aListener, phase: aPhase } = aEntry; const { type: rType, callee: rCallee, capture: rCapture, listener: rListener, phase: rPhase } = rEntry; - if (!ER.isInversePhase(aPhase, rPhase)) { + if (!isInversePhase(aPhase, rPhase)) { return false; } return isSameObject(aCallee, rCallee) && AST.isNodeEqual(aListener, rListener) - && VAR.isNodeValueEqual(aType, rType, [ + && isNodeValueEqual(aType, rType, [ context.sourceCode.getScope(aType), context.sourceCode.getScope(rType), ]) @@ -234,7 +239,7 @@ export function create(context: RuleContext): RuleListener { if (fKind == null) { return; } - if (!ER.ComponentPhaseRelevance.has(fKind)) { + if (!ComponentPhaseRelevance.has(fKind)) { return; } match(getCallKind(node)) diff --git a/packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-interval.ts b/packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-interval.ts index 7d9ad001d4..4b3b87c58f 100644 --- a/packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-interval.ts +++ b/packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-interval.ts @@ -1,13 +1,18 @@ import type * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { + type ComponentPhaseKind, + ComponentPhaseRelevance, + getPhaseKindOfFunction, + isInstanceIdEqual, +} from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; -import * as VAR from "@eslint-react/var"; +import { findAssignmentTarget } from "@eslint-react/var"; import type { TSESTree } from "@typescript-eslint/utils"; import { AST_NODE_TYPES as T } from "@typescript-eslint/utils"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; -import type { TimerEntry } from "../types"; - import { P, isMatching } from "ts-pattern"; + +import type { TimerEntry } from "../types"; import { createRule } from "../utils"; // #region Rule Metadata @@ -25,7 +30,7 @@ export type MessageID = // #region Types -type FunctionKind = ER.ComponentPhaseKind | "other"; +type FunctionKind = ComponentPhaseKind | "other"; type EventMethodKind = "setInterval" | "clearInterval"; type EffectMethodKind = "useEffect" | "useInsertionEffect" | "useLayoutEffect"; type LifecycleMethodKind = "componentDidMount" | "componentWillUnmount"; @@ -82,11 +87,11 @@ export function create(context: RuleContext): RuleListener { const sEntries: TimerEntry[] = []; const cEntries: TimerEntry[] = []; function isInverseEntry(a: TimerEntry, b: TimerEntry) { - return ER.isInstanceIdEqual(context, a.timerId, b.timerId); + return isInstanceIdEqual(context, a.timerId, b.timerId); } return { [":function"](node: AST.TSESTreeFunction) { - const kind = ER.getPhaseKindOfFunction(node) ?? "other"; + const kind = getPhaseKindOfFunction(node) ?? "other"; fEntries.push({ kind, node }); }, [":function:exit"]() { @@ -99,10 +104,10 @@ export function create(context: RuleContext): RuleListener { if (fEntry == null) { break; } - if (!ER.ComponentPhaseRelevance.has(fEntry.kind)) { + if (!ComponentPhaseRelevance.has(fEntry.kind)) { break; } - const intervalIdNode = VAR.findAssignmentTarget(node); + const intervalIdNode = findAssignmentTarget(node); if (intervalIdNode == null) { context.report({ messageId: "expectedIntervalId", @@ -124,7 +129,7 @@ export function create(context: RuleContext): RuleListener { if (fEntry == null) { break; } - if (!ER.ComponentPhaseRelevance.has(fEntry.kind)) { + if (!ComponentPhaseRelevance.has(fEntry.kind)) { break; } const [intervalIdNode] = node.arguments; diff --git a/packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-resize-observer.ts b/packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-resize-observer.ts index e0e8faa454..bcbacbc816 100644 --- a/packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-resize-observer.ts +++ b/packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-resize-observer.ts @@ -1,15 +1,21 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { + type ComponentPhaseKind, + ComponentPhaseRelevance, + getInstanceId, + getPhaseKindOfFunction, + isInstanceIdEqual, +} from "@eslint-react/core"; import type { unit } from "@eslint-react/eff"; import { or } from "@eslint-react/eff"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; -import * as VAR from "@eslint-react/var"; +import { findVariable, getVariableDefinitionNode } from "@eslint-react/var"; import type { TSESTree } from "@typescript-eslint/utils"; import { AST_NODE_TYPES as T } from "@typescript-eslint/utils"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; -import type { ObserverEntry, ObserverMethod } from "../types"; - import { P, isMatching, match } from "ts-pattern"; + +import type { ObserverEntry, ObserverMethod } from "../types"; import { createRule, isConditional } from "../utils"; // #region Rule Metadata @@ -27,7 +33,7 @@ export type MessageID = // #region Types -type FunctionKind = ER.ComponentPhaseKind | "other"; +type FunctionKind = ComponentPhaseKind | "other"; type EffectMethodKind = "useEffect" | "useInsertionEffect" | "useLayoutEffect"; type CallKind = ObserverMethod | EffectMethodKind | "other"; @@ -49,7 +55,7 @@ function isFromObserver(context: RuleContext, node: TSESTree.Expression): boolea switch (true) { case node.type === T.Identifier: { const initialScope = context.sourceCode.getScope(node); - const object = VAR.getVariableDefinitionNode(VAR.findVariable(node, initialScope), 0); + const object = getVariableDefinitionNode(findVariable(node, initialScope), 0); return isNewResizeObserver(object); } case node.type === T.MemberExpression: @@ -76,7 +82,7 @@ function getCallKind(context: RuleContext, node: TSESTree.CallExpression): CallK } function getFunctionKind(node: AST.TSESTreeFunction): FunctionKind { - return ER.getPhaseKindOfFunction(node) ?? "other"; + return getPhaseKindOfFunction(node) ?? "other"; } // #endregion @@ -113,7 +119,7 @@ export function create(context: RuleContext): RuleListener { const observers: { id: TSESTree.Node; node: TSESTree.NewExpression; - phase: ER.ComponentPhaseKind; + phase: ComponentPhaseKind; phaseNode: AST.TSESTreeFunction; }[] = []; const oEntries: OEntry[] = []; @@ -132,7 +138,7 @@ export function create(context: RuleContext): RuleListener { return; } const fKind = fEntries.findLast((x) => x.kind !== "other")?.kind; - if (fKind == null || !ER.ComponentPhaseRelevance.has(fKind)) { + if (fKind == null || !ComponentPhaseRelevance.has(fKind)) { return; } const { object } = node.callee; @@ -182,13 +188,13 @@ export function create(context: RuleContext): RuleListener { ["NewExpression"](node) { const fEntry = fEntries.findLast((x) => x.kind !== "other"); if (fEntry == null) return; - if (!ER.ComponentPhaseRelevance.has(fEntry.kind)) { + if (!ComponentPhaseRelevance.has(fEntry.kind)) { return; } if (!isNewResizeObserver(node)) { return; } - const id = ER.getInstanceId(node); + const id = getInstanceId(node); if (id == null) { context.report({ messageId: "unexpectedFloatingInstance", @@ -205,11 +211,11 @@ export function create(context: RuleContext): RuleListener { }, ["Program:exit"]() { for (const { id, node, phaseNode } of observers) { - if (dEntries.some((e) => ER.isInstanceIdEqual(context, e.observer, id))) { + if (dEntries.some((e) => isInstanceIdEqual(context, e.observer, id))) { continue; } - const oentries = oEntries.filter((e) => ER.isInstanceIdEqual(context, e.observer, id)); - const uentries = uEntries.filter((e) => ER.isInstanceIdEqual(context, e.observer, id)); + const oentries = oEntries.filter((e) => isInstanceIdEqual(context, e.observer, id)); + const uentries = uEntries.filter((e) => isInstanceIdEqual(context, e.observer, id)); const isDynamic = (node: TSESTree.Node | unit) => node?.type === T.CallExpression || isConditional(node); const isPhaseNode = (node: TSESTree.Node | unit) => node === phaseNode; const hasDynamicallyAdded = oentries @@ -219,7 +225,7 @@ export function create(context: RuleContext): RuleListener { continue; } for (const oEntry of oentries) { - if (uentries.some((uEntry) => ER.isInstanceIdEqual(context, uEntry.element, oEntry.element))) { + if (uentries.some((uEntry) => isInstanceIdEqual(context, uEntry.element, oEntry.element))) { continue; } context.report({ messageId: "expectedDisconnectOrUnobserveInCleanup", node: oEntry.node }); diff --git a/packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-timeout.ts b/packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-timeout.ts index 721a16092d..1065f2a85f 100644 --- a/packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-timeout.ts +++ b/packages/plugins/eslint-plugin-react-web-api/src/rules/no-leaked-timeout.ts @@ -1,7 +1,12 @@ import type * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { + type ComponentPhaseKind, + ComponentPhaseRelevance, + getPhaseKindOfFunction, + isInstanceIdEqual, +} from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; -import * as VAR from "@eslint-react/var"; +import { findAssignmentTarget } from "@eslint-react/var"; import type { TSESTree } from "@typescript-eslint/utils"; import { AST_NODE_TYPES as T } from "@typescript-eslint/utils"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; @@ -25,7 +30,7 @@ export type MessageID = // #region Types -type FunctionKind = ER.ComponentPhaseKind | "other"; +type FunctionKind = ComponentPhaseKind | "other"; type EventMethodKind = "setTimeout" | "clearTimeout"; type EffectMethodKind = "useEffect" | "useInsertionEffect" | "useLayoutEffect"; type LifecycleMethodKind = "componentDidMount" | "componentWillUnmount"; @@ -82,11 +87,11 @@ export function create(context: RuleContext): RuleListener { const sEntries: TimerEntry[] = []; const rEntries: TimerEntry[] = []; function isInverseEntry(a: TimerEntry, b: TimerEntry) { - return ER.isInstanceIdEqual(context, a.timerId, b.timerId); + return isInstanceIdEqual(context, a.timerId, b.timerId); } return { [":function"](node: AST.TSESTreeFunction) { - const kind = ER.getPhaseKindOfFunction(node) ?? "other"; + const kind = getPhaseKindOfFunction(node) ?? "other"; fEntries.push({ kind, node }); }, [":function:exit"]() { @@ -94,12 +99,12 @@ export function create(context: RuleContext): RuleListener { }, ["CallExpression"](node) { const fEntry = fEntries.findLast((f) => f.kind !== "other"); - if (!ER.ComponentPhaseRelevance.has(fEntry?.kind)) { + if (!ComponentPhaseRelevance.has(fEntry?.kind)) { return; } switch (getCallKind(node)) { case "setTimeout": { - const timeoutIdNode = VAR.findAssignmentTarget(node); + const timeoutIdNode = findAssignmentTarget(node); if (timeoutIdNode == null) { context.report({ messageId: "expectedTimeoutId", diff --git a/packages/plugins/eslint-plugin-react-web-api/src/types/EventListener/EventListenerEntry.ts b/packages/plugins/eslint-plugin-react-web-api/src/types/EventListener/EventListenerEntry.ts index f33d965f9f..de642637d3 100644 --- a/packages/plugins/eslint-plugin-react-web-api/src/types/EventListener/EventListenerEntry.ts +++ b/packages/plugins/eslint-plugin-react-web-api/src/types/EventListener/EventListenerEntry.ts @@ -1,4 +1,4 @@ -import type * as ER from "@eslint-react/core"; +import type { SemanticEntry } from "@eslint-react/core"; import type { unit } from "@eslint-react/eff"; import type { TSESTree } from "@typescript-eslint/types"; @@ -11,7 +11,7 @@ export type EventListenerEntry = capture: boolean | unit; listener: TSESTree.Node; signal: TSESTree.Node | unit; - } & ER.SemanticEntry + } & SemanticEntry | { kind: "removeEventListener"; type: TSESTree.Node; @@ -19,4 +19,4 @@ export type EventListenerEntry = callee: TSESTree.Node; capture: boolean | unit; listener: TSESTree.Node; - } & ER.SemanticEntry; + } & SemanticEntry; diff --git a/packages/plugins/eslint-plugin-react-web-api/src/types/Observer/ObserverEntry.ts b/packages/plugins/eslint-plugin-react-web-api/src/types/Observer/ObserverEntry.ts index 54c87e4af0..610af1c8ba 100644 --- a/packages/plugins/eslint-plugin-react-web-api/src/types/Observer/ObserverEntry.ts +++ b/packages/plugins/eslint-plugin-react-web-api/src/types/Observer/ObserverEntry.ts @@ -1,5 +1,5 @@ /* eslint-disable perfectionist/sort-object-types */ -import type * as ER from "@eslint-react/core"; +import type { SemanticEntry } from "@eslint-react/core"; import type { TSESTree } from "@typescript-eslint/types"; import type { ObserverKind } from "./ObserverKind"; @@ -11,7 +11,7 @@ export type ObserverEntry = callee: TSESTree.Node; observer: TSESTree.Node; observerKind: ObserverKind; - } & ER.SemanticEntry + } & SemanticEntry | { kind: "observe"; node: TSESTree.CallExpression; @@ -19,7 +19,7 @@ export type ObserverEntry = callee: TSESTree.Node; observer: TSESTree.Node; observerKind: ObserverKind; - } & ER.SemanticEntry + } & SemanticEntry | { kind: "unobserve"; node: TSESTree.CallExpression; @@ -27,4 +27,4 @@ export type ObserverEntry = callee: TSESTree.Node; observer: TSESTree.Node; observerKind: ObserverKind; - } & ER.SemanticEntry; + } & SemanticEntry; diff --git a/packages/plugins/eslint-plugin-react-web-api/src/types/Timer/TimerEntry.ts b/packages/plugins/eslint-plugin-react-web-api/src/types/Timer/TimerEntry.ts index 0ba1c959f6..6c9167bf02 100644 --- a/packages/plugins/eslint-plugin-react-web-api/src/types/Timer/TimerEntry.ts +++ b/packages/plugins/eslint-plugin-react-web-api/src/types/Timer/TimerEntry.ts @@ -1,9 +1,9 @@ -import type * as ER from "@eslint-react/core"; +import type { SemanticEntry } from "@eslint-react/core"; import type { TSESTree } from "@typescript-eslint/types"; import type { TimerKind } from "./TimerKind"; -export interface TimerEntry extends ER.SemanticEntry { +export interface TimerEntry extends SemanticEntry { kind: TimerKind; node: TSESTree.CallExpression; callee: TSESTree.Node; diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/jsx-no-undef.ts b/packages/plugins/eslint-plugin-react-x/src/rules/jsx-no-undef.ts index 211edeab91..e876475b66 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/jsx-no-undef.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/jsx-no-undef.ts @@ -1,10 +1,10 @@ import type { RuleContext, RuleFeature } from "@eslint-react/kit"; +import { findVariable } from "@eslint-react/var"; +import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; - -import * as VAR from "@eslint-react/var"; -import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import { match } from "ts-pattern"; + import { createRule } from "../utils"; export const RULE_NAME = "jsx-no-undef"; @@ -41,7 +41,7 @@ export function create(context: RuleContext): RuleListener { if (name === "this") return; // Skip JsxIntrinsicElements if (/^[a-z]/u.test(name)) return; - if (VAR.findVariable(name, context.sourceCode.getScope(node)) == null) { + if (findVariable(name, context.sourceCode.getScope(node)) == null) { context.report({ messageId: "jsxNoUndef", node, diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/jsx-shorthand-boolean.ts b/packages/plugins/eslint-plugin-react-x/src/rules/jsx-shorthand-boolean.ts index 7689a8f5bb..cd1300d78d 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/jsx-shorthand-boolean.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/jsx-shorthand-boolean.ts @@ -1,13 +1,12 @@ +import { getAttributeName } from "@eslint-react/core"; import type { unit } from "@eslint-react/eff"; import type { RuleContext, RuleFeature, RulePolicy } from "@eslint-react/kit"; import type { TSESTree } from "@typescript-eslint/types"; +import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { JSONSchema4 } from "@typescript-eslint/utils/json-schema"; - import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; - -import * as ER from "@eslint-react/core"; -import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { CamelCase } from "string-ts"; + import { createRule } from "../utils"; export const RULE_NAME = "jsx-shorthand-boolean"; @@ -56,7 +55,7 @@ export function create(context: RuleContext): RuleListener { return { JSXAttribute(node: TSESTree.JSXAttribute) { const { value } = node; - const propName = ER.getAttributeName(context, node); + const propName = getAttributeName(context, node); switch (true) { case policy === 1 diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/jsx-shorthand-fragment.ts b/packages/plugins/eslint-plugin-react-x/src/rules/jsx-shorthand-fragment.ts index 56f9d4cfcb..0870e51f9f 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/jsx-shorthand-fragment.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/jsx-shorthand-fragment.ts @@ -1,12 +1,12 @@ +import { getJsxConfigFromAnnotation, getJsxConfigFromContext, isFragmentElement } from "@eslint-react/core"; import type { unit } from "@eslint-react/eff"; +import { type RuleContext, type RuleFeature, type RulePolicy } from "@eslint-react/kit"; import type { TSESTree } from "@typescript-eslint/types"; import type { JSONSchema4 } from "@typescript-eslint/utils/json-schema"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; - -import * as ER from "@eslint-react/core"; -import { type RuleContext, type RuleFeature, type RulePolicy } from "@eslint-react/kit"; import { match } from "ts-pattern"; + import { createRule } from "../utils"; export const RULE_NAME = "jsx-shorthand-fragment"; @@ -53,8 +53,8 @@ export default createRule({ export function create(context: RuleContext): RuleListener { const policy = context.options[0] ?? defaultOptions[0]; const jsxConfig = { - ...ER.getJsxConfigFromContext(context), - ...ER.getJsxConfigFromAnnotation(context), + ...getJsxConfigFromContext(context), + ...getJsxConfigFromAnnotation(context), }; const { jsxFragmentFactory } = jsxConfig; @@ -62,7 +62,7 @@ export function create(context: RuleContext): RuleListener { return match(policy) .with(1, () => ({ JSXElement(node: TSESTree.JSXElement) { - if (!ER.isFragmentElement(context, node)) return; + if (!isFragmentElement(context, node)) return; const hasAttributes = node.openingElement.attributes.length > 0; if (hasAttributes) return; context.report({ @@ -92,12 +92,18 @@ export function create(context: RuleContext): RuleListener { const { closingFragment, openingFragment } = node; return [ fixer.replaceTextRange( - [openingFragment.range[0], openingFragment.range[1]], - "<" + jsxFragmentFactory + ">", + [ + openingFragment.range[0], + openingFragment.range[1], + ], + `<${jsxFragmentFactory}>`, ), fixer.replaceTextRange( - [closingFragment.range[0], closingFragment.range[1]], - "", + [ + closingFragment.range[0], + closingFragment.range[1], + ], + ``, ), ]; }, diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/jsx-uses-react.ts b/packages/plugins/eslint-plugin-react-x/src/rules/jsx-uses-react.ts index 6ddc01e830..5ec75e3342 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/jsx-uses-react.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/jsx-uses-react.ts @@ -1,11 +1,10 @@ -import * as ER from "@eslint-react/core"; +import { JsxEmit, getJsxConfigFromAnnotation, getJsxConfigFromContext } from "@eslint-react/core"; import { type RuleContext, type RuleFeature } from "@eslint-react/kit"; import type { TSESTree } from "@typescript-eslint/types"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; -import { createRule } from "../utils"; -const JsxEmit = ER.JsxEmit; +import { createRule } from "../utils"; export const RULE_NAME = "jsx-uses-react"; @@ -32,8 +31,8 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { const jsxConfig = { - ...ER.getJsxConfigFromContext(context), - ...ER.getJsxConfigFromAnnotation(context), + ...getJsxConfigFromContext(context), + ...getJsxConfigFromAnnotation(context), }; const { jsx, jsxFactory, jsxFragmentFactory } = jsxConfig; diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-access-state-in-setstate.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-access-state-in-setstate.ts index 2072ba63a6..d7822407fd 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-access-state-in-setstate.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-access-state-in-setstate.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isClassComponent, isThisSetState } from "@eslint-react/core"; import { constFalse, constTrue } from "@eslint-react/eff"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; @@ -66,25 +66,25 @@ export function create(context: RuleContext): RuleListener { ][] = []; return { CallExpression(node) { - if (!ER.isThisSetState(node)) { + if (!isThisSetState(node)) { return; } setStateEntries.push([node, false]); }, "CallExpression:exit"(node) { - if (!ER.isThisSetState(node)) { + if (!isThisSetState(node)) { return; } setStateEntries.pop(); }, ClassDeclaration(node) { - classEntries.push([node, ER.isClassComponent(node)]); + classEntries.push([node, isClassComponent(node)]); }, "ClassDeclaration:exit"() { classEntries.pop(); }, ClassExpression(node) { - classEntries.push([node, ER.isClassComponent(node)]); + classEntries.push([node, isClassComponent(node)]); }, "ClassExpression:exit"() { classEntries.pop(); diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-array-index-key.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-array-index-key.ts index 91c513c0ee..3b097bc891 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-array-index-key.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-array-index-key.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isCloneElementCall, isCreateElementCall, isInitializedFromReact } from "@eslint-react/core"; import { unit } from "@eslint-react/eff"; import { type RuleContext, type RuleFeature, report } from "@eslint-react/kit"; import { coerceSettings } from "@eslint-react/shared"; @@ -37,7 +37,7 @@ function isUsingReactChildren(context: RuleContext, node: TSESTree.CallExpressio return true; } if (callee.object.type === T.MemberExpression && "name" in callee.object.object) { - return ER.isInitializedFromReact(callee.object.object.name, importSource, initialScope); + return isInitializedFromReact(callee.object.object.name, importSource, initialScope); } return false; } @@ -117,7 +117,7 @@ export function create(context: RuleContext): RuleListener { } function isCreateOrCloneElementCall(node: TSESTree.Node): node is TSESTree.CallExpression { - return ER.isCreateElementCall(context, node) || ER.isCloneElementCall(context, node); + return isCreateElementCall(context, node) || isCloneElementCall(context, node); } function getReportDescriptors(node: TSESTree.Node): ReportDescriptor[] { diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-children-count.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-children-count.ts index 6888e4f4af..333da36c69 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-children-count.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-children-count.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isChildrenCount } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -31,7 +31,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { return { MemberExpression(node) { - if (ER.isChildrenCount(context, node)) { + if (isChildrenCount(context, node)) { context.report({ messageId: "noChildrenCount", node: node.property, diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-children-for-each.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-children-for-each.ts index ce5ae4e9fa..14fecdc6d6 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-children-for-each.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-children-for-each.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isChildrenForEach } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -31,7 +31,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { return { MemberExpression(node) { - if (ER.isChildrenForEach(context, node)) { + if (isChildrenForEach(context, node)) { context.report({ messageId: "noChildrenForEach", node: node.property, diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-children-map.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-children-map.ts index f00af93a12..22937ba82f 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-children-map.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-children-map.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isChildrenMap } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -31,7 +31,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { return { MemberExpression(node) { - if (ER.isChildrenMap(context, node)) { + if (isChildrenMap(context, node)) { context.report({ messageId: "noChildrenMap", node: node.property, diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-children-only.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-children-only.ts index 2ed021568e..8edb83a804 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-children-only.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-children-only.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isChildrenOnly } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -31,7 +31,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { return { MemberExpression(node) { - if (ER.isChildrenOnly(context, node)) { + if (isChildrenOnly(context, node)) { context.report({ messageId: "noChildrenOnly", node: node.property, diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-children-prop.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-children-prop.ts index 4f76746580..3bea6e5bbb 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-children-prop.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-children-prop.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { getAttribute } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -31,12 +31,12 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { return { JSXElement(node) { - const getAttribute = ER.getAttribute( + const getAttributeEx = getAttribute( context, node.openingElement.attributes, context.sourceCode.getScope(node), ); - const childrenProp = getAttribute("children"); + const childrenProp = getAttributeEx("children"); if (childrenProp != null) { context.report({ messageId: "noChildrenProp", diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-children-to-array.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-children-to-array.ts index 2d28871586..4114fd8435 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-children-to-array.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-children-to-array.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isChildrenToArray } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -31,7 +31,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { return { MemberExpression(node) { - if (ER.isChildrenToArray(context, node)) { + if (isChildrenToArray(context, node)) { context.report({ messageId: "noChildrenToArray", node: node.property, diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-class-component.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-class-component.ts index a8ea651354..bf8fca0c56 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-class-component.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-class-component.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isComponentDidCatch, isGetDerivedStateFromError, useComponentCollectorLegacy } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -30,13 +30,13 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { if (!context.sourceCode.text.includes("Component")) return {}; - const { ctx, listeners } = ER.useComponentCollectorLegacy(); + const { ctx, listeners } = useComponentCollectorLegacy(); return { ...listeners, "Program:exit"(program) { const components = ctx.getAllComponents(program); for (const { name = "anonymous", node: component } of components.values()) { - if (component.body.body.some((m) => ER.isComponentDidCatch(m) || ER.isGetDerivedStateFromError(m))) { + if (component.body.body.some((m) => isComponentDidCatch(m) || isGetDerivedStateFromError(m))) { continue; } context.report({ diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-clone-element.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-clone-element.ts index eec6e10b99..ef38bc5eaa 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-clone-element.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-clone-element.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isCloneElementCall } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -31,7 +31,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { return { CallExpression(node) { - if (ER.isCloneElementCall(context, node)) { + if (isCloneElementCall(context, node)) { context.report({ messageId: "noCloneElement", node, diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-component-will-mount.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-component-will-mount.ts index 586fd85c67..d5302c412d 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-component-will-mount.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-component-will-mount.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isComponentWillMount, useComponentCollectorLegacy } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -33,7 +33,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { if (!context.sourceCode.text.includes("componentWillMount")) return {}; - const { ctx, listeners } = ER.useComponentCollectorLegacy(); + const { ctx, listeners } = useComponentCollectorLegacy(); return { ...listeners, @@ -42,7 +42,7 @@ export function create(context: RuleContext): RuleListener { for (const { node: component } of components.values()) { const { body } = component.body; for (const member of body) { - if (ER.isComponentWillMount(member)) { + if (isComponentWillMount(member)) { context.report({ messageId: "noComponentWillMount", node: member, diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-component-will-receive-props.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-component-will-receive-props.ts index 7e447f060c..92e2c36d90 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-component-will-receive-props.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-component-will-receive-props.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isComponentWillReceiveProps, useComponentCollectorLegacy } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -33,7 +33,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { if (!context.sourceCode.text.includes("componentWillReceiveProps")) return {}; - const { ctx, listeners } = ER.useComponentCollectorLegacy(); + const { ctx, listeners } = useComponentCollectorLegacy(); return { ...listeners, "Program:exit"(program) { @@ -41,7 +41,7 @@ export function create(context: RuleContext): RuleListener { for (const { node: component } of components.values()) { const { body } = component.body; for (const member of body) { - if (ER.isComponentWillReceiveProps(member)) { + if (isComponentWillReceiveProps(member)) { context.report({ messageId: "noComponentWillReceiveProps", node: member, diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-component-will-update.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-component-will-update.ts index ff61f676a3..12c8b0a38f 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-component-will-update.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-component-will-update.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isComponentWillUpdate, useComponentCollectorLegacy } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -33,7 +33,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { if (!context.sourceCode.text.includes("componentWillUpdate")) return {}; - const { ctx, listeners } = ER.useComponentCollectorLegacy(); + const { ctx, listeners } = useComponentCollectorLegacy(); return { ...listeners, @@ -42,7 +42,7 @@ export function create(context: RuleContext): RuleListener { for (const { node: component } of components.values()) { const { body } = component.body; for (const member of body) { - if (ER.isComponentWillUpdate(member)) { + if (isComponentWillUpdate(member)) { context.report({ messageId: "noComponentWillUpdate", node: member, diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-context-provider.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-context-provider.ts index d7af1ed723..35da096c54 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-context-provider.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-context-provider.ts @@ -1,10 +1,9 @@ -import * as ER from "@eslint-react/core"; +import { getElementType, isComponentNameLoose } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; -import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; -import type { CamelCase } from "string-ts"; - import { getSettingsFromContext } from "@eslint-react/shared"; +import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import { compare } from "compare-versions"; +import type { CamelCase } from "string-ts"; import { createRule } from "../utils"; @@ -40,7 +39,7 @@ export function create(context: RuleContext): RuleListener { if (compare(version, "19.0.0", "<")) return {}; return { JSXElement(node) { - const fullName = ER.getElementType(context, node); + const fullName = getElementType(context, node); const parts = fullName.split("."); const selfName = parts.pop(); const contextFullName = parts.join("."); @@ -51,7 +50,7 @@ export function create(context: RuleContext): RuleListener { messageId: "noContextProvider", node, fix(fixer) { - if (!ER.isComponentNameLoose(contextSelfName)) return null; + if (!isComponentNameLoose(contextSelfName)) return null; const openingElement = node.openingElement; const closingElement = node.closingElement; if (closingElement == null) { diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-create-ref.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-create-ref.ts index b66290210b..ae5d60dee9 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-create-ref.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-create-ref.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isClassComponent, isCreateRefCall } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -32,7 +32,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { return { CallExpression(node) { - if (ER.isCreateRefCall(context, node) && AST.findParentNode(node, ER.isClassComponent) == null) { + if (isCreateRefCall(context, node) && AST.findParentNode(node, isClassComponent) == null) { context.report({ messageId: "noCreateRef", node }); } }, diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-default-props.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-default-props.ts index 4c58cbb57c..260370798c 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-default-props.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-default-props.ts @@ -1,7 +1,7 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isComponentNameLoose } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; -import * as VAR from "@eslint-react/var"; +import { findVariable, getVariableDefinitionNode } from "@eslint-react/var"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -45,11 +45,11 @@ export function create(context: RuleContext): RuleListener { if (property.type !== T.Identifier || property.name !== "defaultProps") { return; } - if (!ER.isComponentNameLoose(object.name)) { + if (!isComponentNameLoose(object.name)) { return; } - const variable = VAR.findVariable(object.name, context.sourceCode.getScope(node)); - const variableNode = VAR.getVariableDefinitionNode(variable, 0); + const variable = findVariable(object.name, context.sourceCode.getScope(node)); + const variableNode = getVariableDefinitionNode(variable, 0); if (variableNode == null) return; if (!AST.isFunction(variableNode)) return; context.report({ messageId: "noDefaultProps", node: property }); diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-direct-mutation-state.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-direct-mutation-state.ts index 7a7df3f859..2df546d7b4 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-direct-mutation-state.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-direct-mutation-state.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isAssignmentToThisState, isClassComponent } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { TSESTree } from "@typescript-eslint/utils"; @@ -43,7 +43,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { return { AssignmentExpression(node: TSESTree.AssignmentExpression) { - if (!ER.isAssignmentToThisState(node)) return; + if (!isAssignmentToThisState(node)) return; const parentClass = AST.findParentNode( node, AST.isOneOf([ @@ -53,7 +53,7 @@ export function create(context: RuleContext): RuleListener { ); if (parentClass == null) return; if ( - ER.isClassComponent(parentClass) + isClassComponent(parentClass) && context.sourceCode.getScope(node).block !== AST.findParentNode(node, isConstructorFunction) ) { context.report({ diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-forward-ref.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-forward-ref.ts index 35674f63a1..e66ff14144 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-forward-ref.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-forward-ref.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isForwardRefCall, isInitializedFromReact } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import { getSettingsFromContext } from "@eslint-react/shared"; import type { TSESTree } from "@typescript-eslint/types"; @@ -47,7 +47,7 @@ export function create(context: RuleContext): RuleListener { } return { CallExpression(node) { - if (!ER.isForwardRefCall(context, node)) { + if (!isForwardRefCall(context, node)) { return; } const id = AST.getFunctionId(node); @@ -74,10 +74,10 @@ function canFix(context: RuleContext, node: TSESTree.CallExpression) { const initialScope = context.sourceCode.getScope(node); switch (node.callee.type) { case T.Identifier: - return ER.isInitializedFromReact(node.callee.name, importSource, initialScope); + return isInitializedFromReact(node.callee.name, importSource, initialScope); case T.MemberExpression: return node.callee.object.type === T.Identifier - && ER.isInitializedFromReact(node.callee.object.name, importSource, initialScope); + && isInitializedFromReact(node.callee.object.name, importSource, initialScope); default: return false; } diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-implicit-key.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-implicit-key.ts index e2d088ffd3..05e1e4e5b5 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-implicit-key.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-implicit-key.ts @@ -1,12 +1,10 @@ +import { getAttribute } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { TSESTree } from "@typescript-eslint/types"; +import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; -import * as ER from "@eslint-react/core"; - -import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; - import { createRule } from "../utils"; export const RULE_NAME = "no-implicit-key"; @@ -39,7 +37,7 @@ export function create(context: RuleContext): RuleListener { return { JSXOpeningElement(node: TSESTree.JSXOpeningElement) { const initialScope = context.sourceCode.getScope(node); - const keyProp = ER.getAttribute(context, node.attributes, initialScope)("key"); + const keyProp = getAttribute(context, node.attributes, initialScope)("key"); const isKeyPropOnElement = node.attributes .some((n) => n.type === T.JSXAttribute diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-leaked-conditional-rendering.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-leaked-conditional-rendering.ts index d72c442e8d..fc4c4d5d58 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-leaked-conditional-rendering.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-leaked-conditional-rendering.ts @@ -2,7 +2,7 @@ import * as AST from "@eslint-react/ast"; import { flow, unit } from "@eslint-react/eff"; import { type RuleContext, type RuleFeature, report } from "@eslint-react/kit"; import { getSettingsFromContext } from "@eslint-react/shared"; -import * as VAR from "@eslint-react/var"; +import { findVariable } from "@eslint-react/var"; import { getConstrainedTypeAtLocation } from "@typescript-eslint/type-utils"; import type { TSESTree } from "@typescript-eslint/types"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; @@ -108,7 +108,7 @@ export function create(context: RuleContext): RuleListener { return getReportDescriptor(consequent) ?? getReportDescriptor(alternate); }) .with({ type: T.Identifier }, (n) => { - const variable = VAR.findVariable(n.name, context.sourceCode.getScope(n)); + const variable = findVariable(n.name, context.sourceCode.getScope(n)); const variableDefNode = variable?.defs.at(0)?.node; return match(variableDefNode) .with({ init: P.select({ type: P.not(T.VariableDeclaration) }) }, getReportDescriptor) diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-missing-component-display-name.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-missing-component-display-name.ts index 9562638a48..616e99f360 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-missing-component-display-name.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-missing-component-display-name.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { ComponentFlag, DEFAULT_COMPONENT_DETECTION_HINT, useComponentCollector } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -34,12 +34,12 @@ export function create(context: RuleContext): RuleListener { const { ctx, listeners, - } = ER.useComponentCollector( + } = useComponentCollector( context, { collectDisplayName: true, collectHookCalls: false, - hint: ER.DEFAULT_COMPONENT_DETECTION_HINT, + hint: DEFAULT_COMPONENT_DETECTION_HINT, }, ); return { @@ -47,7 +47,7 @@ export function create(context: RuleContext): RuleListener { "Program:exit"(program) { const components = ctx.getAllComponents(program); for (const { node, displayName, flag } of components.values()) { - const isMemoOrForwardRef = (flag & (ER.ComponentFlag.ForwardRef | ER.ComponentFlag.Memo)) > 0n; + const isMemoOrForwardRef = (flag & (ComponentFlag.ForwardRef | ComponentFlag.Memo)) > 0n; if (AST.getFunctionId(node) != null) { continue; } diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-missing-context-display-name.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-missing-context-display-name.ts index f9a498a11c..3c28953dc3 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-missing-context-display-name.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-missing-context-display-name.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { getInstanceId, isCreateContextCall, isInstanceIdEqual } from "@eslint-react/core"; import { type RuleContext, type RuleFeature } from "@eslint-react/kit"; import type { TSESTree } from "@typescript-eslint/types"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; @@ -45,12 +45,12 @@ export function create(context: RuleContext): RuleListener { displayNameAssignments.push(node); }, CallExpression(node) { - if (!ER.isCreateContextCall(context, node)) return; + if (!isCreateContextCall(context, node)) return; createCalls.push(node); }, "Program:exit"() { for (const call of createCalls) { - const id = ER.getInstanceId(call); + const id = getInstanceId(call); if (id == null) { context.report({ messageId: "noMissingContextDisplayName", @@ -63,7 +63,7 @@ export function create(context: RuleContext): RuleListener { const left = node.left; if (left.type !== T.MemberExpression) return false; const object = left.object; - return ER.isInstanceIdEqual(context, id, object); + return isInstanceIdEqual(context, id, object); }); if (!hasDisplayNameAssignment) { context.report({ diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-missing-key.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-missing-key.ts index 1db62a574c..4a64847b49 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-missing-key.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-missing-key.ts @@ -1,12 +1,11 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; -import type { TSESTree } from "@typescript-eslint/types"; -import type { ReportDescriptor, RuleListener } from "@typescript-eslint/utils/ts-eslint"; - +import { hasAttribute, isChildrenToArrayCall } from "@eslint-react/core"; import { type RuleContext, type RuleFeature, report } from "@eslint-react/kit"; - +import type { TSESTree } from "@typescript-eslint/types"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; +import type { ReportDescriptor, RuleListener } from "@typescript-eslint/utils/ts-eslint"; import { match } from "ts-pattern"; + import { createRule } from "../utils"; export const RULE_NAME = "no-missing-key"; @@ -42,7 +41,7 @@ export function create(context: RuleContext): RuleListener { switch (node.type) { case T.JSXElement: { const initialScope = context.sourceCode.getScope(node); - if (!ER.hasAttribute(context, "key", node.openingElement.attributes, initialScope)) { + if (!hasAttribute(context, "key", node.openingElement.attributes, initialScope)) { return { messageId: "missingKey", node, @@ -102,7 +101,7 @@ export function create(context: RuleContext): RuleListener { } const initialScope = context.sourceCode.getScope(node); for (const element of elements) { - if (!ER.hasAttribute(context, "key", element.openingElement.attributes, initialScope)) { + if (!hasAttribute(context, "key", element.openingElement.attributes, initialScope)) { context.report({ messageId: "missingKey", node: element, @@ -111,7 +110,7 @@ export function create(context: RuleContext): RuleListener { } }, CallExpression(node) { - state.isWithinChildrenToArray ||= ER.isChildrenToArrayCall(context, node); + state.isWithinChildrenToArray ||= isChildrenToArrayCall(context, node); if (state.isWithinChildrenToArray) return; const callback = match(node) .when(AST.isArrayMapCall, (n) => n.arguments[0]) @@ -127,7 +126,7 @@ export function create(context: RuleContext): RuleListener { report(context)(checkExpression(body)); }, "CallExpression:exit"(node) { - if (!ER.isChildrenToArrayCall(context, node)) { + if (!isChildrenToArrayCall(context, node)) { return; } state.isWithinChildrenToArray = false; diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-misused-capture-owner-stack.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-misused-capture-owner-stack.ts index 30cc9adfb6..c9c0c9f57e 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-misused-capture-owner-stack.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-misused-capture-owner-stack.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isCaptureOwnerStackCall } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import { getSettingsFromContext } from "@eslint-react/shared"; import { AST_NODE_TYPES as T, type TSESTree } from "@typescript-eslint/types"; @@ -45,7 +45,7 @@ export function create(context: RuleContext): RuleListener { return { CallExpression(node) { - if (!ER.isCaptureOwnerStackCall(context, node)) return; + if (!isCaptureOwnerStackCall(context, node)) return; if (AST.findParentNode(node, isDevelopmentOnlyCheck) == null) { context.report({ messageId: "missingDevelopmentOnlyCheck", diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-nested-component-definitions.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-nested-component-definitions.ts index d1363986c5..e06000bf3e 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-nested-component-definitions.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-nested-component-definitions.ts @@ -1,11 +1,21 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { + ComponentDetectionHint, + findParentAttribute, + isClassComponent, + isCreateElementCall, + isDeclaredInRenderPropLoose, + isDirectValueOfRenderPropertyLoose, + isRenderMethodLike, + useComponentCollector, + useComponentCollectorLegacy, +} from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { TSESTree } from "@typescript-eslint/types"; +import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; -import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import { createRule } from "../utils"; export const RULE_NAME = "no-nested-component-definitions"; @@ -33,17 +43,17 @@ export default createRule<[], MessageID>({ }); export function create(context: RuleContext): RuleListener { - const hint = ER.ComponentDetectionHint.SkipArrayMapArgument - | ER.ComponentDetectionHint.SkipNullLiteral - | ER.ComponentDetectionHint.SkipUndefined - | ER.ComponentDetectionHint.SkipBooleanLiteral - | ER.ComponentDetectionHint.SkipStringLiteral - | ER.ComponentDetectionHint.SkipNumberLiteral - | ER.ComponentDetectionHint.StrictLogical - | ER.ComponentDetectionHint.StrictConditional; + const hint = ComponentDetectionHint.SkipArrayMapArgument + | ComponentDetectionHint.SkipNullLiteral + | ComponentDetectionHint.SkipUndefined + | ComponentDetectionHint.SkipBooleanLiteral + | ComponentDetectionHint.SkipStringLiteral + | ComponentDetectionHint.SkipNumberLiteral + | ComponentDetectionHint.StrictLogical + | ComponentDetectionHint.StrictConditional; - const collector = ER.useComponentCollector(context, { hint }); - const collectorLegacy = ER.useComponentCollectorLegacy(); + const collector = useComponentCollector(context, { hint }); + const collectorLegacy = useComponentCollectorLegacy(); return { ...collector.listeners, @@ -73,9 +83,9 @@ export function create(context: RuleContext): RuleListener { // Do not mark anonymous function components to reduce false positives if (name == null) continue; // Do not mark objects containing render methods - if (ER.isDirectValueOfRenderPropertyLoose(component)) continue; + if (isDirectValueOfRenderPropertyLoose(component)) continue; if (isInsideJSXAttributeValue(component)) { - if (!ER.isDeclaredInRenderPropLoose(component)) { + if (!isDeclaredInRenderPropLoose(component)) { context.report({ messageId: "noNestedComponentDefinitions", node: component, @@ -101,7 +111,7 @@ export function create(context: RuleContext): RuleListener { continue; } const parentComponent = AST.findParentNode(component, isFunctionComponent); - if (parentComponent != null && !ER.isDirectValueOfRenderPropertyLoose(parentComponent)) { + if (parentComponent != null && !isDirectValueOfRenderPropertyLoose(parentComponent)) { context.report({ messageId: "noNestedComponentDefinitions", node: component, @@ -152,7 +162,7 @@ export function create(context: RuleContext): RuleListener { */ function isInsideJSXAttributeValue(node: AST.TSESTreeFunction) { return node.parent.type === T.JSXAttribute - || ER.findParentAttribute(node, (n) => n.value?.type === T.JSXExpressionContainer) != null; + || findParentAttribute(node, (n) => n.value?.type === T.JSXExpressionContainer) != null; } /** @@ -171,7 +181,7 @@ function isInsideJSXAttributeValue(node: AST.TSESTreeFunction) { * @returns `true` if node is inside class component's render block, `false` if not */ function isInsideRenderMethod(node: TSESTree.Node) { - return AST.findParentNode(node, (n) => ER.isRenderMethodLike(n) && ER.isClassComponent(n.parent.parent)) != null; + return AST.findParentNode(node, (n) => isRenderMethodLike(n) && isClassComponent(n.parent.parent)) != null; } /** @@ -181,7 +191,7 @@ function isInsideRenderMethod(node: TSESTree.Node) { * @returns `true` if the node is inside createElement's props */ function isInsideCreateElementProps(context: RuleContext, node: TSESTree.Node) { - const call = AST.findParentNode(node, ER.isCreateElementCall(context)); + const call = AST.findParentNode(node, isCreateElementCall(context)); if (call == null) return false; const prop = AST.findParentNode(node, AST.is(T.ObjectExpression)); if (prop == null) return false; diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-nested-lazy-component-declarations.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-nested-lazy-component-declarations.ts index ec10e53392..cbca43547e 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-nested-lazy-component-declarations.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-nested-lazy-component-declarations.ts @@ -1,11 +1,19 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { + ComponentDetectionHint, + isCreateContextCall, + isCreateElementCall, + isLazyCall, + isReactHookCall, + useComponentCollector, + useComponentCollectorLegacy, +} from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { TSESTree } from "@typescript-eslint/types"; +import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; -import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import { createRule } from "../utils"; export const RULE_NAME = "no-nested-lazy-component-declarations"; @@ -33,9 +41,9 @@ export default createRule<[], MessageID>({ }); export function create(context: RuleContext): RuleListener { - const hint = ER.ComponentDetectionHint.None; - const collector = ER.useComponentCollector(context, { hint }); - const collectorLegacy = ER.useComponentCollectorLegacy(); + const hint = ComponentDetectionHint.None; + const collector = useComponentCollector(context, { hint }); + const collectorLegacy = useComponentCollectorLegacy(); const lazyComponentDeclarations = new Set(); @@ -43,7 +51,7 @@ export function create(context: RuleContext): RuleListener { ...collector.listeners, ...collectorLegacy.listeners, ImportExpression(node) { - const lazyCall = AST.findParentNode(node, (n) => ER.isLazyCall(context, n)); + const lazyCall = AST.findParentNode(node, (n) => isLazyCall(context, n)); if (lazyCall != null) { lazyComponentDeclarations.add(lazyCall); } @@ -67,7 +75,7 @@ export function create(context: RuleContext): RuleListener { const significantParent = AST.findParentNode(lazy, (n) => { if (AST.isJSX(n)) return true; if (n.type === T.CallExpression) { - return ER.isReactHookCall(n) || ER.isCreateElementCall(context, n) || ER.isCreateContextCall(context, n); + return isReactHookCall(n) || isCreateElementCall(context, n) || isCreateContextCall(context, n); } if (AST.isFunction(n)) { return functionComponents.some((c) => c.node === n); diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-prop-types.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-prop-types.ts index 7985db70ec..aaf42acbc6 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-prop-types.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-prop-types.ts @@ -1,7 +1,7 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isClassComponent, isComponentNameLoose } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; -import * as VAR from "@eslint-react/var"; +import { findVariable, getVariableDefinitionNode } from "@eslint-react/var"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -48,17 +48,17 @@ export function create(context: RuleContext): RuleListener { if (property.type !== T.Identifier || property.name !== "propTypes") { return; } - if (!ER.isComponentNameLoose(object.name)) { + if (!isComponentNameLoose(object.name)) { return; } - const variable = VAR.findVariable(object.name, context.sourceCode.getScope(node)); - const variableNode = VAR.getVariableDefinitionNode(variable, 0); - if (variableNode != null && (AST.isFunction(variableNode) || ER.isClassComponent(variableNode))) { + const variable = findVariable(object.name, context.sourceCode.getScope(node)); + const variableNode = getVariableDefinitionNode(variable, 0); + if (variableNode != null && (AST.isFunction(variableNode) || isClassComponent(variableNode))) { context.report({ messageId: "noPropTypes", node: property }); } }, PropertyDefinition(node) { - if (!ER.isClassComponent(node.parent.parent)) { + if (!isClassComponent(node.parent.parent)) { return; } if (!node.static || node.key.type !== T.Identifier || node.key.name !== "propTypes") { diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-redundant-should-component-update.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-redundant-should-component-update.ts index 3eeb137365..5a3fe0719c 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-redundant-should-component-update.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-redundant-should-component-update.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { ComponentFlag, useComponentCollectorLegacy } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { TSESTree } from "@typescript-eslint/utils"; @@ -40,7 +40,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { if (!context.sourceCode.text.includes("shouldComponentUpdate")) return {}; - const { ctx, listeners } = ER.useComponentCollectorLegacy(); + const { ctx, listeners } = useComponentCollectorLegacy(); return { ...listeners, @@ -48,7 +48,7 @@ export function create(context: RuleContext): RuleListener { const components = ctx.getAllComponents(program); for (const { name = "PureComponent", node: component, flag } of components.values()) { - if ((flag & ER.ComponentFlag.PureComponent) === 0n) { + if ((flag & ComponentFlag.PureComponent) === 0n) { continue; } const { body } = component.body; diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-set-state-in-component-did-mount.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-set-state-in-component-did-mount.ts index e855ce0dee..66cc64f1dd 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-set-state-in-component-did-mount.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-set-state-in-component-did-mount.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isClassComponent, isComponentDidMount, isThisSetState } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { TSESTree } from "@typescript-eslint/utils"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; @@ -35,11 +35,11 @@ export function create(context: RuleContext): RuleListener { if (!context.sourceCode.text.includes("componentDidMount")) return {}; return { CallExpression(node: TSESTree.CallExpression) { - if (!ER.isThisSetState(node)) { + if (!isThisSetState(node)) { return; } - const clazz = AST.findParentNode(node, ER.isClassComponent); - const method = AST.findParentNode(node, (n) => n === clazz || ER.isComponentDidMount(n)); + const clazz = AST.findParentNode(node, isClassComponent); + const method = AST.findParentNode(node, (n) => n === clazz || isComponentDidMount(n)); if (clazz == null || method == null || method === clazz) return; const methodScope = context.sourceCode.getScope(method); const upperScope = context.sourceCode.getScope(node).upper; diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-set-state-in-component-did-update.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-set-state-in-component-did-update.ts index f6a8deaf1d..2e5e71df70 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-set-state-in-component-did-update.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-set-state-in-component-did-update.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isClassComponent, isComponentDidUpdate, isThisSetState } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { TSESTree } from "@typescript-eslint/utils"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; @@ -35,11 +35,11 @@ export function create(context: RuleContext): RuleListener { if (!context.sourceCode.text.includes("componentDidUpdate")) return {}; return { CallExpression(node: TSESTree.CallExpression) { - if (!ER.isThisSetState(node)) { + if (!isThisSetState(node)) { return; } - const clazz = AST.findParentNode(node, ER.isClassComponent); - const method = AST.findParentNode(node, (n) => n === clazz || ER.isComponentDidUpdate(n)); + const clazz = AST.findParentNode(node, isClassComponent); + const method = AST.findParentNode(node, (n) => n === clazz || isComponentDidUpdate(n)); if (clazz == null || method == null || method === clazz) return; const methodScope = context.sourceCode.getScope(method); const upperScope = context.sourceCode.getScope(node).upper; diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-set-state-in-component-will-update.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-set-state-in-component-will-update.ts index 37362983f9..5556cbec1c 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-set-state-in-component-will-update.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-set-state-in-component-will-update.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isClassComponent, isComponentWillUpdate, isThisSetState } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { TSESTree } from "@typescript-eslint/utils"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; @@ -36,11 +36,11 @@ export function create(context: RuleContext): RuleListener { if (!context.sourceCode.text.includes("componentWillUpdate")) return {}; return { CallExpression(node: TSESTree.CallExpression) { - if (!ER.isThisSetState(node)) { + if (!isThisSetState(node)) { return; } - const clazz = AST.findParentNode(node, ER.isClassComponent); - const method = AST.findParentNode(node, (n) => n === clazz || ER.isComponentWillUpdate(n)); + const clazz = AST.findParentNode(node, isClassComponent); + const method = AST.findParentNode(node, (n) => n === clazz || isComponentWillUpdate(n)); if (clazz == null || method == null || method === clazz) return; const methodScope = context.sourceCode.getScope(method); const upperScope = context.sourceCode.getScope(node).upper; diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-string-refs.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-string-refs.ts index 701638f11b..b80a3e2071 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-string-refs.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-string-refs.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isClassComponent } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { TSESTree } from "@typescript-eslint/types"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; @@ -39,7 +39,7 @@ export function create(context: RuleContext): RuleListener { }; function onClassBodyEnter(node: TSESTree.ClassBody) { - if (ER.isClassComponent(node.parent)) { + if (isClassComponent(node.parent)) { state.isWithinClassComponent = true; } } diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-callback.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-callback.ts index fc6aa37e6a..6a531800ac 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-callback.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-callback.ts @@ -1,8 +1,8 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isUseCallbackCall } from "@eslint-react/core"; import { identity } from "@eslint-react/eff"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; -import * as VAR from "@eslint-react/var"; +import { findVariable, getChildScopes, getVariableDefinitionNode } from "@eslint-react/var"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -40,7 +40,7 @@ export function create(context: RuleContext): RuleListener { if (!context.sourceCode.text.includes("useCallback")) return {}; return { CallExpression(node) { - if (!ER.isUseCallbackCall(node)) { + if (!isUseCallbackCall(node)) { return; } const initialScope = context.sourceCode.getScope(node); @@ -56,8 +56,8 @@ export function create(context: RuleContext): RuleListener { const hasEmptyDeps = match(arg1) .with({ type: T.ArrayExpression }, (n) => n.elements.length === 0) .with({ type: T.Identifier }, (n) => { - const variable = VAR.findVariable(n.name, initialScope); - const variableNode = VAR.getVariableDefinitionNode(variable, 0); + const variable = findVariable(n.name, initialScope); + const variableNode = getVariableDefinitionNode(variable, 0); if (variableNode?.type !== T.ArrayExpression) { return false; } @@ -77,8 +77,8 @@ export function create(context: RuleContext): RuleListener { }) .with({ type: T.FunctionExpression }, identity) .with({ type: T.Identifier }, (n) => { - const variable = VAR.findVariable(n.name, initialScope); - const variableNode = VAR.getVariableDefinitionNode(variable, 0); + const variable = findVariable(n.name, initialScope); + const variableNode = getVariableDefinitionNode(variable, 0); if (variableNode?.type !== T.ArrowFunctionExpression && variableNode?.type !== T.FunctionExpression) { return null; } @@ -88,7 +88,7 @@ export function create(context: RuleContext): RuleListener { if (arg0Node == null) return; const arg0NodeScope = context.sourceCode.getScope(arg0Node); - const arg0NodeReferences = VAR.getChildScopes(arg0NodeScope).flatMap((x) => x.references); + const arg0NodeReferences = getChildScopes(arg0NodeScope).flatMap((x) => x.references); const isReferencedToComponentScope = arg0NodeReferences.some((x) => x.resolved?.scope.block === component); if (!isReferencedToComponentScope) { diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-memo.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-memo.ts index eccfd13585..d1775bb08f 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-memo.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-memo.ts @@ -1,8 +1,8 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isUseMemoCall } from "@eslint-react/core"; import { identity } from "@eslint-react/eff"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; -import * as VAR from "@eslint-react/var"; +import { findVariable, getChildScopes, getVariableDefinitionNode } from "@eslint-react/var"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -40,7 +40,7 @@ export function create(context: RuleContext): RuleListener { return { CallExpression(node) { const initialScope = context.sourceCode.getScope(node); - if (!ER.isUseMemoCall(node)) { + if (!isUseMemoCall(node)) { return; } const scope = context.sourceCode.getScope(node); @@ -62,8 +62,8 @@ export function create(context: RuleContext): RuleListener { const hasEmptyDeps = match(arg1) .with({ type: T.ArrayExpression }, (n) => n.elements.length === 0) .with({ type: T.Identifier }, (n) => { - const variable = VAR.findVariable(n.name, initialScope); - const variableNode = VAR.getVariableDefinitionNode(variable, 0); + const variable = findVariable(n.name, initialScope); + const variableNode = getVariableDefinitionNode(variable, 0); if (variableNode?.type !== T.ArrayExpression) { return false; } @@ -83,8 +83,8 @@ export function create(context: RuleContext): RuleListener { }) .with({ type: T.FunctionExpression }, identity) .with({ type: T.Identifier }, (n) => { - const variable = VAR.findVariable(n.name, initialScope); - const variableNode = VAR.getVariableDefinitionNode(variable, 0); + const variable = findVariable(n.name, initialScope); + const variableNode = getVariableDefinitionNode(variable, 0); if (variableNode?.type !== T.ArrowFunctionExpression && variableNode?.type !== T.FunctionExpression) { return null; } @@ -94,7 +94,7 @@ export function create(context: RuleContext): RuleListener { if (arg0Node == null) return; const arg0NodeScope = context.sourceCode.getScope(arg0Node); - const arg0NodeReferences = VAR.getChildScopes(arg0NodeScope).flatMap((x) => x.references); + const arg0NodeReferences = getChildScopes(arg0NodeScope).flatMap((x) => x.references); const isReferencedToComponentScope = arg0NodeReferences.some((x) => x.resolved?.scope.block === component); if (!isReferencedToComponentScope) { diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-prefix.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-prefix.ts index a539cff678..3ff88136cc 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-prefix.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-unnecessary-use-prefix.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { useHookCollector } from "@eslint-react/core"; import { type RuleContext, type RuleFeature } from "@eslint-react/kit"; import type { TSESTree } from "@typescript-eslint/types"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; @@ -42,7 +42,7 @@ export default createRule<[], MessageID>({ }); export function create(context: RuleContext): RuleListener { - const { ctx, listeners } = ER.useHookCollector(); + const { ctx, listeners } = useHookCollector(); return { ...listeners, "Program:exit"(program) { diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-unsafe-component-will-mount.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-unsafe-component-will-mount.ts index 649b2d36fe..59c897bc12 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-unsafe-component-will-mount.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-unsafe-component-will-mount.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isUnsafeComponentWillMount, useComponentCollectorLegacy } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -30,7 +30,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { if (!context.sourceCode.text.includes("UNSAFE_componentWillMount")) return {}; - const { ctx, listeners } = ER.useComponentCollectorLegacy(); + const { ctx, listeners } = useComponentCollectorLegacy(); return { ...listeners, @@ -41,7 +41,7 @@ export function create(context: RuleContext): RuleListener { const { body } = component.body; for (const member of body) { - if (ER.isUnsafeComponentWillMount(member)) { + if (isUnsafeComponentWillMount(member)) { context.report({ messageId: "noUnsafeComponentWillMount", node: member, diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-unsafe-component-will-receive-props.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-unsafe-component-will-receive-props.ts index 3bb97c0383..3983126ce3 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-unsafe-component-will-receive-props.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-unsafe-component-will-receive-props.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isUnsafeComponentWillReceiveProps, useComponentCollectorLegacy } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -32,7 +32,7 @@ export function create(context: RuleContext): RuleListener { if (!context.sourceCode.text.includes("UNSAFE_componentWillReceiveProps")) { return {}; } - const { ctx, listeners } = ER.useComponentCollectorLegacy(); + const { ctx, listeners } = useComponentCollectorLegacy(); return { ...listeners, @@ -43,7 +43,7 @@ export function create(context: RuleContext): RuleListener { const { body } = component.body; for (const member of body) { - if (ER.isUnsafeComponentWillReceiveProps(member)) { + if (isUnsafeComponentWillReceiveProps(member)) { context.report({ messageId: "noUnsafeComponentWillReceiveProps", node: member, diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-unsafe-component-will-update.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-unsafe-component-will-update.ts index a157646b3c..fe292a7af7 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-unsafe-component-will-update.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-unsafe-component-will-update.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isUnsafeComponentWillUpdate, useComponentCollectorLegacy } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -30,7 +30,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { if (!context.sourceCode.text.includes("UNSAFE_componentWillUpdate")) return {}; - const { ctx, listeners } = ER.useComponentCollectorLegacy(); + const { ctx, listeners } = useComponentCollectorLegacy(); return { ...listeners, @@ -41,7 +41,7 @@ export function create(context: RuleContext): RuleListener { const { body } = component.body; for (const member of body) { - if (ER.isUnsafeComponentWillUpdate(member)) { + if (isUnsafeComponentWillUpdate(member)) { context.report({ messageId: "noUnsafeComponentWillUpdate", node: member, diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-unstable-context-value.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-unstable-context-value.ts index 0ddefc48f7..00eaaf109c 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-unstable-context-value.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-unstable-context-value.ts @@ -1,12 +1,11 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { getElementType, isReactHookCall, useComponentCollector } from "@eslint-react/core"; import { getOrElseUpdate } from "@eslint-react/eff"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; -import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; - import { getSettingsFromContext } from "@eslint-react/shared"; -import * as VAR from "@eslint-react/var"; +import { type Construction, getConstruction } from "@eslint-react/var"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; +import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import { compare } from "compare-versions"; import { createRule } from "../utils"; @@ -39,13 +38,13 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { const { version } = getSettingsFromContext(context); const isReact18OrBelow = compare(version, "19.0.0", "<"); - const { ctx, listeners } = ER.useComponentCollector(context); - const constructions = new WeakMap(); + const { ctx, listeners } = useComponentCollector(context); + const constructions = new WeakMap(); return { ...listeners, JSXOpeningElement(node) { - const fullName = ER.getElementType(context, node.parent); + const fullName = getElementType(context, node.parent); const selfName = fullName.split(".").at(-1); if (selfName == null) return; if (!isContextName(selfName, isReact18OrBelow)) return; @@ -62,9 +61,9 @@ export function create(context: RuleContext): RuleListener { if (value?.type !== T.JSXExpressionContainer) return; const valueExpression = value.expression; const initialScope = context.sourceCode.getScope(valueExpression); - const construction = VAR.getConstruction(valueExpression, initialScope); + const construction = getConstruction(valueExpression, initialScope); if (construction == null) return; - if (ER.isReactHookCall(construction.node)) { + if (isReactHookCall(construction.node)) { return; } getOrElseUpdate(constructions, functionEntry.node, () => []).push(construction); diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-unstable-default-props.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-unstable-default-props.ts index a12309f34b..dddc3c2c51 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-unstable-default-props.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-unstable-default-props.ts @@ -1,8 +1,8 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isReactHookCall, useComponentCollector } from "@eslint-react/core"; import { getOrElseUpdate } from "@eslint-react/eff"; import { type RuleContext, type RuleFeature } from "@eslint-react/kit"; -import * as VAR from "@eslint-react/var"; +import { ConstructionDetectionHint, getConstruction } from "@eslint-react/var"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -35,7 +35,7 @@ export default createRule<[], MessageID>({ }); export function create(context: RuleContext): RuleListener { - const { ctx, listeners } = ER.useComponentCollector(context); + const { ctx, listeners } = useComponentCollector(context); const declarators = new WeakMap(); return { @@ -72,15 +72,15 @@ export function create(context: RuleContext): RuleListener { const { value } = prop; const { right } = value; const initialScope = context.sourceCode.getScope(value); - const construction = VAR.getConstruction( + const construction = getConstruction( value, initialScope, - VAR.ConstructionDetectionHint.StrictCallExpression, + ConstructionDetectionHint.StrictCallExpression, ); if (construction == null) { continue; } - if (ER.isReactHookCall(construction.node)) { + if (isReactHookCall(construction.node)) { continue; } const forbiddenType = AST.toDelimiterFormat(right); diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-unused-class-component-members.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-unused-class-component-members.ts index 2b962137ed..6dd5c5bb91 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-unused-class-component-members.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-unused-class-component-members.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isClassComponent } from "@eslint-react/core"; import { constFalse, constTrue } from "@eslint-react/eff"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; @@ -77,7 +77,7 @@ export function create(context: RuleContext): RuleListener { const propertyUsages = new WeakMap>(); function classEnter(node: AST.TSESTreeClass) { classEntries.push(node); - if (!ER.isClassComponent(node)) { + if (!isClassComponent(node)) { return; } propertyDefs.set(node, new Set()); @@ -85,7 +85,7 @@ export function create(context: RuleContext): RuleListener { } function classExit() { const currentClass = classEntries.pop(); - if (currentClass == null || !ER.isClassComponent(currentClass)) { + if (currentClass == null || !isClassComponent(currentClass)) { return; } const className = AST.getClassId(currentClass)?.name; @@ -116,7 +116,7 @@ export function create(context: RuleContext): RuleListener { function methodEnter(node: AST.TSESTreeMethodOrProperty) { methodEntries.push(node); const currentClass = classEntries.at(-1); - if (currentClass == null || !ER.isClassComponent(currentClass)) { + if (currentClass == null || !isClassComponent(currentClass)) { return; } if (node.static) { @@ -141,7 +141,7 @@ export function create(context: RuleContext): RuleListener { if (currentClass == null || currentMethod == null) { return; } - if (!ER.isClassComponent(currentClass) || currentMethod.static) { + if (!isClassComponent(currentClass) || currentMethod.static) { return; } if (!AST.isThisExpression(node.object) || !isKeyLiteral(node, node.property)) { @@ -168,7 +168,7 @@ export function create(context: RuleContext): RuleListener { if (currentClass == null || currentMethod == null) { return; } - if (!ER.isClassComponent(currentClass) || currentMethod.static) { + if (!isClassComponent(currentClass) || currentMethod.static) { return; } // detect `{ foo, bar: baz } = this` diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-unused-props.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-unused-props.ts index 6a3feea668..8c15073713 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-unused-props.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-unused-props.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { useComponentCollector } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { Reference } from "@typescript-eslint/scope-manager"; import type { TSESTree } from "@typescript-eslint/types"; @@ -35,7 +35,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { const services = ESLintUtils.getParserServices(context, false); - const { ctx, listeners } = ER.useComponentCollector(context); + const { ctx, listeners } = useComponentCollector(context); return { ...listeners, diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-unused-state.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-unused-state.ts index 5fb684b726..6a3b7f2158 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-unused-state.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-unused-state.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isAssignmentToThisState, isClassComponent, isGetDerivedStateFromProps } from "@eslint-react/core"; import type { unit } from "@eslint-react/eff"; import { constFalse, constTrue } from "@eslint-react/eff"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; @@ -59,7 +59,7 @@ export function create(context: RuleContext): RuleListener { } function classExit() { const currentClass = classEntries.pop(); - if (currentClass == null || !ER.isClassComponent(currentClass)) { + if (currentClass == null || !isClassComponent(currentClass)) { return; } const className = AST.getClassId(currentClass)?.name; @@ -78,11 +78,11 @@ export function create(context: RuleContext): RuleListener { function methodEnter(node: AST.TSESTreeMethodOrProperty) { methodEntries.push(node); const currentClass = classEntries.at(-1); - if (currentClass == null || !ER.isClassComponent(currentClass)) { + if (currentClass == null || !isClassComponent(currentClass)) { return; } if (node.static) { - if (ER.isGetDerivedStateFromProps(node) && isMatching({ params: [P.nonNullable, ...P.array()] })(node.value)) { + if (isGetDerivedStateFromProps(node) && isMatching({ params: [P.nonNullable, ...P.array()] })(node.value)) { const defNode = stateDefs.get(currentClass)?.node; stateDefs.set(currentClass, { node: defNode, isUsed: true }); } @@ -104,11 +104,11 @@ export function create(context: RuleContext): RuleListener { return { AssignmentExpression(node) { - if (!ER.isAssignmentToThisState(node)) { + if (!isAssignmentToThisState(node)) { return; } const currentClass = classEntries.at(-1); - if (currentClass == null || !ER.isClassComponent(currentClass)) { + if (currentClass == null || !isClassComponent(currentClass)) { return; } const currentConstructor = constructorEntries.at(-1); @@ -131,7 +131,7 @@ export function create(context: RuleContext): RuleListener { return; } const currentClass = classEntries.at(-1); - if (currentClass == null || !ER.isClassComponent(currentClass)) { + if (currentClass == null || !isClassComponent(currentClass)) { return; } const currentMethod = methodEntries.at(-1); @@ -155,7 +155,7 @@ export function create(context: RuleContext): RuleListener { "PropertyDefinition:exit": methodExit, VariableDeclarator(node) { const currentClass = classEntries.at(-1); - if (currentClass == null || !ER.isClassComponent(currentClass)) { + if (currentClass == null || !isClassComponent(currentClass)) { return; } const currentMethod = methodEntries.at(-1); diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-use-context.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-use-context.ts index f279afcc3c..bd92cdf60d 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-use-context.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-use-context.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { isReactHookCall, isUseContextCall } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import { getSettingsFromContext } from "@eslint-react/shared"; import type { TSESTree } from "@typescript-eslint/types"; @@ -45,7 +45,7 @@ export function create(context: RuleContext): RuleListener { const hookCalls = new Set(); return { CallExpression(node) { - if (!ER.isReactHookCall(node)) { + if (!isReactHookCall(node)) { return; } hookCalls.add(node); @@ -85,7 +85,7 @@ export function create(context: RuleContext): RuleListener { }, "Program:exit"() { for (const node of hookCalls) { - if (!ER.isUseContextCall(node)) { + if (!isUseContextCall(node)) { continue; } context.report({ diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-useless-forward-ref.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-useless-forward-ref.ts index 72f0604806..2461f1bc49 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-useless-forward-ref.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-useless-forward-ref.ts @@ -1,6 +1,6 @@ // Ported from https://github.com/jsx-eslint/eslint-plugin-react/pull/3667 import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isForwardRefCall } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -33,7 +33,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { return { CallExpression(node) { - if (!ER.isForwardRefCall(context, node)) { + if (!isForwardRefCall(context, node)) { return; } const [component] = node.arguments; diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/no-useless-fragment.ts b/packages/plugins/eslint-plugin-react-x/src/rules/no-useless-fragment.ts index 595af4e374..4f2cde0960 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/no-useless-fragment.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/no-useless-fragment.ts @@ -1,6 +1,6 @@ /* eslint-disable jsdoc/require-param */ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { hasAttribute, isFragmentElement, isHostElement, isJsxText } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import { AST_NODE_TYPES as T } from "@typescript-eslint/types"; import type { TSESTree } from "@typescript-eslint/utils"; @@ -60,7 +60,7 @@ export function create(context: RuleContext, [option]: Optio return { // Check JSX elements that might be fragments JSXElement(node) { - if (!ER.isFragmentElement(context, node)) return; + if (!isFragmentElement(context, node)) return; checkNode(context, node, allowExpressions); }, // Check JSX fragments @@ -83,7 +83,7 @@ function isWhiteSpace(node: TSESTree.JSXText | TSESTree.Literal) { * Check if a node is padding spaces (whitespace with line breaks) */ function isPaddingSpaces(node: TSESTree.Node) { - return ER.isJsxText(node) + return isJsxText(node) && isWhiteSpace(node) && node.raw.includes("\n"); } @@ -112,12 +112,12 @@ function checkNode( const initialScope = context.sourceCode.getScope(node); // Skip if the fragment has a key prop (indicates it's needed for lists) - if (node.type === T.JSXElement && ER.hasAttribute(context, "key", node.openingElement.attributes, initialScope)) { + if (node.type === T.JSXElement && hasAttribute(context, "key", node.openingElement.attributes, initialScope)) { return; } // Report fragment placed inside a host component (e.g.
<>
) - if (ER.isHostElement(context, node.parent)) { + if (isHostElement(context, node.parent)) { context.report({ messageId: "uselessFragment", node, @@ -145,7 +145,7 @@ function checkNode( case allowExpressions && !isChildElement && node.children.length === 1 - && ER.isJsxText(node.children.at(0)): { + && isJsxText(node.children.at(0)): { return; } @@ -217,7 +217,7 @@ function getFix(context: RuleContext, node: TSESTree.JSXElement | TSESTree.JSXFr function canFix(context: RuleContext, node: TSESTree.JSXElement | TSESTree.JSXFragment) { // Don't fix fragments inside custom components (might require children to be ReactElement) if (node.parent.type === T.JSXElement || node.parent.type === T.JSXFragment) { - return ER.isHostElement(context, node.parent); + return isHostElement(context, node.parent); } // Don't fix empty fragments without a JSX parent @@ -228,5 +228,5 @@ function canFix(context: RuleContext, node: TSESTree.JSXElement | TSESTree.JSXFr // Don't fix fragments with text or expressions outside of JSX context return !node .children - .some((child) => (ER.isJsxText(child) && !isWhiteSpace(child)) || AST.is(T.JSXExpressionContainer)(child)); + .some((child) => (isJsxText(child) && !isWhiteSpace(child)) || AST.is(T.JSXExpressionContainer)(child)); } diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/prefer-destructuring-assignment.ts b/packages/plugins/eslint-plugin-react-x/src/rules/prefer-destructuring-assignment.ts index 12249729c4..b84bcab675 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/prefer-destructuring-assignment.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/prefer-destructuring-assignment.ts @@ -1,5 +1,5 @@ import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isComponentNameLoose, useComponentCollector } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { Scope } from "@typescript-eslint/scope-manager"; import type { TSESTree } from "@typescript-eslint/types"; @@ -39,7 +39,7 @@ export default createRule<[], MessageID>({ }); export function create(context: RuleContext): RuleListener { - const { ctx, listeners } = ER.useComponentCollector(context); + const { ctx, listeners } = useComponentCollector(context); const memberExpressionWithNames: [Scope, MemberExpressionWithObjectName][] = []; return { @@ -64,7 +64,7 @@ export function create(context: RuleContext): RuleListener { } const id = AST.getFunctionId(block); return id != null - && ER.isComponentNameLoose(id.name) + && isComponentNameLoose(id.name) && components.some((component) => component.node === block); } diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/prefer-read-only-props.ts b/packages/plugins/eslint-plugin-react-x/src/rules/prefer-read-only-props.ts index aebb5305c6..b37ed5038b 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/prefer-read-only-props.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/prefer-read-only-props.ts @@ -1,4 +1,4 @@ -import * as ER from "@eslint-react/core"; +import { useComponentCollector } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import { getConstrainedTypeAtLocation, isTypeReadonly } from "@typescript-eslint/type-utils"; import { ESLintUtils, type ParserServicesWithTypeInformation } from "@typescript-eslint/utils"; @@ -37,7 +37,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { const services = ESLintUtils.getParserServices(context, false); - const { ctx, listeners } = ER.useComponentCollector(context); + const { ctx, listeners } = useComponentCollector(context); return { ...listeners, "Program:exit"(program) { diff --git a/packages/plugins/eslint-plugin-react-x/src/rules/prefer-use-state-lazy-initialization.ts b/packages/plugins/eslint-plugin-react-x/src/rules/prefer-use-state-lazy-initialization.ts index 3a17dae6a8..2d85414dab 100644 --- a/packages/plugins/eslint-plugin-react-x/src/rules/prefer-use-state-lazy-initialization.ts +++ b/packages/plugins/eslint-plugin-react-x/src/rules/prefer-use-state-lazy-initialization.ts @@ -1,6 +1,6 @@ // Ported from https://github.com/jsx-eslint/eslint-plugin-react/pull/3579/commits/ebb739a0fe99a2ee77055870bfda9f67a2691374 import * as AST from "@eslint-react/ast"; -import * as ER from "@eslint-react/core"; +import { isReactHookName, isUseCall, isUseStateCall } from "@eslint-react/core"; import type { RuleContext, RuleFeature } from "@eslint-react/kit"; import type { RuleListener } from "@typescript-eslint/utils/ts-eslint"; import type { CamelCase } from "string-ts"; @@ -44,7 +44,7 @@ export default createRule<[], MessageID>({ export function create(context: RuleContext): RuleListener { return { CallExpression(node) { - if (!ER.isUseStateCall(node)) { + if (!isUseStateCall(node)) { return; } const [useStateInput] = node.arguments; @@ -54,7 +54,7 @@ export function create(context: RuleContext): RuleListener { for (const expr of AST.getNestedNewExpressions(useStateInput)) { if (!("name" in expr.callee)) continue; if (ALLOW_LIST.includes(expr.callee.name)) continue; - if (AST.findParentNode(expr, ER.isUseCall) != null) continue; + if (AST.findParentNode(expr, isUseCall) != null) continue; context.report({ messageId: "preferUseStateLazyInitialization", node: expr, @@ -62,9 +62,9 @@ export function create(context: RuleContext): RuleListener { } for (const expr of AST.getNestedCallExpressions(useStateInput)) { if (!("name" in expr.callee)) continue; - if (ER.isReactHookName(expr.callee.name)) continue; + if (isReactHookName(expr.callee.name)) continue; if (ALLOW_LIST.includes(expr.callee.name)) continue; - if (AST.findParentNode(expr, ER.isUseCall) != null) continue; + if (AST.findParentNode(expr, isUseCall) != null) continue; context.report({ messageId: "preferUseStateLazyInitialization", node: expr,