Skip to content

Commit

Permalink
feat: add optional modifier in sort-classes rule
Browse files Browse the repository at this point in the history
  • Loading branch information
hugop95 committed Aug 21, 2024
1 parent 0086427 commit 27fa7e8
Show file tree
Hide file tree
Showing 3 changed files with 158 additions and 9 deletions.
19 changes: 14 additions & 5 deletions docs/content/rules/sort-classes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -223,18 +223,27 @@ Predefined groups are characterized by a single selector and potentially multipl
- Modifiers: `protected`, `private`, `public`.
- Example: `protected-constructor`, `private-constructor`, `public-constructor` or `constructor`.

#### Methods and accessors
- Method selectors: `get-method`, `set-method`, `method`.
- Accessors selector: `accessor-property`.
- Modifiers: `static`, `abstract`, `decorated`, `override`, `protected`, `private`, `public`.
#### Methods
- Selectors: `get-method`, `set-method`, `method`.
- Modifiers: `static`, `abstract`, `decorated`, `override`, `protected`, `private`, `public`, `optional`.
- Example: `private-static-accessor-property`, `protected-abstract-override-method` or `static-get-method`.

The `optional` modifier is incompatible with the `get-method` and `set-method` selectors.

The `abstract` modifier is incompatible with the `static`, `private` and `decorated` modifiers.

`constructor`, `get-method` and `set-method` elements will also be matched as `method`.

#### Accessors
- Selector: `accessor-property`.
- Modifiers: `static`, `abstract`, `decorated`, `override`, `protected`, `private`, `public`.
- Example: `private-static-accessor-property`, `protected-abstract-override-method` or `static-get-method`.

The `abstract` modifier is incompatible with the `static`, `private` and `decorated` modifiers.

#### Properties
- Selectors: `function-property`, `property`.
- Modifiers: `static`, `declare`, `abstract`, `decorated`, `override`, `readonly`, `protected`, `private`, `public`.
- Modifiers: `static`, `declare`, `abstract`, `decorated`, `override`, `readonly`, `protected`, `private`, `public`, `optional`.
- Example: `readonly-decorated-property`.

The `abstract` modifier is incompatible with the `static`, `private` and `decorated` modifiers.
Expand Down
22 changes: 18 additions & 4 deletions rules/sort-classes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,12 @@ type OverrideModifier = 'override'
type ReadonlyModifier = 'readonly'
type DecoratedModifier = 'decorated'
type DeclareModifier = 'declare'
type OptionalModifier = 'optional'
export type Modifier =
| ProtectedModifier
| DecoratedModifier
| AbstractModifier
| OptionalModifier
| OverrideModifier
| ReadonlyModifier
| PrivateModifier
Expand Down Expand Up @@ -72,6 +74,7 @@ type PublicOrProtectedOrPrivateModifierPrefix = WithDashSuffixOrEmpty<
>

type OverrideModifierPrefix = WithDashSuffixOrEmpty<OverrideModifier>
type OptionalModifierPrefix = WithDashSuffixOrEmpty<OptionalModifier>
type ReadonlyModifierPrefix = WithDashSuffixOrEmpty<ReadonlyModifier>
type DecoratedModifierPrefix = WithDashSuffixOrEmpty<DecoratedModifier>
type DeclareModifierPrefix = WithDashSuffixOrEmpty<DeclareModifier>
Expand All @@ -92,10 +95,12 @@ type ConstructorGroup =
type FunctionPropertyGroup =
`${PublicOrProtectedOrPrivateModifierPrefix}${StaticModifierPrefix}${OverrideModifierPrefix}${ReadonlyModifierPrefix}${DecoratedModifierPrefix}${FunctionPropertySelector}`
type DeclarePropertyGroup =
`${DeclareModifierPrefix}${PublicOrProtectedOrPrivateModifierPrefix}${StaticOrAbstractModifierPrefix}${ReadonlyModifierPrefix}${PropertySelector}`
`${DeclareModifierPrefix}${PublicOrProtectedOrPrivateModifierPrefix}${StaticOrAbstractModifierPrefix}${ReadonlyModifierPrefix}${OptionalModifierPrefix}${PropertySelector}`
type NonDeclarePropertyGroup =
`${PublicOrProtectedOrPrivateModifierPrefix}${StaticOrAbstractModifierPrefix}${OverrideModifierPrefix}${ReadonlyModifierPrefix}${DecoratedModifierPrefix}${PropertySelector}`
type MethodOrGetMethodOrSetMethodGroup =
`${PublicOrProtectedOrPrivateModifierPrefix}${StaticOrAbstractModifierPrefix}${OverrideModifierPrefix}${ReadonlyModifierPrefix}${DecoratedModifierPrefix}${OptionalModifierPrefix}${PropertySelector}`
type MethodGroup =
`${PublicOrProtectedOrPrivateModifierPrefix}${StaticOrAbstractModifierPrefix}${OverrideModifierPrefix}${DecoratedModifierPrefix}${OptionalModifierPrefix}${MethodSelector}`
type GetMethodOrSetMethodGroup =
`${PublicOrProtectedOrPrivateModifierPrefix}${StaticOrAbstractModifierPrefix}${OverrideModifierPrefix}${DecoratedModifierPrefix}${MethodOrGetMethodOrSetMethodSelector}`
type AccessorPropertyGroup =
`${PublicOrProtectedOrPrivateModifierPrefix}${StaticOrAbstractModifierPrefix}${OverrideModifierPrefix}${DecoratedModifierPrefix}${AccessorPropertySelector}`
Expand All @@ -109,14 +114,15 @@ type StaticBlockGroup = `${StaticBlockSelector}`
* - abstract decorated X
*/
type Group =
| MethodOrGetMethodOrSetMethodGroup
| GetMethodOrSetMethodGroup
| NonDeclarePropertyGroup
| AccessorPropertyGroup
| FunctionPropertyGroup
| DeclarePropertyGroup
| IndexSignatureGroup
| ConstructorGroup
| StaticBlockGroup
| MethodGroup
| 'unknown'
| string

