eslint-plugin-perfectionist
eslint-plugin-perfectionist copied to clipboard
Feature: `sort-classes` Improved custom group system
What rule do you want to change?
sort-classes
Describe the problem
The objective is to extend the custom grouping system of the sort-classes
rule in order to respond to the following points
- Extend custom group definitions to more than just pattern matching the name of an element. (see issue #165).
- Allow users to explicitly define a custom group priority over other custom groups.
- Allow users to override official groups priorities if they want.
For the sake of simplicity, I suppose that we are adding a advancedCustomGroups
option to the list of existing options for this rule, but nothing prevents from using the existing customGroups
option as well.
advancedCustomGroups
could be an array
of AdvancedCustomGroup
, which follows the following interface:
interface SortClassesAdvancedCustomGroup {
decoratorNamePattern?: string
elementNamePattern?: string
valueTypePattern?: string
typeDeclarationPattern?: string
modifiers?: string[]
groupName: string
selector: string
}
This interface is easily extensible if additional features need to be added later on.
-
groupName
: The group's name. Today incustomGroups
, this is one key of the object. -
selector
: Filter on theselector
of the element. -
modifiers
: Filter on themodifiers
of the element. (All the modifiers of the element must be present in that list) -
elementNamePattern
: If entered, will check that the name of the element matches the pattern entered. Today incustomGroups
, this is the value associated to a key of the object. -
decoratorNamePattern
: If entered, will check that at least onedecorator
matches the pattern entered. (solves #165) -
valueTypePattern
: If entered, will check that the value type of the element matches the pattern entered. (can solve #189 withArrowFunctionExpression
andFunctionExpression
, but I don't see other use cases for that otherwise)
I had in mind to have and
conditions between selector
, modifiers
, decoratorNamePattern
, valueTypePattern
, etc... in order to match an element successfully.
Because advancedCustomGroups
is a list of custom groups and not an object like it is the case with customGroups
, this allows the user to properly define an order in which each advanced custom group should be used. Like customGroups
, advancedCustomGroups
would take priority over official groups if a match is found.
This system also allows users to replicate official groups by only using the selector
and modifiers
options. This allows them to still make sure that some official groups do not get overridden by other advanced custom groups by placing the official group replica first in the advancedCustomGroups
list.
The same groupName
can be used multiple times if needed. Official group names can be used as well.
Code example
Here is the simplified configuration that solves #165:
{
"groups": [
"input",
"output"
],
"advancedCustomGroups": [
{
"groupName": "input",
"decoratorNamePattern": "Input"
},
{
"groupName": "output",
"decoratorNamePattern": "Output"
}
]
}
Here is a simplified configuration that can solve #189:
{
"groups": [
[
"public-method",
"public-function-property"
],
[
"protected-method",
"protected-function-property"
],
[
"private-method",
]
],
"advancedCustomGroups": [
{
"groupName": "public-function-property",
"selector": "property",
"modifiers": ["public"],
"valueTypePattern": "ArrowFunctionExpression"
},
{
"groupName": "public-function-property",
"selector": "property",
"modifiers": ["public"],
"valueTypePattern": "FunctionExpression"
},
{
"groupName": "protected-function-property",
"selector": "property",
"modifiers": ["protected"],
"valueTypePattern": "ArrowFunctionExpression" // Maybe it is possible to group both `FunctionExpression` and `ArrowFunctionExpression` at the same time with `minimatch`, I haven't looked it up.
},
{
"groupName": "protected-function-property",
"selector": "property",
"modifiers": ["protected"],
"valueTypePattern": "FunctionExpression"
},
{
"groupName": "private-method", // Can even directly write `private-method` if we want
"selector": "property",
"modifiers": ["private"],
"valueTypePattern": "ArrowFunctionExpression"
},
{
"groupName": "private-method",
"selector": "property",
"modifiers": ["private"],
"valueTypePattern": "FunctionExpression"
}
]
}
Validations
- [X] Read the docs.
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.