eslint-plugin-react-debug
Version:
ESLint React's ESLint plugin for debugging related rules.
345 lines (333 loc) • 9.88 kB
JavaScript
'use strict';
var shared = require('@eslint-react/shared');
var ER2 = require('@eslint-react/core');
var utils = require('@typescript-eslint/utils');
var eff = require('@eslint-react/eff');
var kit = require('@eslint-react/kit');
var types = require('@typescript-eslint/types');
var tsPattern = require('ts-pattern');
var typescript = require('typescript');
function _interopNamespace(e) {
if (e && e.__esModule) return e;
var n = Object.create(null);
if (e) {
Object.keys(e).forEach(function (k) {
if (k !== 'default') {
var d = Object.getOwnPropertyDescriptor(e, k);
Object.defineProperty(n, k, d.get ? d : {
enumerable: true,
get: function () { return e[k]; }
});
}
});
}
n.default = e;
return Object.freeze(n);
}
var ER2__namespace = /*#__PURE__*/_interopNamespace(ER2);
var __defProp = Object.defineProperty;
var __export = (target, all) => {
for (var name3 in all)
__defProp(target, name3, { get: all[name3], enumerable: true });
};
// src/configs/all.ts
var all_exports = {};
__export(all_exports, {
name: () => name,
rules: () => rules,
settings: () => settings
});
var name = "react-debug/all";
var rules = {
"react-debug/class-component": "warn",
"react-debug/function-component": "warn",
"react-debug/hook": "warn",
"react-debug/is-from-react": "warn",
"react-debug/jsx": "warn"
};
var settings = {
"react-x": shared.DEFAULT_ESLINT_REACT_SETTINGS
};
// package.json
var name2 = "eslint-plugin-react-debug";
var version = "1.47.4";
var createRule = utils.ESLintUtils.RuleCreator(shared.getDocsUrl("debug"));
// src/utils/stringify.ts
function stringify(value) {
return JSON.stringify(value, null, 2);
}
// src/rules/class-component.ts
var RULE_NAME = "class-component";
var RULE_FEATURES = [
"DBG"
];
var class_component_default = createRule({
meta: {
type: "problem",
docs: {
description: "Reports all class components.",
[Symbol.for("rule_features")]: RULE_FEATURES
},
messages: {
classComponent: "{{json}}"
},
schema: []
},
name: RULE_NAME,
create,
defaultOptions: []
});
function create(context) {
const { ctx, listeners } = ER2__namespace.useComponentCollectorLegacy();
return {
...listeners,
"Program:exit"(program) {
const components = ctx.getAllComponents(program);
for (const { name: name3 = "anonymous", node: component } of components.values()) {
context.report({
messageId: "classComponent",
node: component,
data: {
json: stringify({ name: name3 })
}
});
}
}
};
}
var RULE_NAME2 = "function-component";
var RULE_FEATURES2 = [
"DBG"
];
var function_component_default = createRule({
meta: {
type: "problem",
docs: {
description: "Reports all function components.",
[Symbol.for("rule_features")]: RULE_FEATURES2
},
messages: {
functionComponent: "{{json}}"
// "[function component] name: {{name}}, memo: {{memo}}, forwardRef: {{forwardRef}}, hookCalls: {{hookCalls}}, displayName: {{displayName}}.",
},
schema: []
},
name: RULE_NAME2,
create: create2,
defaultOptions: []
});
function create2(context) {
const { ctx, listeners } = ER2__namespace.useComponentCollector(
context,
{
collectDisplayName: true,
collectHookCalls: true,
hint: ER2__namespace.DEFAULT_COMPONENT_DETECTION_HINT
}
);
return {
...listeners,
"Program:exit"(program) {
const components = ctx.getAllComponents(program);
for (const { name: name3 = "anonymous", node, displayName, flag, hookCalls } of components.values()) {
context.report({
messageId: "functionComponent",
node,
data: {
json: stringify({
name: name3,
displayName: displayName == null ? "none" : context.sourceCode.getText(displayName),
forwardRef: (flag & ER2__namespace.ComponentFlag.ForwardRef) > 0n,
hookCalls: hookCalls.length,
memo: (flag & ER2__namespace.ComponentFlag.Memo) > 0n
})
}
});
}
}
};
}
var RULE_NAME3 = "hook";
var RULE_FEATURES3 = [
"DBG"
];
var hook_default = createRule({
meta: {
type: "problem",
docs: {
description: "Reports all React Hooks.",
[Symbol.for("rule_features")]: RULE_FEATURES3
},
messages: {
hook: "{{json}}"
},
schema: []
},
name: RULE_NAME3,
create: create3,
defaultOptions: []
});
function create3(context) {
const { ctx, listeners } = ER2__namespace.useHookCollector();
return {
...listeners,
"Program:exit"(program) {
const allHooks = ctx.getAllHooks(program);
for (const { name: name3, node, hookCalls } of allHooks.values()) {
context.report({
messageId: "hook",
node,
data: {
json: stringify({
name: name3,
hookCalls: hookCalls.length
})
}
});
}
}
};
}
var RULE_NAME4 = "is-from-react";
var RULE_FEATURES4 = [
"DBG"
];
var is_from_react_default = createRule({
meta: {
type: "problem",
docs: {
description: "Reports all identifiers that are initialized from React.",
[Symbol.for("rule_features")]: RULE_FEATURES4
},
messages: {
isFromReact: "{{json}}"
},
schema: []
},
name: RULE_NAME4,
create: create4,
defaultOptions: []
});
function create4(context) {
const { importSource = "react" } = shared.getSettingsFromContext(context);
function isFromReact(node, initialScope) {
const name3 = node.name;
switch (true) {
case (node.parent.type === utils.AST_NODE_TYPES.MemberExpression && node.parent.property === node && node.parent.object.type === utils.AST_NODE_TYPES.Identifier):
return ER2__namespace.isInitializedFromReact(node.parent.object.name, importSource, initialScope);
case (node.parent.type === utils.AST_NODE_TYPES.JSXMemberExpression && node.parent.property === node && node.parent.object.type === utils.AST_NODE_TYPES.JSXIdentifier):
return ER2__namespace.isInitializedFromReact(node.parent.object.name, importSource, initialScope);
default:
return ER2__namespace.isInitializedFromReact(name3, importSource, initialScope);
}
}
function visitorFunction(node) {
const shouldSkipDuplicate = node.parent.type === utils.AST_NODE_TYPES.ImportSpecifier && node.parent.imported === node && node.parent.imported.name === node.parent.local.name;
if (shouldSkipDuplicate) return;
const name3 = node.name;
const initialScope = context.sourceCode.getScope(node);
if (!isFromReact(node, initialScope)) return;
context.report({
messageId: "isFromReact",
node,
data: {
json: stringify({
name: name3,
importSource
})
}
});
}
return {
Identifier: visitorFunction,
JSXIdentifier: visitorFunction
};
}
var RULE_NAME5 = "jsx";
var RULE_FEATURES5 = [
"DBG"
];
var jsx_default = createRule({
meta: {
type: "problem",
docs: {
description: "Reports all JSX elements and fragments.",
[Symbol.for("rule_features")]: RULE_FEATURES5
},
messages: {
jsx: "{{json}}"
},
schema: []
},
name: RULE_NAME5,
create: create5,
defaultOptions: []
});
function create5(context) {
const jsxConfigFromContext = kit.JsxConfig.getFromContext(context);
const jsxConfigFromAnnotation = kit.JsxConfig.getFromAnnotation(context);
const jsxConfig = {
...jsxConfigFromContext,
...jsxConfigFromAnnotation
};
function getReportDescriptor(context2) {
return (node) => ({
messageId: "jsx",
node,
data: {
json: stringify({
kind: tsPattern.match(node).with({ type: types.AST_NODE_TYPES.JSXElement }, (n) => ER2__namespace.isFragmentElement(context2, n) ? "fragment" : "element").with({ type: types.AST_NODE_TYPES.JSXFragment }, () => "fragment").exhaustive(),
type: ER2__namespace.getElementType(context2, node),
jsx: tsPattern.match(jsxConfig.jsx).with(typescript.JsxEmit.None, () => "none").with(typescript.JsxEmit.ReactJSX, () => "react-jsx").with(typescript.JsxEmit.ReactJSXDev, () => "react-jsx-dev").with(typescript.JsxEmit.React, () => "react").with(typescript.JsxEmit.ReactNative, () => "react-native").with(typescript.JsxEmit.Preserve, () => "preserve").otherwise(() => "unknown"),
jsxFactory: jsxConfig.jsxFactory,
jsxFragmentFactory: jsxConfig.jsxFragmentFactory,
jsxImportSource: jsxConfig.jsxImportSource,
jsxRuntime: tsPattern.match(jsxConfig.jsx).with(tsPattern.P.union(typescript.JsxEmit.None, typescript.JsxEmit.ReactJSX, typescript.JsxEmit.ReactJSXDev), () => "automatic").otherwise(() => "classic")
})
}
});
}
return {
"JSXElement, JSXFragment": eff.flow(getReportDescriptor(context), kit.Reporter.make(context).send)
};
}
// src/plugin.ts
var plugin = {
meta: {
name: name2,
version
},
rules: {
["class-component"]: class_component_default,
["function-component"]: function_component_default,
["hook"]: hook_default,
["is-from-react"]: is_from_react_default,
["jsx"]: jsx_default,
// Part: deprecated rules
/** @deprecated Use `hook` instead */
"react-hooks": hook_default
}
};
// src/index.ts
function makeConfig(config) {
return {
...config,
plugins: {
"react-debug": plugin
}
};
}
function makeLegacyConfig({ rules: rules2 }) {
return {
plugins: ["react-debug"],
rules: rules2
};
}
var index_default = {
...plugin,
configs: {
["all"]: makeConfig(all_exports),
["all-legacy"]: makeLegacyConfig(all_exports)
}
};
module.exports = index_default;