Skip to content

Commit 370df85

Browse files
committed
refactor: less abstraction
1 parent 5f15e99 commit 370df85

File tree

8 files changed

+82
-56
lines changed

8 files changed

+82
-56
lines changed

packages/plugins/eslint-plugin-react-x/src/rules/no-access-state-in-setstate.ts

+18-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import * as AST from "@eslint-react/ast";
22
import { isClassComponent, isThisSetState } from "@eslint-react/core";
3-
import { _ } from "@eslint-react/eff";
3+
import { _, constFalse, constTrue } from "@eslint-react/eff";
44
import type { RuleFeature } from "@eslint-react/shared";
55
import { AST_NODE_TYPES as T } from "@typescript-eslint/types";
66
import type { TSESTree } from "@typescript-eslint/utils";
77
import type { CamelCase } from "string-ts";
8+
import { match } from "ts-pattern";
89

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

@@ -16,6 +17,21 @@ export const RULE_FEATURES = [
1617

1718
export type MessageID = CamelCase<typeof RULE_NAME>;
1819

20+
function isKeyLiteral(
21+
node:
22+
| TSESTree.MemberExpression
23+
| TSESTree.MethodDefinition
24+
| TSESTree.Property
25+
| TSESTree.PropertyDefinition,
26+
key: TSESTree.Node,
27+
) {
28+
return match(key)
29+
.with({ type: T.Literal }, constTrue)
30+
.with({ type: T.TemplateLiteral, expressions: [] }, constTrue)
31+
.with({ type: T.Identifier }, () => !node.computed)
32+
.otherwise(constFalse);
33+
}
34+
1935
function getName(node: TSESTree.Expression | TSESTree.PrivateIdentifier): string | _ {
2036
if (AST.isTsOnlyExpression(node)) {
2137
return getName(node.expression);
@@ -142,7 +158,7 @@ export default createRule<[], MessageID>({
142158
.properties
143159
.some((prop) =>
144160
prop.type === T.Property
145-
&& AST.isKeyLiteralLike(prop, prop.key)
161+
&& isKeyLiteral(prop, prop.key)
146162
&& getName(prop.key) === "state"
147163
);
148164
if (!hasState) {

packages/plugins/eslint-plugin-react-x/src/rules/no-unused-class-component-members.ts

+20-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
import * as AST from "@eslint-react/ast";
22
import { isClassComponent } from "@eslint-react/core";
3-
import { _ } from "@eslint-react/eff";
3+
import { _, constFalse, constTrue } from "@eslint-react/eff";
44
import type { RuleFeature } from "@eslint-react/shared";
55
import { AST_NODE_TYPES as T } from "@typescript-eslint/types";
66
import type { TSESTree } from "@typescript-eslint/utils";
77
import type { CamelCase } from "string-ts";
8+
import { match } from "ts-pattern";
89

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

@@ -38,6 +39,21 @@ const LIFECYCLE_METHODS = new Set([
3839
"UNSAFE_componentWillUpdate",
3940
]);
4041

42+
function isKeyLiteral(
43+
node:
44+
| TSESTree.MemberExpression
45+
| TSESTree.MethodDefinition
46+
| TSESTree.Property
47+
| TSESTree.PropertyDefinition,
48+
key: TSESTree.Node,
49+
) {
50+
return match(key)
51+
.with({ type: T.Literal }, constTrue)
52+
.with({ type: T.TemplateLiteral, expressions: [] }, constTrue)
53+
.with({ type: T.Identifier }, () => !node.computed)
54+
.otherwise(constFalse);
55+
}
56+
4157
// Return the name of an identifier or the string value of a literal. Useful
4258
// anywhere that a literal may be used as a key (e.g., member expressions,
4359
// method definitions, ObjectExpression property keys).
@@ -123,7 +139,7 @@ export default createRule<[], MessageID>({
123139
if (node.static) {
124140
return;
125141
}
126-
if (AST.isKeyLiteralLike(node, node.key)) {
142+
if (isKeyLiteral(node, node.key)) {
127143
propertyDefs.get(currentClass)?.add(node.key);
128144
}
129145
}
@@ -145,7 +161,7 @@ export default createRule<[], MessageID>({
145161
if (!isClassComponent(currentClass) || currentMethod.static) {
146162
return;
147163
}
148-
if (!AST.isThisExpression(node.object) || !AST.isKeyLiteralLike(node, node.property)) {
164+
if (!AST.isThisExpression(node.object) || !isKeyLiteral(node, node.property)) {
149165
return;
150166
}
151167
if (node.parent.type === T.AssignmentExpression && node.parent.left === node) {
@@ -175,7 +191,7 @@ export default createRule<[], MessageID>({
175191
// detect `{ foo, bar: baz } = this`
176192
if (node.init != null && AST.isThisExpression(node.init) && node.id.type === T.ObjectPattern) {
177193
for (const prop of node.id.properties) {
178-
if (prop.type === T.Property && AST.isKeyLiteralLike(prop, prop.key)) {
194+
if (prop.type === T.Property && isKeyLiteral(prop, prop.key)) {
179195
const keyName = getName(prop.key);
180196
if (keyName != null) {
181197
propertyUsages.get(currentClass)?.add(keyName);

packages/plugins/eslint-plugin-react-x/src/rules/no-unused-state.ts

+18-3
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import * as AST from "@eslint-react/ast";
22
import { isClassComponent, isGetDerivedStateFromProps } from "@eslint-react/core";
3-
import { _ } from "@eslint-react/eff";
3+
import { _, constFalse, constTrue } from "@eslint-react/eff";
44
import type { RuleFeature } from "@eslint-react/shared";
55
import { AST_NODE_TYPES as T } from "@typescript-eslint/types";
66
import type { TSESTree } from "@typescript-eslint/utils";
77
import type { CamelCase } from "string-ts";
8-
import { isMatching, P } from "ts-pattern";
8+
import { isMatching, match, P } from "ts-pattern";
99

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

@@ -17,6 +17,21 @@ export const RULE_FEATURES = [
1717

1818
export type MessageID = CamelCase<typeof RULE_NAME>;
1919

20+
function isKeyLiteral(
21+
node:
22+
| TSESTree.MemberExpression
23+
| TSESTree.MethodDefinition
24+
| TSESTree.Property
25+
| TSESTree.PropertyDefinition,
26+
key: TSESTree.Node,
27+
) {
28+
return match(key)
29+
.with({ type: T.Literal }, constTrue)
30+
.with({ type: T.TemplateLiteral, expressions: [] }, constTrue)
31+
.with({ type: T.Identifier }, () => !node.computed)
32+
.otherwise(constFalse);
33+
}
34+
2035
function getName(node: TSESTree.Expression | TSESTree.PrivateIdentifier): string | _ {
2136
if (AST.isTsOnlyExpression(node)) {
2237
return getName(node.expression);
@@ -179,7 +194,7 @@ export default createRule<[], MessageID>({
179194
return;
180195
}
181196
const hasState = node.id.properties.some((prop) => {
182-
if (prop.type === T.Property && AST.isKeyLiteralLike(prop, prop.key)) {
197+
if (prop.type === T.Property && isKeyLiteral(prop, prop.key)) {
183198
return getName(prop.key) === "state";
184199
}
185200
return false;

packages/plugins/eslint-plugin-react-x/src/rules/no-use-context.ts

+24-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import { isReactHookCall, isReactHookCallWithNameAlias } from "@eslint-react/core";
2-
import type { RuleFeature } from "@eslint-react/shared";
2+
import type { RuleContext, RuleFeature } from "@eslint-react/shared";
33
import { getSettingsFromContext } from "@eslint-react/shared";
4+
import type { TSESTree } from "@typescript-eslint/types";
45
import { AST_NODE_TYPES as T } from "@typescript-eslint/types";
56
import { compare } from "compare-versions";
67
import type { CamelCase } from "string-ts";
78
import { isMatching } from "ts-pattern";
89

9-
import { createRule, getAssociatedTokens } from "../utils";
10+
import { createRule } from "../utils";
1011

1112
export const RULE_NAME = "no-use-context";
1213

@@ -102,3 +103,24 @@ export default createRule<[], MessageID>({
102103
},
103104
defaultOptions: [],
104105
});
106+
107+
function getAssociatedTokens(context: RuleContext, node: TSESTree.Node) {
108+
{
109+
const tokenBefore = context.sourceCode.getTokenBefore(node);
110+
const tokenAfter = context.sourceCode.getTokenAfter(node);
111+
const tokens = [];
112+
113+
// If this is not the only entry, then the line above this one
114+
// will become the last line, and should not have a trailing comma.
115+
if (tokenAfter?.value !== "," && tokenBefore?.value === ",") {
116+
tokens.push(tokenBefore);
117+
}
118+
119+
// If this is not the last entry, then we need to remove the comma from this line.
120+
if (tokenAfter?.value === ",") {
121+
tokens.push(tokenAfter);
122+
}
123+
124+
return tokens;
125+
}
126+
}

packages/plugins/eslint-plugin-react-x/src/utils/get-associated-tokens.ts

-26
This file was deleted.
Original file line numberDiff line numberDiff line change
@@ -1,2 +1 @@
11
export * from "./create-rule";
2-
export * from "./get-associated-tokens";

packages/utilities/ast/src/index.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,13 @@ export * from "./get-nested-expressions";
88
export * from "./get-nested-identifiers";
99
export * from "./get-nested-return-statements";
1010
export * from "./get-top-level-identifier";
11-
export * from "./is";
1211
export * from "./is-empty-function";
13-
export * from "./is-key-literal";
1412
export * from "./is-kind-of-literal";
1513
export * from "./is-map-call";
1614
export * from "./is-multi-line";
1715
export * from "./is-node-equal";
1816
export * from "./is-this-expression";
17+
export * from "./is";
1918
export * from "./to-readable-node-name";
2019
export * from "./to-readable-node-type";
21-
export type * from "./types";
20+
export * from "./types";

packages/utilities/ast/src/is-key-literal.ts

-15
This file was deleted.

0 commit comments

Comments
 (0)