Skip to content

Commit

Permalink
feat(plugins/react-x): add jsx-uses-vars
Browse files Browse the repository at this point in the history
  • Loading branch information
Rel1cx committed Oct 29, 2024
1 parent 01cc707 commit 4609a3a
Show file tree
Hide file tree
Showing 7 changed files with 241 additions and 98 deletions.
10 changes: 5 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@
"devDependencies": {
"@changesets/cli": "^2.27.9",
"@effect/language-service": "^0.2.0",
"@effect/platform": "^0.69.9",
"@effect/platform-bun": "^0.49.10",
"@effect/platform-node": "^0.64.10",
"@effect/platform": "^0.69.10",
"@effect/platform-bun": "^0.49.11",
"@effect/platform-node": "^0.64.11",
"@effect/schema": "^0.75.5",
"@eslint/config-inspector": "^0.5.5",
"@eslint/js": "^9.13.0",
Expand All @@ -71,7 +71,7 @@
"concurrently": "^9.0.1",
"cspell": "^8.15.4",
"dprint": "^0.47.5",
"effect": "^3.10.4",
"effect": "^3.10.5",
"esbuild": "^0.24.0",
"eslint": "^9.13.0",
"eslint-config-flat-gitignore": "^0.3.0",
Expand All @@ -87,7 +87,7 @@
"eslint-plugin-unicorn": "^56.0.0",
"eslint-plugin-vitest": "^0.5.4",
"importx": "^0.5.0",
"lefthook": "^1.8.1",
"lefthook": "^1.8.2",
"markdownlint": "^0.36.1",
"publint": "^0.2.12",
"react": "^18.3.1",
Expand Down
2 changes: 2 additions & 0 deletions packages/plugins/eslint-plugin-react-x/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { name, version } from "../package.json";
import avoidShorthandBoolean from "./rules/avoid-shorthand-boolean";
import avoidShorthandFragment from "./rules/avoid-shorthand-fragment";
import forwardRefUsingRef from "./rules/ensure-forward-ref-using-ref";
import jsxUsesVars from "./rules/jsx-uses-vars";
import noAccessStateInSetstate from "./rules/no-access-state-in-setstate";
import noArrayIndexKey from "./rules/no-array-index-key";
import noChildrenCount from "./rules/no-children-count";
Expand Down Expand Up @@ -70,6 +71,7 @@ export default {
"avoid-shorthand-boolean": avoidShorthandBoolean,
"avoid-shorthand-fragment": avoidShorthandFragment,
"ensure-forward-ref-using-ref": forwardRefUsingRef,
"jsx-uses-vars": jsxUsesVars,
"no-access-state-in-setstate": noAccessStateInSetstate,
"no-array-index-key": noArrayIndexKey,
"no-children-count": noChildrenCount,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { allValid, ruleTester } from "../../../../../test";
import rule, { RULE_NAME } from "./jsx-uses-vars";

ruleTester.run(RULE_NAME, rule, {
invalid: [],
valid: [
...allValid,
{
code: /* tsx */ `
function foo() {
var App;
var bar = React.render(<App/>);
return bar;
};
foo()
`,
},
{
code: /* tsx */ `
var App;
React.render(<App/>);
`,
},
{
code: /* tsx */ `
var a = 1;
React.render(<img src={a} />);
`,
},
{
code: /* tsx */ `
var App;
function f() {
return <App />;
}
f();
`,
},
{
code: /* tsx */ `
var App;
<App.Hello />
`,
},
{
code: /* tsx */ `
class HelloMessage {};
<HelloMessage />
`,
},
{
code: /* tsx */ `
class HelloMessage {
render() {
var HelloMessage = <div>Hello</div>;
return HelloMessage;
}
};
<HelloMessage />
`,
},
{
code: /* tsx */ `
function foo() {
var App = { Foo: { Bar: {} } };
var bar = React.render(<App.Foo.Bar/>);
return bar;
};
foo()
`,
},
{
code: /* tsx */ `
function foo() {
var App = { Foo: { Bar: { Baz: {} } } };
var bar = React.render(<App.Foo.Bar.Baz/>);
return bar;
};
foo()
`,
},
{
code: /* tsx */ `
var object;
React.render(<object.Tag />);
`,
},
{
code: /* tsx */ `
var object;
React.render(<object.tag />);
`,
},
],
});
46 changes: 46 additions & 0 deletions packages/plugins/eslint-plugin-react-x/src/rules/jsx-uses-vars.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { O } from "@eslint-react/tools";
import type { TSESTree } from "@typescript-eslint/types";
import { AST_NODE_TYPES } from "@typescript-eslint/types";
import type { CamelCase } from "string-ts";

import { createRule } from "../utils";

export const RULE_NAME = "jsx-uses-vars";

export type MessageID = CamelCase<typeof RULE_NAME>;

export default createRule<[], MessageID>({
meta: {
type: "problem",
docs: {
// eslint-disable-next-line eslint-plugin/require-meta-docs-description
description: "a helper rule to mark variables as used",
},
messages: {
jsxUsesVars: "",
},
schema: [],
},
name: RULE_NAME,
create(context) {
function getName(node: TSESTree.Node): O.Option<string> {
switch (node.type) {
case AST_NODE_TYPES.JSXIdentifier:
return O.some(node.name);
case AST_NODE_TYPES.JSXMemberExpression:
return getName(node.object);
default:
return O.none();
}
}
return {
JSXOpeningElement(node) {
if (node.name.type === AST_NODE_TYPES.JSXIdentifier && /^[a-z]/u.test(node.name.name)) return;
O.map(getName(node.name), (name) => {
context.sourceCode.markVariableAsUsed(name, node);
});
},
};
},
defaultOptions: [],
});
2 changes: 1 addition & 1 deletion packages/tools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"publish": "pnpm run build && pnpm run lint:publish"
},
"devDependencies": {
"effect": "^3.10.4",
"effect": "^3.10.5",
"tsup": "^8.3.5"
}
}
Loading

0 comments on commit 4609a3a

Please sign in to comment.