eslint-plugin-code-style 1.0.39 → 1.0.41
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +22 -0
- package/index.js +95 -17
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -890,44 +890,66 @@ useEffect(() => {}, [
|
|
|
890
890
|
// ✅ Good — consistent formatting
|
|
891
891
|
if (condition) {
|
|
892
892
|
doSomething();
|
|
893
|
+
|
|
894
|
+
doMore();
|
|
893
895
|
}
|
|
894
896
|
|
|
895
897
|
if (condition) {
|
|
896
898
|
doSomething();
|
|
899
|
+
|
|
900
|
+
doMore();
|
|
897
901
|
} else {
|
|
898
902
|
doOther();
|
|
903
|
+
|
|
904
|
+
doAnother();
|
|
899
905
|
}
|
|
900
906
|
|
|
901
907
|
if (conditionA) {
|
|
902
908
|
handleA();
|
|
909
|
+
|
|
910
|
+
processA();
|
|
903
911
|
} else if (conditionB) {
|
|
904
912
|
handleB();
|
|
913
|
+
|
|
914
|
+
processB();
|
|
905
915
|
} else {
|
|
906
916
|
handleDefault();
|
|
917
|
+
|
|
918
|
+
processDefault();
|
|
907
919
|
}
|
|
908
920
|
|
|
909
921
|
// ❌ Bad — brace on new line
|
|
910
922
|
if (condition)
|
|
911
923
|
{
|
|
912
924
|
doSomething();
|
|
925
|
+
|
|
926
|
+
doMore();
|
|
913
927
|
}
|
|
914
928
|
|
|
915
929
|
// ❌ Bad — else on new line
|
|
916
930
|
if (condition) {
|
|
917
931
|
doSomething();
|
|
932
|
+
|
|
933
|
+
doMore();
|
|
918
934
|
}
|
|
919
935
|
else {
|
|
920
936
|
doOther();
|
|
937
|
+
|
|
938
|
+
doAnother();
|
|
921
939
|
}
|
|
922
940
|
|
|
923
941
|
// ❌ Bad — inconsistent formatting
|
|
924
942
|
if (condition)
|
|
925
943
|
{
|
|
926
944
|
doSomething();
|
|
945
|
+
|
|
946
|
+
doMore();
|
|
927
947
|
}
|
|
928
948
|
else
|
|
929
949
|
{
|
|
930
950
|
doOther();
|
|
951
|
+
|
|
952
|
+
doAnother();
|
|
931
953
|
}
|
|
932
954
|
```
|
|
933
955
|
|
package/index.js
CHANGED
|
@@ -2128,21 +2128,28 @@ const hookDepsPerLine = {
|
|
|
2128
2128
|
* opening brace on the same line as the condition and else
|
|
2129
2129
|
* on the same line as the closing brace.
|
|
2130
2130
|
*
|
|
2131
|
+
*
|
|
2131
2132
|
* ✓ Good:
|
|
2132
2133
|
* if (condition) {
|
|
2133
2134
|
* doSomething();
|
|
2135
|
+
*
|
|
2136
|
+
* doMore();
|
|
2134
2137
|
* } else {
|
|
2135
2138
|
* doOther();
|
|
2139
|
+
*
|
|
2140
|
+
* doAnother();
|
|
2136
2141
|
* }
|
|
2137
2142
|
*
|
|
2138
2143
|
* ✗ Bad:
|
|
2139
2144
|
* if (condition)
|
|
2140
2145
|
* {
|
|
2141
2146
|
* doSomething();
|
|
2147
|
+
* doMore();
|
|
2142
2148
|
* }
|
|
2143
2149
|
* else
|
|
2144
2150
|
* {
|
|
2145
2151
|
* doOther();
|
|
2152
|
+
* doAnother();
|
|
2146
2153
|
* }
|
|
2147
2154
|
*/
|
|
2148
2155
|
const ifStatementFormat = {
|
|
@@ -4708,12 +4715,46 @@ const jsxTernaryFormat = {
|
|
|
4708
4715
|
return tokenBefore && tokenAfter && tokenBefore.value === "(" && tokenAfter.value === ")";
|
|
4709
4716
|
};
|
|
4710
4717
|
|
|
4718
|
+
// Check if condition has broken operators (spread across lines)
|
|
4719
|
+
const hasConditionBrokenAcrossLinesHandler = (testNode) => {
|
|
4720
|
+
// Check binary expressions (===, !==, etc.)
|
|
4721
|
+
if (testNode.type === "BinaryExpression") {
|
|
4722
|
+
const leftEnd = testNode.left.loc.end.line;
|
|
4723
|
+
const rightStart = testNode.right.loc.start.line;
|
|
4724
|
+
|
|
4725
|
+
if (leftEnd !== rightStart) return true;
|
|
4726
|
+
|
|
4727
|
+
// Recursively check nested expressions
|
|
4728
|
+
return hasConditionBrokenAcrossLinesHandler(testNode.left)
|
|
4729
|
+
|| hasConditionBrokenAcrossLinesHandler(testNode.right);
|
|
4730
|
+
}
|
|
4731
|
+
|
|
4732
|
+
// Check logical expressions (&&, ||)
|
|
4733
|
+
if (testNode.type === "LogicalExpression") {
|
|
4734
|
+
const leftEnd = testNode.left.loc.end.line;
|
|
4735
|
+
const rightStart = testNode.right.loc.start.line;
|
|
4736
|
+
|
|
4737
|
+
if (leftEnd !== rightStart) return true;
|
|
4738
|
+
|
|
4739
|
+
return hasConditionBrokenAcrossLinesHandler(testNode.left)
|
|
4740
|
+
|| hasConditionBrokenAcrossLinesHandler(testNode.right);
|
|
4741
|
+
}
|
|
4742
|
+
|
|
4743
|
+
return false;
|
|
4744
|
+
};
|
|
4745
|
+
|
|
4746
|
+
// Get the full condition text collapsed to single line
|
|
4747
|
+
const getCollapsedConditionTextHandler = (testNode) => sourceCode.getText(testNode).replace(/\s*\n\s*/g, " ").trim();
|
|
4748
|
+
|
|
4711
4749
|
return {
|
|
4712
4750
|
ConditionalExpression(node) {
|
|
4713
|
-
// Only handle ternaries in JSX context
|
|
4714
4751
|
const parent = node.parent;
|
|
4715
4752
|
|
|
4716
|
-
|
|
4753
|
+
// Handle ternaries in JSX context or return statements
|
|
4754
|
+
const isJsxContext = parent && parent.type === "JSXExpressionContainer";
|
|
4755
|
+
const isReturnContext = parent && parent.type === "ReturnStatement";
|
|
4756
|
+
|
|
4757
|
+
if (!isJsxContext && !isReturnContext) return;
|
|
4717
4758
|
|
|
4718
4759
|
const {
|
|
4719
4760
|
alternate,
|
|
@@ -4732,19 +4773,32 @@ const jsxTernaryFormat = {
|
|
|
4732
4773
|
const baseIndent = getIndentHandler(node);
|
|
4733
4774
|
const contentIndent = baseIndent + " ";
|
|
4734
4775
|
|
|
4735
|
-
// Check
|
|
4736
|
-
|
|
4776
|
+
// Check: Condition should not be broken across multiple lines
|
|
4777
|
+
if (hasConditionBrokenAcrossLinesHandler(node.test)) {
|
|
4778
|
+
const collapsedCondition = getCollapsedConditionTextHandler(node.test);
|
|
4737
4779
|
|
|
4738
|
-
|
|
4739
|
-
|
|
4740
|
-
|
|
4741
|
-
|
|
4742
|
-
|
|
4743
|
-
|
|
4744
|
-
|
|
4745
|
-
|
|
4746
|
-
|
|
4747
|
-
|
|
4780
|
+
context.report({
|
|
4781
|
+
fix: (fixer) => fixer.replaceText(node.test, collapsedCondition),
|
|
4782
|
+
message: "Ternary condition should not be broken across multiple lines",
|
|
4783
|
+
node: node.test,
|
|
4784
|
+
});
|
|
4785
|
+
}
|
|
4786
|
+
|
|
4787
|
+
// Check: Condition should be on same line as opening { (for JSX context)
|
|
4788
|
+
if (isJsxContext) {
|
|
4789
|
+
const openBrace = sourceCode.getFirstToken(parent);
|
|
4790
|
+
|
|
4791
|
+
if (openBrace && openBrace.value === "{") {
|
|
4792
|
+
if (openBrace.loc.end.line !== node.test.loc.start.line) {
|
|
4793
|
+
context.report({
|
|
4794
|
+
fix: (fixer) => fixer.replaceTextRange(
|
|
4795
|
+
[openBrace.range[1], node.test.range[0]],
|
|
4796
|
+
"",
|
|
4797
|
+
),
|
|
4798
|
+
message: "Ternary condition should be on same line as opening '{'",
|
|
4799
|
+
node: node.test,
|
|
4800
|
+
});
|
|
4801
|
+
}
|
|
4748
4802
|
}
|
|
4749
4803
|
}
|
|
4750
4804
|
|
|
@@ -4764,8 +4818,8 @@ const jsxTernaryFormat = {
|
|
|
4764
4818
|
|
|
4765
4819
|
if (!colonToken) return;
|
|
4766
4820
|
|
|
4767
|
-
// Get closing brace of JSXExpressionContainer
|
|
4768
|
-
const closeBrace = sourceCode.getLastToken(parent);
|
|
4821
|
+
// Get closing brace of JSXExpressionContainer (null for return statements)
|
|
4822
|
+
const closeBrace = isJsxContext ? sourceCode.getLastToken(parent) : null;
|
|
4769
4823
|
|
|
4770
4824
|
// Check for unnecessary parentheses around simple JSX
|
|
4771
4825
|
if (consequentSimple && hasUnnecessaryParensHandler(consequent)) {
|
|
@@ -5059,6 +5113,30 @@ const jsxTernaryFormat = {
|
|
|
5059
5113
|
}
|
|
5060
5114
|
}
|
|
5061
5115
|
|
|
5116
|
+
// Check if simple alternate is wrapped in unnecessary parentheses
|
|
5117
|
+
const tokenAfterColon = sourceCode.getTokenAfter(colonToken);
|
|
5118
|
+
|
|
5119
|
+
if (tokenAfterColon && tokenAfterColon.value === "(") {
|
|
5120
|
+
// Find the matching closing paren
|
|
5121
|
+
const closingParen = sourceCode.getTokenAfter(alternate);
|
|
5122
|
+
|
|
5123
|
+
if (closingParen && closingParen.value === ")") {
|
|
5124
|
+
// Remove parentheses and put simple alternate on same line as :
|
|
5125
|
+
const alternateText = sourceCode.getText(alternate);
|
|
5126
|
+
|
|
5127
|
+
context.report({
|
|
5128
|
+
fix: (fixer) => fixer.replaceTextRange(
|
|
5129
|
+
[colonToken.range[1], closingParen.range[1]],
|
|
5130
|
+
` ${alternateText}`,
|
|
5131
|
+
),
|
|
5132
|
+
message: "Simple JSX should not be wrapped in parentheses; put on same line as ':'",
|
|
5133
|
+
node: alternate,
|
|
5134
|
+
});
|
|
5135
|
+
|
|
5136
|
+
return;
|
|
5137
|
+
}
|
|
5138
|
+
}
|
|
5139
|
+
|
|
5062
5140
|
// Simple alternate should be on same line as :
|
|
5063
5141
|
if (colonToken.loc.end.line !== alternate.loc.start.line) {
|
|
5064
5142
|
context.report({
|
|
@@ -5071,7 +5149,7 @@ const jsxTernaryFormat = {
|
|
|
5071
5149
|
});
|
|
5072
5150
|
}
|
|
5073
5151
|
|
|
5074
|
-
// } should be on same line as simple alternate
|
|
5152
|
+
// } should be on same line as simple alternate (only for JSX context)
|
|
5075
5153
|
if (closeBrace && closeBrace.value === "}" && alternate.loc.end.line !== closeBrace.loc.start.line) {
|
|
5076
5154
|
context.report({
|
|
5077
5155
|
fix: (fixer) => fixer.replaceTextRange(
|
package/package.json
CHANGED