eslint-plugin-sonarjs 0.18.0 → 0.19.0
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.
|
@@ -19,20 +19,21 @@
|
|
|
19
19
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
20
20
|
*/
|
|
21
21
|
// https://sonarsource.github.io/rspec/#/rspec/S1862
|
|
22
|
-
const nodes_1 = require("../utils/nodes");
|
|
23
22
|
const equivalence_1 = require("../utils/equivalence");
|
|
24
23
|
const locations_1 = require("../utils/locations");
|
|
25
24
|
const docs_url_1 = require("../utils/docs-url");
|
|
26
|
-
const
|
|
25
|
+
const duplicatedConditionMessage = 'This condition is covered by the one on line {{line}}';
|
|
26
|
+
const duplicatedCaseMessage = 'This case duplicates the one on line {{line}}';
|
|
27
27
|
const rule = {
|
|
28
28
|
meta: {
|
|
29
29
|
messages: {
|
|
30
|
-
|
|
30
|
+
duplicatedCondition: duplicatedConditionMessage,
|
|
31
|
+
duplicatedCase: duplicatedCaseMessage,
|
|
31
32
|
sonarRuntime: '{{sonarRuntimeData}}',
|
|
32
33
|
},
|
|
33
34
|
type: 'problem',
|
|
34
35
|
docs: {
|
|
35
|
-
description: 'Related "if
|
|
36
|
+
description: 'Related "if-else-if" and "switch-case" statements should not have the same condition',
|
|
36
37
|
recommended: 'error',
|
|
37
38
|
url: (0, docs_url_1.default)(__filename),
|
|
38
39
|
},
|
|
@@ -44,34 +45,84 @@ const rule = {
|
|
|
44
45
|
],
|
|
45
46
|
},
|
|
46
47
|
create(context) {
|
|
48
|
+
const sourceCode = context.getSourceCode();
|
|
47
49
|
return {
|
|
48
50
|
IfStatement(node) {
|
|
49
|
-
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
}
|
|
66
|
-
statement = statement.alternate;
|
|
67
|
-
}
|
|
68
|
-
else {
|
|
51
|
+
var _a;
|
|
52
|
+
const { test } = node;
|
|
53
|
+
const conditionsToCheck = test.type === 'LogicalExpression' && test.operator === '&&'
|
|
54
|
+
? [test, ...splitByAnd(test)]
|
|
55
|
+
: [test];
|
|
56
|
+
let current = node;
|
|
57
|
+
let operandsToCheck = conditionsToCheck.map(c => splitByOr(c).map(splitByAnd));
|
|
58
|
+
while (((_a = current.parent) === null || _a === void 0 ? void 0 : _a.type) === 'IfStatement' && current.parent.alternate === current) {
|
|
59
|
+
current = current.parent;
|
|
60
|
+
const currentOrOperands = splitByOr(current.test).map(splitByAnd);
|
|
61
|
+
operandsToCheck = operandsToCheck.map(orOperands => orOperands.filter(orOperand => !currentOrOperands.some(currentOrOperand => isSubset(currentOrOperand, orOperand, sourceCode))));
|
|
62
|
+
if (operandsToCheck.some(orOperands => orOperands.length === 0)) {
|
|
63
|
+
(0, locations_1.report)(context, {
|
|
64
|
+
messageId: 'duplicatedCondition',
|
|
65
|
+
data: { line: current.test.loc.start.line },
|
|
66
|
+
node: test,
|
|
67
|
+
}, [(0, locations_1.issueLocation)(current.test.loc, current.test.loc, 'Covering')], duplicatedConditionMessage);
|
|
69
68
|
break;
|
|
70
69
|
}
|
|
71
70
|
}
|
|
72
71
|
},
|
|
72
|
+
SwitchStatement(node) {
|
|
73
|
+
const switchStmt = node;
|
|
74
|
+
const previousTests = [];
|
|
75
|
+
for (const switchCase of switchStmt.cases) {
|
|
76
|
+
if (switchCase.test) {
|
|
77
|
+
const { test } = switchCase;
|
|
78
|
+
const duplicateTest = previousTests.find(previousTest => (0, equivalence_1.areEquivalent)(test, previousTest, sourceCode));
|
|
79
|
+
if (duplicateTest) {
|
|
80
|
+
(0, locations_1.report)(context, {
|
|
81
|
+
messageId: 'duplicatedCase',
|
|
82
|
+
data: {
|
|
83
|
+
line: duplicateTest.loc.start.line,
|
|
84
|
+
},
|
|
85
|
+
node: test,
|
|
86
|
+
}, [(0, locations_1.issueLocation)(duplicateTest.loc, duplicateTest.loc, 'Original')], duplicatedCaseMessage);
|
|
87
|
+
}
|
|
88
|
+
else {
|
|
89
|
+
previousTests.push(test);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
},
|
|
73
94
|
};
|
|
74
95
|
},
|
|
75
96
|
};
|
|
97
|
+
const splitByOr = splitByLogicalOperator.bind(null, '||');
|
|
98
|
+
const splitByAnd = splitByLogicalOperator.bind(null, '&&');
|
|
99
|
+
function splitByLogicalOperator(operator, node) {
|
|
100
|
+
if (node.type === 'LogicalExpression' && node.operator === operator) {
|
|
101
|
+
return [
|
|
102
|
+
...splitByLogicalOperator(operator, node.left),
|
|
103
|
+
...splitByLogicalOperator(operator, node.right),
|
|
104
|
+
];
|
|
105
|
+
}
|
|
106
|
+
return [node];
|
|
107
|
+
}
|
|
108
|
+
function isSubset(first, second, sourceCode) {
|
|
109
|
+
return first.every(fst => second.some(snd => isSubsetOf(fst, snd, sourceCode)));
|
|
110
|
+
function isSubsetOf(first, second, sourceCode) {
|
|
111
|
+
if (first.type !== second.type) {
|
|
112
|
+
return false;
|
|
113
|
+
}
|
|
114
|
+
if (first.type === 'LogicalExpression') {
|
|
115
|
+
const second1 = second;
|
|
116
|
+
if ((first.operator === '||' || first.operator === '&&') &&
|
|
117
|
+
first.operator === second1.operator) {
|
|
118
|
+
return ((isSubsetOf(first.left, second1.left, sourceCode) &&
|
|
119
|
+
isSubsetOf(first.right, second1.right, sourceCode)) ||
|
|
120
|
+
(isSubsetOf(first.left, second1.right, sourceCode) &&
|
|
121
|
+
isSubsetOf(first.right, second1.left, sourceCode)));
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return (0, equivalence_1.areEquivalent)(first, second, sourceCode);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
76
127
|
module.exports = rule;
|
|
77
128
|
//# sourceMappingURL=no-identical-conditions.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"no-identical-conditions.js","sourceRoot":"","sources":["../../src/rules/no-identical-conditions.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;GAkBG;AACH,oDAAoD;AAGpD,
|
|
1
|
+
{"version":3,"file":"no-identical-conditions.js","sourceRoot":"","sources":["../../src/rules/no-identical-conditions.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "eslint-plugin-sonarjs",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "SonarJS rules for ESLint",
|
|
5
5
|
"main": "lib/index.js",
|
|
6
6
|
"types": "lib/index.d.ts",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"eslint-config-prettier": "8.5.0",
|
|
52
52
|
"eslint-plugin-import": "2.26.0",
|
|
53
53
|
"eslint-plugin-notice": "0.9.10",
|
|
54
|
-
"eslint-plugin-sonarjs": "0.
|
|
54
|
+
"eslint-plugin-sonarjs": "0.18.0",
|
|
55
55
|
"jest": "28.1.3",
|
|
56
56
|
"jest-sonar-reporter": "2.0.0",
|
|
57
57
|
"lint-staged": "13.0.3",
|