Skip to content

Commit 70e1add

Browse files
committed
chore(consistent-selector-style): moved functions into create() and remove RuleGlobals
1 parent 9194000 commit 70e1add

File tree

1 file changed

+128
-144
lines changed

1 file changed

+128
-144
lines changed

packages/eslint-plugin-svelte/src/rules/consistent-selector-style.ts

+128-144
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,6 @@ import type {
99
import { findClassesInAttribute } from '../utils/ast-utils.js';
1010
import { getSourceCode } from '../utils/compat.js';
1111
import { createRule } from '../utils/index.js';
12-
import type { RuleContext, SourceCode } from '../types.js';
13-
14-
interface RuleGlobals {
15-
checkGlobal: boolean;
16-
style: string[];
17-
classSelections: Map<string, AST.SvelteHTMLElement[]>;
18-
idSelections: Map<string, AST.SvelteHTMLElement[]>;
19-
typeSelections: Map<string, AST.SvelteHTMLElement[]>;
20-
context: RuleContext;
21-
getStyleSelectorAST: NonNullable<SourceCode['parserServices']['getStyleSelectorAST']>;
22-
styleSelectorNodeLoc: NonNullable<SourceCode['parserServices']['styleSelectorNodeLoc']>;
23-
}
2412

2513
export default createRule('consistent-selector-style', {
2614
meta: {
@@ -61,9 +49,15 @@ export default createRule('consistent-selector-style', {
6149
},
6250
create(context) {
6351
const sourceCode = getSourceCode(context);
64-
if (!sourceCode.parserServices.isSvelte) {
52+
if (
53+
!sourceCode.parserServices.isSvelte ||
54+
sourceCode.parserServices.getStyleSelectorAST === undefined ||
55+
sourceCode.parserServices.styleSelectorNodeLoc === undefined
56+
) {
6557
return {};
6658
}
59+
const getStyleSelectorAST = sourceCode.parserServices.getStyleSelectorAST;
60+
const styleSelectorNodeLoc = sourceCode.parserServices.styleSelectorNodeLoc;
6761

6862
const checkGlobal = context.options[0]?.checkGlobal ?? false;
6963
const style = context.options[0]?.style ?? ['type', 'id', 'class'];
@@ -72,6 +66,123 @@ export default createRule('consistent-selector-style', {
7266
const idSelections: Map<string, AST.SvelteHTMLElement[]> = new Map();
7367
const typeSelections: Map<string, AST.SvelteHTMLElement[]> = new Map();
7468

69+
/**
70+
* Checks selectors in a given PostCSS node
71+
*/
72+
function checkSelectorsInPostCSSNode(node: AnyNode): void {
73+
if (node.type === 'rule') {
74+
checkSelector(getStyleSelectorAST(node));
75+
}
76+
if (
77+
(node.type === 'root' ||
78+
(node.type === 'rule' && (node.selector !== ':global' || checkGlobal)) ||
79+
node.type === 'atrule') &&
80+
node.nodes !== undefined
81+
) {
82+
node.nodes.flatMap((node) => checkSelectorsInPostCSSNode(node));
83+
}
84+
}
85+
86+
/**
87+
* Checks an individual selector
88+
*/
89+
function checkSelector(node: SelectorNode): void {
90+
if (node.type === 'class') {
91+
checkClassSelector(node);
92+
}
93+
if (node.type === 'id') {
94+
checkIdSelector(node);
95+
}
96+
if (node.type === 'tag') {
97+
checkTypeSelector(node);
98+
}
99+
if (
100+
(node.type === 'pseudo' && (node.value !== ':global' || checkGlobal)) ||
101+
node.type === 'root' ||
102+
node.type === 'selector'
103+
) {
104+
node.nodes.flatMap((node) => checkSelector(node));
105+
}
106+
}
107+
108+
/**
109+
* Checks a class selector
110+
*/
111+
function checkClassSelector(node: SelectorClass): void {
112+
const selection = classSelections.get(node.value) ?? [];
113+
for (const styleValue of style) {
114+
if (styleValue === 'class') {
115+
return;
116+
}
117+
if (styleValue === 'id' && canUseIdSelector(selection)) {
118+
context.report({
119+
messageId: 'classShouldBeId',
120+
loc: styleSelectorNodeLoc(node) as AST.SourceLocation
121+
});
122+
return;
123+
}
124+
if (styleValue === 'type' && canUseTypeSelector(selection, typeSelections)) {
125+
context.report({
126+
messageId: 'classShouldBeType',
127+
loc: styleSelectorNodeLoc(node) as AST.SourceLocation
128+
});
129+
return;
130+
}
131+
}
132+
}
133+
134+
/**
135+
* Checks an ID selector
136+
*/
137+
function checkIdSelector(node: SelectorIdentifier): void {
138+
const selection = idSelections.get(node.value) ?? [];
139+
for (const styleValue of style) {
140+
if (styleValue === 'class') {
141+
context.report({
142+
messageId: 'idShouldBeClass',
143+
loc: styleSelectorNodeLoc(node) as AST.SourceLocation
144+
});
145+
return;
146+
}
147+
if (styleValue === 'id') {
148+
return;
149+
}
150+
if (styleValue === 'type' && canUseTypeSelector(selection, typeSelections)) {
151+
context.report({
152+
messageId: 'idShouldBeType',
153+
loc: styleSelectorNodeLoc(node) as AST.SourceLocation
154+
});
155+
return;
156+
}
157+
}
158+
}
159+
160+
/**
161+
* Checks a type selector
162+
*/
163+
function checkTypeSelector(node: SelectorTag): void {
164+
const selection = typeSelections.get(node.value) ?? [];
165+
for (const styleValue of style) {
166+
if (styleValue === 'class') {
167+
context.report({
168+
messageId: 'typeShouldBeClass',
169+
loc: styleSelectorNodeLoc(node) as AST.SourceLocation
170+
});
171+
return;
172+
}
173+
if (styleValue === 'id' && canUseIdSelector(selection)) {
174+
context.report({
175+
messageId: 'typeShouldBeId',
176+
loc: styleSelectorNodeLoc(node) as AST.SourceLocation
177+
});
178+
return;
179+
}
180+
if (styleValue === 'type') {
181+
return;
182+
}
183+
}
184+
}
185+
75186
return {
76187
SvelteElement(node) {
77188
if (node.kind !== 'html') {
@@ -97,21 +208,11 @@ export default createRule('consistent-selector-style', {
97208
const styleContext = sourceCode.parserServices.getStyleContext!();
98209
if (
99210
styleContext.status !== 'success' ||
100-
sourceCode.parserServices.getStyleSelectorAST === undefined ||
101-
sourceCode.parserServices.styleSelectorNodeLoc === undefined
211+
sourceCode.parserServices.getStyleSelectorAST === undefined
102212
) {
103213
return;
104214
}
105-
checkSelectorsInPostCSSNode(styleContext.sourceAst, {
106-
checkGlobal,
107-
style,
108-
classSelections,
109-
idSelections,
110-
typeSelections,
111-
context,
112-
getStyleSelectorAST: sourceCode.parserServices.getStyleSelectorAST,
113-
styleSelectorNodeLoc: sourceCode.parserServices.styleSelectorNodeLoc
114-
});
215+
checkSelectorsInPostCSSNode(styleContext.sourceAst);
115216
}
116217
};
117218
}
@@ -128,134 +229,17 @@ function addToArrayMap(
128229
map.set(key, (map.get(key) ?? []).concat(value));
129230
}
130231

131-
/**
132-
* Checks selectors in a given PostCSS node
133-
*/
134-
function checkSelectorsInPostCSSNode(node: AnyNode, ruleGlobals: RuleGlobals): void {
135-
if (node.type === 'rule') {
136-
checkSelector(ruleGlobals.getStyleSelectorAST(node), ruleGlobals);
137-
}
138-
if (
139-
(node.type === 'root' ||
140-
(node.type === 'rule' && (node.selector !== ':global' || ruleGlobals.checkGlobal)) ||
141-
node.type === 'atrule') &&
142-
node.nodes !== undefined
143-
) {
144-
node.nodes.flatMap((node) => checkSelectorsInPostCSSNode(node, ruleGlobals));
145-
}
146-
}
147-
148-
/**
149-
* Checks an individual selector
150-
*/
151-
function checkSelector(node: SelectorNode, ruleGlobals: RuleGlobals): void {
152-
if (node.type === 'class') {
153-
checkClassSelector(node, ruleGlobals);
154-
}
155-
if (node.type === 'id') {
156-
checkIdSelector(node, ruleGlobals);
157-
}
158-
if (node.type === 'tag') {
159-
checkTypeSelector(node, ruleGlobals);
160-
}
161-
if (
162-
(node.type === 'pseudo' && (node.value !== ':global' || ruleGlobals.checkGlobal)) ||
163-
node.type === 'root' ||
164-
node.type === 'selector'
165-
) {
166-
node.nodes.flatMap((node) => checkSelector(node, ruleGlobals));
167-
}
168-
}
169-
170-
/**
171-
* Checks a class selector
172-
*/
173-
function checkClassSelector(node: SelectorClass, ruleGlobals: RuleGlobals): void {
174-
const selection = ruleGlobals.classSelections.get(node.value) ?? [];
175-
for (const styleValue of ruleGlobals.style) {
176-
if (styleValue === 'class') {
177-
return;
178-
}
179-
if (styleValue === 'id' && couldBeId(selection)) {
180-
ruleGlobals.context.report({
181-
messageId: 'classShouldBeId',
182-
loc: ruleGlobals.styleSelectorNodeLoc(node) as AST.SourceLocation
183-
});
184-
return;
185-
}
186-
if (styleValue === 'type' && couldBeType(selection, ruleGlobals.typeSelections)) {
187-
ruleGlobals.context.report({
188-
messageId: 'classShouldBeType',
189-
loc: ruleGlobals.styleSelectorNodeLoc(node) as AST.SourceLocation
190-
});
191-
return;
192-
}
193-
}
194-
}
195-
196-
/**
197-
* Checks an ID selector
198-
*/
199-
function checkIdSelector(node: SelectorIdentifier, ruleGlobals: RuleGlobals): void {
200-
const selection = ruleGlobals.idSelections.get(node.value) ?? [];
201-
for (const styleValue of ruleGlobals.style) {
202-
if (styleValue === 'class') {
203-
ruleGlobals.context.report({
204-
messageId: 'idShouldBeClass',
205-
loc: ruleGlobals.styleSelectorNodeLoc(node) as AST.SourceLocation
206-
});
207-
return;
208-
}
209-
if (styleValue === 'id') {
210-
return;
211-
}
212-
if (styleValue === 'type' && couldBeType(selection, ruleGlobals.typeSelections)) {
213-
ruleGlobals.context.report({
214-
messageId: 'idShouldBeType',
215-
loc: ruleGlobals.styleSelectorNodeLoc(node) as AST.SourceLocation
216-
});
217-
return;
218-
}
219-
}
220-
}
221-
222-
/**
223-
* Checks a type selector
224-
*/
225-
function checkTypeSelector(node: SelectorTag, ruleGlobals: RuleGlobals): void {
226-
const selection = ruleGlobals.typeSelections.get(node.value) ?? [];
227-
for (const styleValue of ruleGlobals.style) {
228-
if (styleValue === 'class') {
229-
ruleGlobals.context.report({
230-
messageId: 'typeShouldBeClass',
231-
loc: ruleGlobals.styleSelectorNodeLoc(node) as AST.SourceLocation
232-
});
233-
return;
234-
}
235-
if (styleValue === 'id' && couldBeId(selection)) {
236-
ruleGlobals.context.report({
237-
messageId: 'typeShouldBeId',
238-
loc: ruleGlobals.styleSelectorNodeLoc(node) as AST.SourceLocation
239-
});
240-
return;
241-
}
242-
if (styleValue === 'type') {
243-
return;
244-
}
245-
}
246-
}
247-
248232
/**
249233
* Checks whether a given selection could be obtained using an ID selector
250234
*/
251-
function couldBeId(selection: AST.SvelteHTMLElement[]): boolean {
235+
function canUseIdSelector(selection: AST.SvelteHTMLElement[]): boolean {
252236
return selection.length <= 1;
253237
}
254238

255239
/**
256240
* Checks whether a given selection could be obtained using a type selector
257241
*/
258-
function couldBeType(
242+
function canUseTypeSelector(
259243
selection: AST.SvelteHTMLElement[],
260244
typeSelections: Map<string, AST.SvelteHTMLElement[]>
261245
): boolean {

0 commit comments

Comments
 (0)