-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: add allowLineSeparatedGroups option to sort-keys (fixes #12759) #13573
Changes from 9 commits
d5cdfb4
33e603c
914a498
03d0ac0
f5520c3
ae37ed8
4a2ee2d
6c0e784
365b75d
9393cfb
137b22c
a648a32
1943dc8
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,38 @@ function getPropertyName(node) { | |
return node.key.name || null; | ||
} | ||
|
||
/** | ||
* Check the Line Separated Groups | ||
* | ||
* - Compare the start line of the current node with the last line of the previous node. | ||
* If the difference between the two values is greater than 0, Not the same group. | ||
* @param {number} thisStartLine is start line of the current node. | ||
* @param {number} prevEndLine is end line of the previous node. | ||
* @param {Array<string>} sourceCodeLines use to check comment between groups. | ||
* @returns {boolean} check group | ||
* @private | ||
*/ | ||
function checkLineSeparatedGroups(thisStartLine, prevEndLine, sourceCodeLines) { | ||
let blockCommentFlag = false; | ||
let commentOffset = 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I used the forEach function to check the comment line, but I'm not sure if it's okay. Is there a better way? |
||
|
||
sourceCodeLines.slice(prevEndLine, thisStartLine).forEach(value => { | ||
if (value.includes("//")) { | ||
commentOffset++; | ||
} else if (value.includes("/*")) { | ||
commentOffset++; | ||
blockCommentFlag = true; | ||
} else if (value.includes("*/")) { | ||
commentOffset++; | ||
blockCommentFlag = false; | ||
} else if (blockCommentFlag) { | ||
commentOffset++; | ||
} | ||
}); | ||
|
||
return !!Math.max(thisStartLine - prevEndLine - commentOffset - 1, 0); | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It has some false positives when we use {
code: `
var obj = {
c: "/*",
a: "*/", // Error. Expected object keys to be in ascending order. 'a' should be before 'c'.
}
`,
options: ["asc", { allowLineSeparatedGroups: true }]
}
🤔 IMO, we can use SourceCode methods for it. there are some methods for treating comment as a getTokenAfter(nodeOrToken, {includeComments: true})
getTokenBefore(nodeOrToken, {includeComments: true}); There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you @yeonjuan !! in this case, var sampleObject1 = {
a: 1,
b: 2,
// comment 1
// comment 2
c: 3
} I used There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this would be a complicated way to find out if there's a blank line. For example, this is a false positive: /* eslint sort-keys: ["error", "asc", { allowLineSeparatedGroups: true }] */
var obj = {
b,
/*
*/ //
a
} comments offset is calculated as Could we maybe simplify this? We could take tokens between properties and then see if there's a blank line between any two successive tokens. More precisely, if we want to check if there's a blank line between two properties (
|
||
|
||
/** | ||
* Functions which check that the given 2 names are in specific order. | ||
* | ||
|
@@ -105,6 +137,10 @@ module.exports = { | |
type: "integer", | ||
minimum: 2, | ||
default: 2 | ||
}, | ||
allowLineSeparatedGroups: { | ||
type: "boolean", | ||
default: false | ||
} | ||
}, | ||
additionalProperties: false | ||
|
@@ -124,18 +160,23 @@ module.exports = { | |
const insensitive = options && options.caseSensitive === false; | ||
const natural = options && options.natural; | ||
const minKeys = options && options.minKeys; | ||
const allowLineSeparatedGroups = options && options.allowLineSeparatedGroups || false; | ||
const isValidOrder = isValidOrders[ | ||
order + (insensitive ? "I" : "") + (natural ? "N" : "") | ||
]; | ||
|
||
// The stack to save the previous property's name for each object literals. | ||
let stack = null; | ||
|
||
// The sourceCode use to check comment between groups | ||
const sourceCode = context.getSourceCode(); | ||
|
||
return { | ||
ObjectExpression(node) { | ||
stack = { | ||
upper: stack, | ||
prevName: null, | ||
prevEndLine: null, | ||
numKeys: node.properties.length | ||
}; | ||
}, | ||
|
@@ -156,13 +197,23 @@ module.exports = { | |
} | ||
|
||
const prevName = stack.prevName; | ||
const prevEndLine = stack.prevEndLine; | ||
const numKeys = stack.numKeys; | ||
const thisName = getPropertyName(node); | ||
const thisStartLine = node.loc.start.line; | ||
const isLineSeparatedGroups = prevEndLine && checkLineSeparatedGroups(thisStartLine, prevEndLine, sourceCode.lines); | ||
|
||
stack.prevEndLine = node.loc.end.line; | ||
|
||
if (thisName !== null) { | ||
stack.prevName = thisName; | ||
} | ||
|
||
if (allowLineSeparatedGroups && isLineSeparatedGroups) { | ||
stack.prevName = null; | ||
return; | ||
} | ||
|
||
if (prevName === null || thisName === null || numKeys < minKeys) { | ||
return; | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.