Expand Down Expand Up @@ -398,6 +404,10 @@ export default createEslintRule<Options, MESSAGE_ID>({
modifiers.push('public')
}

if (member.optional) {
modifiers.push('optional')
}

if (member.kind === 'constructor') {
selectors.push('constructor')
}
Expand Down Expand Up @@ -487,6 +497,10 @@ export default createEslintRule<Options, MESSAGE_ID>({
modifiers.push('public')
}

if (member.optional) {
modifiers.push('optional')
}

if (
member.value?.type === 'ArrowFunctionExpression' ||
member.value?.type === 'FunctionExpression'
Expand Down
126 changes: 126 additions & 0 deletions test/sort-classes.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,10 @@ describe(ruleName, () => {
code: dedent`
abstract class Class {
p?(): void;
o?;
static {}
static readonly [key: string]: string;
Expand Down Expand Up @@ -252,6 +256,10 @@ describe(ruleName, () => {
static readonly [key: string]: string;
static {}
o?;
p?(): void;
}
`,
options: [
Expand All @@ -274,10 +282,30 @@ describe(ruleName, () => {
'function-property',
'static-readonly-index-signature',
'static-block',
'public-optional-property',
'public-optional-method',
],
},
],
errors: [
{
messageId: 'unexpectedClassesGroupOrder',
data: {
left: 'p',
leftGroup: 'public-optional-method',
right: 'o',
rightGroup: 'public-optional-property',
},
},
{
messageId: 'unexpectedClassesGroupOrder',
data: {
left: 'o',
leftGroup: 'public-optional-property',
right: 'static',
rightGroup: 'static-block',
},
},
{
messageId: 'unexpectedClassesGroupOrder',
data: {
Expand Down Expand Up @@ -840,6 +868,55 @@ describe(ruleName, () => {
],
},
)

ruleTester.run(
`${ruleName}(${type}): prioritize ${accessibilityModifier} accessibility over optional`,
rule,
{
valid: [],
invalid: [
{
code: dedent`
export class Class {
a: string;
${accessibilityModifier} z?(): string;
}
`,
output: dedent`
export class Class {
${accessibilityModifier} z?(): string;
a: string;
}
`,
options: [
{
...options,
groups: [
`${accessibilityModifier}-method`,
'property',
'optional-method',
],
},
],
errors: [
{
messageId: 'unexpectedClassesGroupOrder',
data: {
left: 'a',
leftGroup: 'property',
right: 'z',
rightGroup: `${accessibilityModifier}-method`,
},
},
],
},
],
},
)
}
})

Expand Down Expand Up @@ -1461,6 +1538,55 @@ describe(ruleName, () => {
],
},
)

ruleTester.run(
`${ruleName}(${type}): prioritize ${accessibilityModifier} accessibility over optional`,
rule,
{
valid: [],
invalid: [
{
code: dedent`
export class Class {
a(): void {}
${accessibilityModifier} z?: string;
}
`,
output: dedent`
export class Class {
${accessibilityModifier} z?: string;
a(): void {}
}
`,
options: [
{
...options,
groups: [
`${accessibilityModifier}-property`,
'method',
'optional-property',
],
},
],
errors: [
{
messageId: 'unexpectedClassesGroupOrder',
data: {
left: 'a',
leftGroup: 'method',
right: 'z',
rightGroup: `${accessibilityModifier}-property`,
},
},
],
},
],
},
)
}
})

Expand Down

0 comments on commit 27fa7e8

Please sign in to comment.