1- import type {
2- SortVariableDeclarationsSortingNode ,
3- Selector ,
4- Options ,
5- } from './sort-variable-declarations/types'
1+ import { AST_NODE_TYPES } from '@typescript-eslint/utils'
2+
3+ import type { MessageId , Options } from './sort-variable-declarations/types'
64
5+ import {
6+ additionalCustomGroupMatchOptionsJsonSchema ,
7+ DEPENDENCY_ORDER_ERROR_ID ,
8+ MISSED_SPACING_ERROR_ID ,
9+ EXTRA_SPACING_ERROR_ID ,
10+ GROUP_ORDER_ERROR_ID ,
11+ ORDER_ERROR_ID ,
12+ } from './sort-variable-declarations/types'
13+ import {
14+ useExperimentalDependencyDetectionJsonSchema ,
15+ buildUseConfigurationIfJsonSchema ,
16+ matchesAstSelectorJsonSchema ,
17+ buildCommonJsonSchemas ,
18+ } from '../utils/json-schemas/common-json-schemas'
719import {
820 DEPENDENCY_ORDER_ERROR ,
921 MISSED_SPACING_ERROR ,
@@ -16,223 +28,28 @@ import {
1628 partitionByNewLineJsonSchema ,
1729} from '../utils/json-schemas/common-partition-json-schemas'
1830import {
19- useExperimentalDependencyDetectionJsonSchema ,
20- buildCommonJsonSchemas ,
21- } from '../utils/json-schemas/common-json-schemas'
22- import { computeDependenciesOutsideFunctionsBySortingNode } from '../utils/compute-dependencies-outside-functions-by-sorting-node'
23- import {
24- additionalCustomGroupMatchOptionsJsonSchema ,
25- allSelectors ,
26- } from './sort-variable-declarations/types'
27- import { populateSortingNodeGroupsWithDependencies } from '../utils/populate-sorting-node-groups-with-dependencies'
28- import { validateNewlinesAndPartitionConfiguration } from '../utils/validate-newlines-and-partition-configuration'
29- import { defaultComparatorByOptionsComputer } from '../utils/compare/default-comparator-by-options-computer'
30- import { buildOptionsByGroupIndexComputer } from '../utils/build-options-by-group-index-computer'
31+ sortVariableDeclaration ,
32+ defaultOptions ,
33+ } from './sort-variable-declarations/sort-variable-declaration'
3134import { buildCommonGroupsJsonSchemas } from '../utils/json-schemas/common-groups-json-schemas'
32- import { validateCustomSortConfiguration } from '../utils/validate-custom-sort-configuration'
33- import { computeDependencies } from './sort-variable-declarations/compute-dependencies'
34- import { validateGroupsConfiguration } from '../utils/validate-groups-configuration'
35- import { computeNodeName } from './sort-variable-declarations/compute-node-name'
36- import { generatePredefinedGroups } from '../utils/generate-predefined-groups'
37- import { sortNodesByDependencies } from '../utils/sort-nodes-by-dependencies'
38- import { getEslintDisabledLines } from '../utils/get-eslint-disabled-lines'
39- import { doesCustomGroupMatch } from '../utils/does-custom-group-match'
40- import { isNodeEslintDisabled } from '../utils/is-node-eslint-disabled'
41- import { sortNodesByGroups } from '../utils/sort-nodes-by-groups'
35+ import { buildAstListeners } from '../utils/build-ast-listeners'
4236import { createEslintRule } from '../utils/create-eslint-rule'
43- import { reportAllErrors } from '../utils/report-all-errors'
44- import { shouldPartition } from '../utils/should-partition'
45- import { computeGroup } from '../utils/compute-group'
46- import { rangeToDiff } from '../utils/range-to-diff'
47- import { getSettings } from '../utils/get-settings'
48- import { isSortable } from '../utils/is-sortable'
49- import { complete } from '../utils/complete'
50-
51- /**
52- * Cache computed groups by modifiers and selectors for performance.
53- */
54- let cachedGroupsByModifiersAndSelectors = new Map < string , string [ ] > ( )
55-
56- const ORDER_ERROR_ID = 'unexpectedVariableDeclarationsOrder'
57- const GROUP_ORDER_ERROR_ID = 'unexpectedVariableDeclarationsGroupOrder'
58- const EXTRA_SPACING_ERROR_ID = 'extraSpacingBetweenVariableDeclarationsMembers'
59- const MISSED_SPACING_ERROR_ID =
60- 'missedSpacingBetweenVariableDeclarationsMembers'
61- const DEPENDENCY_ORDER_ERROR_ID =
62- 'unexpectedVariableDeclarationsDependencyOrder'
63-
64- type MessageId =
65- | typeof DEPENDENCY_ORDER_ERROR_ID
66- | typeof MISSED_SPACING_ERROR_ID
67- | typeof EXTRA_SPACING_ERROR_ID
68- | typeof GROUP_ORDER_ERROR_ID
69- | typeof ORDER_ERROR_ID
70-
71- let defaultOptions : Required < Options [ number ] > = {
72- useExperimentalDependencyDetection : true ,
73- fallbackSort : { type : 'unsorted' } ,
74- newlinesInside : 'newlinesBetween' ,
75- specialCharacters : 'keep' ,
76- partitionByNewLine : false ,
77- partitionByComment : false ,
78- newlinesBetween : 'ignore' ,
79- type : 'alphabetical' ,
80- customGroups : [ ] ,
81- ignoreCase : true ,
82- locales : 'en-US' ,
83- alphabet : '' ,
84- order : 'asc' ,
85- groups : [ ] ,
86- }
8737
8838export default createEslintRule < Options , MessageId > ( {
89- create : context => ( {
90- VariableDeclaration : variableDeclaration => {
91- if ( ! isSortable ( variableDeclaration . declarations ) ) {
92- return
93- }
94-
95- let settings = getSettings ( context . settings )
96- let options = complete ( context . options . at ( 0 ) , settings , defaultOptions )
97-
98- validateCustomSortConfiguration ( options )
99- validateNewlinesAndPartitionConfiguration ( options )
100- validateGroupsConfiguration ( {
101- selectors : allSelectors ,
102- modifiers : [ ] ,
103- options,
104- } )
105-
106- let { sourceCode, id } = context
107- let eslintDisabledLines = getEslintDisabledLines ( {
108- ruleName : id ,
109- sourceCode,
110- } )
111- let optionsByGroupIndexComputer =
112- buildOptionsByGroupIndexComputer ( options )
113-
114- let sortingNodeGroups = variableDeclaration . declarations . reduce (
115- ( accumulator : SortVariableDeclarationsSortingNode [ ] [ ] , declaration ) => {
116- let name = computeNodeName ( {
117- node : declaration ,
118- sourceCode,
119- } )
120-
121- let selector : Selector =
122- declaration . init ? 'initialized' : 'uninitialized'
123-
124- let predefinedGroups = generatePredefinedGroups ( {
125- cache : cachedGroupsByModifiersAndSelectors ,
126- selectors : [ selector ] ,
127- modifiers : [ ] ,
128- } )
129-
130- let lastSortingNode = accumulator . at ( - 1 ) ?. at ( - 1 )
131- let sortingNode : Omit <
132- SortVariableDeclarationsSortingNode ,
133- 'partitionId'
134- > = {
135- group : computeGroup ( {
136- customGroupMatcher : customGroup =>
137- doesCustomGroupMatch ( {
138- selectors : [ selector ] ,
139- elementName : name ,
140- modifiers : [ ] ,
141- customGroup,
142- } ) ,
143- predefinedGroups,
144- options,
145- } ) ,
146- dependencies :
147- options . useExperimentalDependencyDetection ?
148- [ ]
149- : computeDependencies ( declaration ) ,
150- isEslintDisabled : isNodeEslintDisabled (
151- declaration ,
152- eslintDisabledLines ,
153- ) ,
154- size : rangeToDiff ( declaration , sourceCode ) ,
155- dependencyNames : [ name ] ,
156- node : declaration ,
157- name,
158- }
159-
160- if (
161- shouldPartition ( {
162- lastSortingNode,
163- sortingNode,
164- sourceCode,
165- options,
166- } )
167- ) {
168- accumulator . push ( [ ] )
169- }
170-
171- accumulator . at ( - 1 ) ?. push ( {
172- ...sortingNode ,
173- partitionId : accumulator . length ,
174- } )
175-
176- return accumulator
177- } ,
178- [ [ ] ] ,
179- )
180-
181- if ( options . useExperimentalDependencyDetection ) {
182- let dependenciesBySortingNode =
183- computeDependenciesOutsideFunctionsBySortingNode ( {
184- sortingNodes : sortingNodeGroups . flat ( ) ,
185- sourceCode,
186- } )
187- sortingNodeGroups = populateSortingNodeGroupsWithDependencies ( {
188- dependenciesBySortingNode,
189- sortingNodeGroups,
190- } )
191- }
192- let sortingNodes = sortingNodeGroups . flat ( )
193-
194- reportAllErrors < MessageId > ( {
195- availableMessageIds : {
196- missedSpacingBetweenMembers : MISSED_SPACING_ERROR_ID ,
197- unexpectedDependencyOrder : DEPENDENCY_ORDER_ERROR_ID ,
198- extraSpacingBetweenMembers : EXTRA_SPACING_ERROR_ID ,
199- unexpectedGroupOrder : GROUP_ORDER_ERROR_ID ,
200- unexpectedOrder : ORDER_ERROR_ID ,
201- } ,
202- sortNodesExcludingEslintDisabled,
203- nodes : sortingNodes ,
204- options,
205- context,
206- } )
207-
208- function sortNodesExcludingEslintDisabled (
209- ignoreEslintDisabledNodes : boolean ,
210- ) : SortVariableDeclarationsSortingNode [ ] {
211- let nodesSortedByGroups = sortingNodeGroups . flatMap ( sortingNodeGroup =>
212- sortNodesByGroups ( {
213- comparatorByOptionsComputer : defaultComparatorByOptionsComputer ,
214- optionsByGroupIndexComputer,
215- ignoreEslintDisabledNodes,
216- nodes : sortingNodeGroup ,
217- groups : options . groups ,
218- } ) ,
219- )
220-
221- return sortNodesByDependencies ( nodesSortedByGroups , {
222- ignoreEslintDisabledNodes,
223- } )
224- }
225- } ,
226- } ) ,
22739 meta : {
228- schema : [
229- {
40+ schema : {
41+ items : {
23042 properties : {
23143 ...buildCommonJsonSchemas ( ) ,
23244 ...buildCommonGroupsJsonSchemas ( {
23345 additionalCustomGroupMatchProperties :
23446 additionalCustomGroupMatchOptionsJsonSchema ,
23547 } ) ,
48+ useConfigurationIf : buildUseConfigurationIfJsonSchema ( {
49+ additionalProperties : {
50+ matchesAstSelector : matchesAstSelectorJsonSchema ,
51+ } ,
52+ } ) ,
23653 useExperimentalDependencyDetection :
23754 useExperimentalDependencyDetectionJsonSchema ,
23855 partitionByComment : partitionByCommentJsonSchema ,
@@ -241,7 +58,9 @@ export default createEslintRule<Options, MessageId>({
24158 additionalProperties : false ,
24259 type : 'object' ,
24360 } ,
244- ] ,
61+ uniqueItems : true ,
62+ type : 'array' ,
63+ } ,
24564 messages : {
24665 [ DEPENDENCY_ORDER_ERROR_ID ] : DEPENDENCY_ORDER_ERROR ,
24766 [ MISSED_SPACING_ERROR_ID ] : MISSED_SPACING_ERROR ,
@@ -257,6 +76,12 @@ export default createEslintRule<Options, MessageId>({
25776 type : 'suggestion' ,
25877 fixable : 'code' ,
25978 } ,
79+ create : context =>
80+ buildAstListeners ( {
81+ nodeTypes : [ AST_NODE_TYPES . VariableDeclaration ] ,
82+ sorter : sortVariableDeclaration ,
83+ context,
84+ } ) ,
26085 name : 'sort-variable-declarations' ,
26186 defaultOptions : [ defaultOptions ] ,
26287} )
0 commit comments