Skip to content

Commit 412d5da

Browse files
authoredSep 9, 2024··
feat: improve dependency detection in sort-objects rule
1 parent e0f375a commit 412d5da

File tree

3 files changed

+771
-408
lines changed

3 files changed

+771
-408
lines changed
 

‎rules/sort-objects.ts

+87-62
Original file line numberDiff line numberDiff line change
@@ -266,6 +266,92 @@ export default createEslintRule<Options, MESSAGE_ID>({
266266
}
267267

268268
let sourceCode = getSourceCode(context)
269+
270+
let extractDependencies = (
271+
init: TSESTree.AssignmentPattern,
272+
): string[] => {
273+
let dependencies: string[] = []
274+
275+
let checkNode = (nodeValue: TSESTree.Node) => {
276+
/**
277+
* No need to check the body of functions and arrow functions
278+
*/
279+
if (
280+
nodeValue.type === 'ArrowFunctionExpression' ||
281+
nodeValue.type === 'FunctionExpression'
282+
) {
283+
return
284+
}
285+
286+
if (nodeValue.type === 'Identifier') {
287+
dependencies.push(nodeValue.name)
288+
}
289+
290+
if (nodeValue.type === 'Property') {
291+
traverseNode(nodeValue.key)
292+
traverseNode(nodeValue.value)
293+
}
294+
295+
if (nodeValue.type === 'ConditionalExpression') {
296+
traverseNode(nodeValue.test)
297+
traverseNode(nodeValue.consequent)
298+
traverseNode(nodeValue.alternate)
299+
}
300+
301+
if (
302+
'expression' in nodeValue &&
303+
typeof nodeValue.expression !== 'boolean'
304+
) {
305+
traverseNode(nodeValue.expression)
306+
}
307+
308+
if ('object' in nodeValue) {
309+
traverseNode(nodeValue.object)
310+
}
311+
312+
if ('callee' in nodeValue) {
313+
traverseNode(nodeValue.callee)
314+
}
315+
316+
if ('left' in nodeValue) {
317+
traverseNode(nodeValue.left)
318+
}
319+
320+
if ('right' in nodeValue) {
321+
traverseNode(nodeValue.right as TSESTree.Node)
322+
}
323+
324+
if ('elements' in nodeValue) {
325+
nodeValue.elements
326+
.filter(currentNode => currentNode !== null)
327+
.forEach(traverseNode)
328+
}
329+
330+
if ('argument' in nodeValue && nodeValue.argument) {
331+
traverseNode(nodeValue.argument)
332+
}
333+
334+
if ('arguments' in nodeValue) {
335+
nodeValue.arguments.forEach(traverseNode)
336+
}
337+
338+
if ('properties' in nodeValue) {
339+
nodeValue.properties.forEach(traverseNode)
340+
}
341+
342+
if ('expressions' in nodeValue) {
343+
nodeValue.expressions.forEach(traverseNode)
344+
}
345+
}
346+
347+
let traverseNode = (nodeValue: TSESTree.Node) => {
348+
checkNode(nodeValue)
349+
}
350+
351+
traverseNode(init)
352+
return dependencies
353+
}
354+
269355
let formatProperties = (
270356
props: (
271357
| TSESTree.ObjectLiteralElement
@@ -323,68 +409,7 @@ export default createEslintRule<Options, MESSAGE_ID>({
323409
}
324410

325411
if (prop.value.type === 'AssignmentPattern') {
326-
let addDependencies = (value: TSESTree.AssignmentPattern) => {
327-
if (value.right.type === 'Identifier') {
328-
dependencies.push(value.right.name)
329-
}
330-
331-
let handleComplexExpression = (
332-
expression:
333-
| TSESTree.ArrowFunctionExpression
334-
| TSESTree.ConditionalExpression
335-
| TSESTree.LogicalExpression
336-
| TSESTree.BinaryExpression
337-
| TSESTree.CallExpression,
338-
) => {
339-
let nodes = []
340-
341-
switch (expression.type) {
342-
case 'ArrowFunctionExpression':
343-
nodes.push(expression.body)
344-
break
345-
346-
case 'ConditionalExpression':
347-
nodes.push(expression.consequent, expression.alternate)
348-
break
349-
350-
case 'LogicalExpression':
351-
case 'BinaryExpression':
352-
nodes.push(expression.left, expression.right)
353-
break
354-
355-
case 'CallExpression':
356-
nodes.push(...expression.arguments)
357-
break
358-
}
359-
360-
nodes.forEach(nestedNode => {
361-
if (nestedNode.type === 'Identifier') {
362-
dependencies.push(nestedNode.name)
363-
}
364-
365-
if (
366-
nestedNode.type === 'BinaryExpression' ||
367-
nestedNode.type === 'ConditionalExpression'
368-
) {
369-
handleComplexExpression(nestedNode)
370-
}
371-
})
372-
}
373-
374-
switch (value.right.type) {
375-
case 'ArrowFunctionExpression':
376-
case 'ConditionalExpression':
377-
case 'LogicalExpression':
378-
case 'BinaryExpression':
379-
case 'CallExpression':
380-
handleComplexExpression(value.right)
381-
break
382-
383-
default:
384-
}
385-
}
386-
387-
addDependencies(prop.value)
412+
dependencies = extractDependencies(prop.value)
388413
}
389414

390415
setCustomGroups(options.customGroups, name)

‎rules/sort-variable-declarations.ts

+5-7
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,7 @@ export default createEslintRule<Options, MESSAGE_ID>({
8080

8181
let sourceCode = getSourceCode(context)
8282

83-
let extractDependencies = (
84-
init: TSESTree.Expression | null,
85-
): string[] => {
86-
if (!init) {
87-
return []
88-
}
83+
let extractDependencies = (init: TSESTree.Expression): string[] => {
8984
let dependencies: string[] = []
9085

9186
let checkNode = (nodeValue: TSESTree.Node) => {
@@ -181,7 +176,10 @@ export default createEslintRule<Options, MESSAGE_ID>({
181176
;({ name } = declaration.id)
182177
}
183178

184-
let dependencies = extractDependencies(declaration.init)
179+
let dependencies: string[] = []
180+
if (declaration.init) {
181+
dependencies = extractDependencies(declaration.init)
182+
}
185183

186184
return {
187185
size: rangeToDiff(declaration.range),

‎test/sort-objects.test.ts

+679-339
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)
Please sign in to comment.