Skip to content

Commit baa701d

Browse files
authored
feat: use dynamic group generation in sort-classes
1 parent c30c8ee commit baa701d

8 files changed

+1618
-174
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ dist/
88
# Editor
99
.vscode/
1010
.vim/
11+
.idea/
1112

1213
# Astro
1314
.astro/

docs/content/rules/sort-classes.mdx

+149-80
Original file line numberDiff line numberDiff line change
@@ -215,146 +215,215 @@ Allows you to use comments to separate the class members into logical groups. Th
215215

216216
Allows you to specify a list of class member groups for sorting. Groups help organize class members into categories, prioritizing them during sorting. Multiple groups can be combined to achieve the desired sorting order.
217217

218-
There are a lot of predefined groups.
219-
220-
Predefined Groups:
221-
222-
- `'index-signature'` — Index signatures, which define the types of keys and values in an object.
223-
- `'protected-decorated-accessor-property'` — Protected accessor properties with decorators.
224-
- `'private-decorated-accessor-property'` — Private accessor properties with decorators.
225-
- `'decorated-accessor-property'` — Accessor properties with decorators.
226-
- `'protected-decorated-property'` — Protected properties with decorators.
227-
- `'private-decorated-property'` — Private properties with decorators.
228-
- `'decorated-property'` — Properties with decorators.
229-
- `'protected-property'` — Protected properties.
230-
- `'private-property'` — Private properties.
231-
- `'static-property'` — Static properties.
232-
- `'property'` — Regular properties.
233-
- `'constructor'` — Constructor method.
234-
- `'protected-method'` — Protected methods.
235-
- `'private-method'` — Private methods.
236-
- `'static-protected-method'` — Static protected methods.
237-
- `'static-private-method'` — Static private methods.
238-
- `'static-method'` — Static methods.
239-
- `'decorated-method'` — Methods with decorators.
240-
- `'decorated-get-method'` — Getter methods with decorators.
241-
- `'decorated-set-method'` — Setter methods with decorators.
242-
- `'get-method'` — Getter methods.
243-
- `'set-method'` — Setter methods.
244-
- `'method'` — Regular methods.
245-
- `'unknown'` — Members that don’t fit into any other group.
218+
Predefined groups are characterized by a single selector and potentially multiple modifiers. You may enter modifiers in any order, but the selector must always come at the end.
246219

247-
Example:
220+
#### Constructors
221+
- Selector: `constructor`.
222+
- Modifiers: `protected`, `private`, `public`.
223+
- Example: `protected-constructor`, `private-constructor`, `public-constructor` or `constructor`.
224+
225+
#### Methods and accessors
226+
- Method selectors: `get-method`, `set-method`, `method`.
227+
- Accessors selector: `accessor-property`.
228+
- Modifiers: `static`, `abstract`, `decorated`, `override`, `protected`, `private`, `public`.
229+
- Example: `private-static-accessor-property`, `protected-abstract-override-method` or `static-get-method`.
230+
231+
The `abstract` modifier is incompatible with the `static`, `private` and `decorated` modifiers.
232+
`constructor`, `get-method` and `set-method` elements will also be matched as `method`.
233+
234+
#### Properties
235+
- Selector: `property`.
236+
- Modifiers: `static`, `declare`, `abstract`, `decorated`, `override`, `readonly`, `protected`, `private`, `public`.
237+
- Example: `readonly-decorated-property`.
238+
239+
The `abstract` modifier is incompatible with the `static`, `private` and `decorated` modifiers.
240+
The `declare` modifier is incompatible with the `override` and `decorated` modifiers.
241+
242+
#### Index-signatures
243+
- Selector: `index-signature`.
244+
- Modifiers: `static`, `readonly`.
245+
- Example: `static-readonly-index-signature`.
246+
247+
#### Static-blocks
248+
- Selector: `static-block`.
249+
- Modifiers: No modifier available.
250+
- Example: `static-block`.
251+
252+
#### Important notes
253+
254+
##### Scope of the `private` modifier
255+
The `private` modifier will currently match any of the following:
256+
- Elements with the `private` keyword.
257+
- Elements with their name starting with `#`.
258+
259+
##### Scope of the `public` modifier
260+
Elements that are not `protected` nor `private` will be matched with the `public` modifier, even if the keyword is not present.
261+
262+
263+
##### The `unknown` group
264+
Members that don’t fit into any group entered by the user will be placed in the `unknown` group.
265+
266+
##### Behavior when multiple groups match an element
267+
268+
The lists of selectors and modifiers above are both sorted by importance, from most to least important.
269+
In case of multiple groups matching an element, the following rules will be applied:
270+
271+
1. Selector priority: `constructor`, `get-method` and `set-method` groups will always take precedence over `method` groups.
272+
2. If the selector is the same, the group with the most modifiers matching will be selected.
273+
3. If modifiers quantity is the same, order will be chosen based on modifier importance as listed above.
274+
275+
Example 1:
276+
```ts
277+
abstract class Class {
278+
279+
protected abstract get field();
280+
281+
}
282+
```
283+
284+
`field` can be matched by the following groups, from most to least important:
285+
- `abstract-protected-get-method` or `protected-abstract-get-method`.
286+
- `abstract-get-method`.
287+
- `protected-get-method`.
288+
- `get-method`.
289+
- `abstract-protected-method` or `protected-abstract-method`.
290+
- `abstract-method`.
291+
- `protected-method`.
292+
- `method`.
293+
- `unknown`.
294+
295+
Example 2: (The most important group is written in the comments)
248296

249297
```ts
250-
class Example {
298+
abstract class Example extends BaseExample {
299+
251300
// 'index-signature'
252301
[key: string]: any;
253302

254-
// 'protected-decorated-accessor-property'
255-
@SomeDecorator
256-
protected get accessor() {
257-
return this._value;
258-
}
303+
// 'public-static-property'
304+
static instance: Example;
259305

260-
// 'private-decorated-accessor-property'
261-
@SomeDecorator
262-
private get accessor() {
263-
return this._value;
264-
}
306+
// 'declare-protected-static-readonly-property'
307+
declare protected static readonly value: string;
265308

266-
// 'decorated-accessor-property'
309+
// 'protected-abstract-override-readonly-decorated-property'
267310
@SomeDecorator
268-
get accessor() {
269-
return this._value;
270-
}
311+
protected abstract override readonly _value: number;
271312

272-
// 'protected-decorated-property'
273-
@SomeDecorator
274-
protected _value: number;
313+
// 'protected-property'
314+
protected name: string;
275315

276316
// 'private-decorated-property'
277317
@SomeDecorator
278318
private _value: number;
279319

280-
// 'decorated-property'
281-
@SomeDecorator
282-
public value: number;
283-
284-
// 'protected-property'
285-
protected name: string;
286-
287320
// 'private-property'
288321
private name: string;
289322

290-
// 'static-property'
291-
static instance: Example;
292-
293-
// 'property'
323+
// 'public-property'
294324
public description: string;
295325

296-
// 'constructor'
326+
// 'public-decorated-property'
327+
@SomeDecorator
328+
public value: number;
329+
330+
// 'public-constructor'
297331
constructor(value: number) {
298332
this._value = value;
299333
}
300334

301-
// 'protected-method'
302-
protected calculate() {
303-
return this._value * 2;
304-
}
305-
306-
// 'private-method'
307-
private calculate() {
308-
return this._value * 2;
335+
// 'public-static-method'
336+
static getInstance() {
337+
return this.instance;
309338
}
310339

311-
// 'static-protected-method'
340+
// 'protected-static-method'
312341
protected static initialize() {
313342
this.instance = new Example(0);
314343
}
315344

316-
// 'static-private-method'
345+
// 'private-static-method'
317346
private static initialize() {
318347
this.instance = new Example(0);
319348
}
320349

321-
// 'static-method'
322-
static getInstance() {
323-
return this.instance;
350+
// 'protected-method'
351+
protected calculate() {
352+
return this._value * 2;
353+
}
354+
355+
// 'private-method'
356+
private calculate() {
357+
return this._value * 2;
324358
}
325359

326-
// 'decorated-method'
360+
// 'public-decorated-method'
327361
@SomeDecorator
328362
public decoratedMethod() {
329363
return this._value;
330364
}
331365

332-
// 'decorated-get-method'
366+
// 'public-method'
367+
public display() {
368+
console.log(this._value);
369+
}
370+
371+
// 'public-decorated-get-method'
333372
@SomeDecorator
334373
get decoratedValue() {
335374
return this._value;
336375
}
337376

338-
// 'decorated-set-method'
377+
// 'public-decorated-set-method'
339378
@SomeDecorator
340379
set decoratedValue(value: number) {
341380
this._value = value;
342381
}
343382

344-
// 'get-method'
383+
// 'protected-decorated-get-method'
384+
@SomeDecorator
385+
protected get value() {
386+
return this._value;
387+
}
388+
389+
// 'private-decorated-get-method'
390+
@SomeDecorator
391+
private get value() {
392+
return this._value;
393+
}
394+
395+
// 'public-decorated-get-method'
396+
@SomeDecorator
397+
get value() {
398+
return this._value;
399+
}
400+
401+
// 'public-get-method'
345402
get value() {
346403
return this._value;
347404
}
348405

349-
// 'set-method'
406+
// 'public-set-method'
350407
set value(value: number) {
351408
this._value = value;
352409
}
353410

354-
// 'method'
355-
public display() {
356-
console.log(this._value);
411+
// 'protected-decorated-accessor-property'
412+
@SomeDecorator
413+
protected accessor _value: number;
414+
415+
// 'private-decorated-accessor-property'
416+
@SomeDecorator
417+
private accessor _value: number;
418+
419+
// 'static-block'
420+
static {
421+
console.log("I am a static block");
357422
}
423+
424+
// 'public-decorated-accessor-property'
425+
@SomeDecorator
426+
public accessor value: number;
358427
}
359428
```
360429

eslint.config.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,6 @@ module.exports = [
2222
rules: {
2323
'perfectionist/sort-objects': 'off',
2424
},
25-
files: ['**/test/*', '**/rules/*'],
25+
files: ['**/test/**', '**/rules/**'],
2626
},
2727
]

0 commit comments

Comments
 (0)