New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

eslint-plugin-sonarjs

Package Overview
Dependencies
Maintainers
6
Versions
53
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

eslint-plugin-sonarjs - npm Package Compare versions

Comparing version 0.10.0 to 0.11.0

.jfrog/projects/npm.yaml

5

lib/rules/cognitive-complexity.d.ts

@@ -1,4 +0,3 @@

import { Rule } from '../utils/types';
declare type Options = [number, 'metric'];
declare const rule: Rule.RuleModule<string, Options>;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, (number | 'metric' | 'sonar-runtime')[]>;
export = rule;

67

lib/rules/cognitive-complexity.js

@@ -26,10 +26,15 @@ "use strict";

const DEFAULT_THRESHOLD = 15;
const message = 'Refactor this function to reduce its Cognitive Complexity from {{complexityAmount}} to the {{threshold}} allowed.';
const rule = {
meta: {
messages: {
refactorFunction: message,
sonarRuntime: '{{sonarRuntimeData}}',
fileComplexity: '{{complexityAmount}}',
},
type: 'suggestion',
docs: {
description: 'Cognitive Complexity of functions should not be too high',
category: 'Best Practices',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -45,3 +50,3 @@ schema: [

create(context) {
const threshold = getThreshold();
const threshold = typeof context.options[0] === 'number' ? context.options[0] : DEFAULT_THRESHOLD;
const isFileComplexity = context.options.includes('metric');

@@ -102,5 +107,8 @@ /** Complexity of the file */

if (isFileComplexity) {
// as issues are the only communication channel of a rule
// we pass data as serialized json as an issue message
context.report({ node, message: fileComplexity.toString() });
// value from the message will be saved in SonarQube as file complexity metric
context.report({
node,
messageId: 'fileComplexity',
data: { complexityAmount: fileComplexity },
});
}

@@ -148,5 +156,2 @@ },

};
function getThreshold() {
return context.options[0] !== undefined ? context.options[0] : DEFAULT_THRESHOLD;
}
function onEnterFunction(node) {

@@ -180,8 +185,8 @@ if (enclosingFunctions.length === 0) {

});
checkFunction(totalComplexity, locations_1.getMainFunctionTokenLocation(node, node.parent, context));
checkFunction(totalComplexity, (0, locations_1.getMainFunctionTokenLocation)(node, node.parent, context));
}
else {
checkFunction(topLevelOwnComplexity, locations_1.getMainFunctionTokenLocation(node, node.parent, context));
checkFunction(topLevelOwnComplexity, (0, locations_1.getMainFunctionTokenLocation)(node, node.parent, context));
secondLevelFunctions.forEach(secondLevelFunction => {
checkFunction(secondLevelFunction.complexityIfThisSecondaryIsTopLevel, locations_1.getMainFunctionTokenLocation(secondLevelFunction.node, secondLevelFunction.parent, context));
checkFunction(secondLevelFunction.complexityIfThisSecondaryIsTopLevel, (0, locations_1.getMainFunctionTokenLocation)(secondLevelFunction.node, secondLevelFunction.parent, context));
});

@@ -197,3 +202,3 @@ }

complexityIfThisSecondaryIsTopLevel: complexityIfNotNested,
loc: locations_1.getMainFunctionTokenLocation(node, node.parent, context),
loc: (0, locations_1.getMainFunctionTokenLocation)(node, node.parent, context),
});

@@ -208,5 +213,5 @@ }

const { parent } = ifStatement;
const { loc: ifLoc } = locations_1.getFirstToken(ifStatement, context);
const { loc: ifLoc } = (0, locations_1.getFirstToken)(ifStatement, context);
// if the current `if` statement is `else if`, do not count it in structural complexity
if (nodes_1.isIfStatement(parent) && parent.alternate === ifStatement) {
if ((0, nodes_1.isIfStatement)(parent) && parent.alternate === ifStatement) {
addComplexity(ifLoc);

@@ -222,5 +227,5 @@ }

// - add +1 complexity
if (ifStatement.alternate && !nodes_1.isIfStatement(ifStatement.alternate)) {
if (ifStatement.alternate && !(0, nodes_1.isIfStatement)(ifStatement.alternate)) {
nestingNodes.add(ifStatement.alternate);
const elseTokenLoc = locations_1.getFirstTokenAfter(ifStatement.consequent, context).loc;
const elseTokenLoc = (0, locations_1.getFirstTokenAfter)(ifStatement.consequent, context).loc;
addComplexity(elseTokenLoc);

@@ -230,7 +235,7 @@ }

function visitLoop(loop) {
addStructuralComplexity(locations_1.getFirstToken(loop, context).loc);
addStructuralComplexity((0, locations_1.getFirstToken)(loop, context).loc);
nestingNodes.add(loop.body);
}
function visitSwitchStatement(switchStatement) {
addStructuralComplexity(locations_1.getFirstToken(switchStatement, context).loc);
addStructuralComplexity((0, locations_1.getFirstToken)(switchStatement, context).loc);
for (const switchCase of switchStatement.cases) {

@@ -242,11 +247,11 @@ nestingNodes.add(switchCase);

if (statement.label) {
addComplexity(locations_1.getFirstToken(statement, context).loc);
addComplexity((0, locations_1.getFirstToken)(statement, context).loc);
}
}
function visitCatchClause(catchClause) {
addStructuralComplexity(locations_1.getFirstToken(catchClause, context).loc);
addStructuralComplexity((0, locations_1.getFirstToken)(catchClause, context).loc);
nestingNodes.add(catchClause.body);
}
function visitConditionalExpression(conditionalExpression) {
const questionTokenLoc = locations_1.getFirstTokenAfter(conditionalExpression.test, context).loc;
const questionTokenLoc = (0, locations_1.getFirstTokenAfter)(conditionalExpression.test, context).loc;
addStructuralComplexity(questionTokenLoc);

@@ -269,3 +274,3 @@ nestingNodes.add(conditionalExpression.consequent);

};
if (!nodes_1.isArrowFunctionExpression(node) && node.id) {
if (!(0, nodes_1.isArrowFunctionExpression)(node) && node.id) {
return checkFirstLetter(node.id.name);

@@ -285,3 +290,3 @@ }

if (!previous || previous.operator !== current.operator) {
const operatorTokenLoc = locations_1.getFirstTokenAfter(logicalExpression.left, context).loc;
const operatorTokenLoc = (0, locations_1.getFirstTokenAfter)(logicalExpression.left, context).loc;
addComplexity(operatorTokenLoc);

@@ -294,3 +299,3 @@ }

function flattenLogicalExpression(node) {
if (nodes_1.isLogicalExpression(node)) {
if ((0, nodes_1.isLogicalExpression)(node)) {
consideredLogicalExpressions.add(node);

@@ -349,8 +354,12 @@ return [

const message = complexity === 1 ? '+1' : `+${complexity} (incl. ${complexity - 1} for nesting)`;
return locations_1.issueLocation(location, undefined, message);
return (0, locations_1.issueLocation)(location, undefined, message);
});
locations_1.report(context, {
message: `Refactor this function to reduce its Cognitive Complexity from ${complexityAmount} to the ${threshold} allowed.`,
(0, locations_1.report)(context, {
messageId: 'refactorFunction',
data: {
complexityAmount,
threshold,
},
loc,
}, secondaryLocations, complexityAmount - threshold);
}, secondaryLocations, message, complexityAmount - threshold);
}

@@ -357,0 +366,0 @@ }

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -25,8 +25,11 @@ "use strict";

meta: {
messages: {
addMissingElseClause: 'Add the missing "else" clause.',
},
schema: [],
type: 'suggestion',
docs: {
description: '"if ... else if" constructs should end with "else" clauses',
category: 'Best Practices',
recommended: false,
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -43,3 +46,3 @@ },

context.report({
message: `Add the missing "else" clause.`,
messageId: 'addMissingElseClause',
loc: {

@@ -46,0 +49,0 @@ start: elseKeyword.loc.start,

@@ -1,4 +0,4 @@

import { Rule } from '../utils/types';
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare type Options = [number];
declare const rule: Rule.RuleModule<string, Options>;
declare const rule: TSESLint.RuleModule<string, Options>;
export = rule;

@@ -23,3 +23,2 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const MESSAGE = 'Reduce the number of non-empty switch cases from {{numSwitchCases}} to at most {{maxSwitchCases}}.';
const DEFAULT_MAX_SWITCH_CASES = 30;

@@ -29,8 +28,10 @@ let maxSwitchCases = DEFAULT_MAX_SWITCH_CASES;

meta: {
messages: {
reduceNumberOfNonEmptySwitchCases: 'Reduce the number of non-empty switch cases from {{numSwitchCases}} to at most {{maxSwitchCases}}.',
},
type: 'suggestion',
docs: {
description: '"switch" statements should not have too many "case" clauses',
category: 'Best Practices',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -58,3 +59,3 @@ schema: [

context.report({
message: MESSAGE,
messageId: 'reduceNumberOfNonEmptySwitchCases',
loc: switchKeyword.loc,

@@ -61,0 +62,0 @@ data: {

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -26,12 +26,14 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const MESSAGE = "Remove this conditional structure or edit its code blocks so that they're not all the same.";
const MESSAGE_CONDITIONAL_EXPRESSION = 'This conditional operation returns the same value whether the condition is "true" or "false".';
const rule = {
meta: {
messages: {
removeOrEditConditionalStructure: "Remove this conditional structure or edit its code blocks so that they're not all the same.",
returnsTheSameValue: 'This conditional operation returns the same value whether the condition is "true" or "false".',
},
schema: [],
type: 'problem',
docs: {
description: 'All branches in a conditional structure should not have exactly the same implementation',
category: 'Possible Errors',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -44,6 +46,6 @@ },

// don't visit `else if` statements
if (!nodes_1.isIfStatement(node.parent)) {
const { branches, endsWithElse } = conditions_1.collectIfBranches(ifStmt);
if (!(0, nodes_1.isIfStatement)(node.parent)) {
const { branches, endsWithElse } = (0, conditions_1.collectIfBranches)(ifStmt);
if (endsWithElse && allDuplicated(branches)) {
context.report({ message: MESSAGE, node: ifStmt });
context.report({ messageId: 'removeOrEditConditionalStructure', node: ifStmt });
}

@@ -54,5 +56,5 @@ }

const switchStmt = node;
const { branches, endsWithDefault } = conditions_1.collectSwitchBranches(switchStmt);
const { branches, endsWithDefault } = (0, conditions_1.collectSwitchBranches)(switchStmt);
if (endsWithDefault && allDuplicated(branches)) {
context.report({ message: MESSAGE, node: switchStmt });
context.report({ messageId: 'removeOrEditConditionalStructure', node: switchStmt });
}

@@ -64,3 +66,3 @@ },

if (allDuplicated(branches)) {
context.report({ message: MESSAGE_CONDITIONAL_EXPRESSION, node: conditional });
context.report({ messageId: 'returnsTheSameValue', node: conditional });
}

@@ -72,3 +74,3 @@ },

branches.slice(1).every((branch, index) => {
return equivalence_1.areEquivalent(branch, branches[index], context.getSourceCode());
return (0, equivalence_1.areEquivalent)(branch, branches[index], context.getSourceCode());
}));

@@ -75,0 +77,0 @@ }

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -25,10 +25,14 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const message = 'Merge this if statement with the nested one.';
const rule = {
meta: {
messages: {
mergeNestedIfStatement: message,
sonarRuntime: '{{sonarRuntimeData}}',
},
type: 'suggestion',
docs: {
description: 'Collapsible "if" statements should be merged',
category: 'Best Practices',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -46,3 +50,3 @@ schema: [

let { consequent } = node;
if (nodes_1.isBlockStatement(consequent) && consequent.body.length === 1) {
if ((0, nodes_1.isBlockStatement)(consequent) && consequent.body.length === 1) {
consequent = consequent.body[0];

@@ -54,6 +58,6 @@ }

if (ifKeyword && enclosingIfKeyword) {
locations_1.report(context, {
message: `Merge this if statement with the nested one.`,
(0, locations_1.report)(context, {
messageId: 'mergeNestedIfStatement',
loc: enclosingIfKeyword.loc,
}, [locations_1.issueLocation(ifKeyword.loc, ifKeyword.loc, `Nested "if" statement.`)]);
}, [(0, locations_1.issueLocation)(ifKeyword.loc, ifKeyword.loc, 'Nested "if" statement.')], message);
}

@@ -64,3 +68,3 @@ }

function isIfStatementWithoutElse(node) {
return nodes_1.isIfStatement(node) && !node.alternate;
return (0, nodes_1.isIfStatement)(node) && !node.alternate;
}

@@ -67,0 +71,0 @@ },

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -28,8 +28,11 @@ "use strict";

meta: {
messages: {
fixCollectionSizeCheck: 'Fix this expression; {{propertyName}} of "{{objectName}}" is always greater or equal to zero.',
},
schema: [],
type: 'problem',
docs: {
description: 'Collection sizes and array length comparisons should make sense',
category: 'Possible Errors',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -39,3 +42,3 @@ },

const services = context.parserServices;
const isTypeCheckerAvailable = parser_services_1.isRequiredParserServices(services);
const isTypeCheckerAvailable = (0, parser_services_1.isRequiredParserServices)(services);
return {

@@ -53,5 +56,7 @@ BinaryExpression: (node) => {

context.report({
message: `Fix this expression; ${property.name} of "${context
.getSourceCode()
.getText(object)}" is always greater or equal to zero.`,
messageId: 'fixCollectionSizeCheck',
data: {
propertyName: property.name,
objectName: context.getSourceCode().getText(object),
},
node,

@@ -58,0 +63,0 @@ });

@@ -1,4 +0,4 @@

import { Rule } from '../utils/types';
declare type Options = [number];
declare const rule: Rule.RuleModule<string, Options>;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare type Options = (number | 'sonar-runtime')[];
declare const rule: TSESLint.RuleModule<string, Options>;
export = rule;

@@ -23,2 +23,3 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const locations_1 = require("../utils/locations");
// Number of times a literal must be duplicated to trigger an issue

@@ -30,2 +31,3 @@ const DEFAULT_THRESHOLD = 3;

'ImportDeclaration',
'ImportExpression',
'JSXAttribute',

@@ -35,17 +37,23 @@ 'ExportAllDeclaration',

];
const MESSAGE = 'Define a constant instead of duplicating this literal {{times}} times.';
const message = 'Define a constant instead of duplicating this literal {{times}} times.';
const rule = {
meta: {
messages: {
defineConstant: message,
sonarRuntime: '{{sonarRuntimeData}}',
},
type: 'suggestion',
docs: {
description: 'String literals should not be duplicated',
category: 'Best Practices',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},
schema: [{ type: 'integer', minimum: 2 }],
schema: [
{ type: 'integer', minimum: 2 },
{ enum: ['sonar-runtime'] /* internal parameter for rules having secondary locations */ },
],
},
create(context) {
const literalsByValue = new Map();
const threshold = context.options[0] !== undefined ? context.options[0] : DEFAULT_THRESHOLD;
const threshold = typeof context.options[0] === 'number' ? context.options[0] : DEFAULT_THRESHOLD;
return {

@@ -71,7 +79,9 @@ Literal: (node) => {

if (literals.length >= threshold) {
context.report({
message: MESSAGE,
node: literals[0],
const [primaryNode, ...secondaryNodes] = literals;
const secondaryIssues = secondaryNodes.map(node => (0, locations_1.issueLocation)(node.loc, node.loc, 'Duplication'));
(0, locations_1.report)(context, {
messageId: 'defineConstant',
node: primaryNode,
data: { times: literals.length.toString() },
});
}, secondaryIssues, message);
}

@@ -78,0 +88,0 @@ });

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -27,11 +27,14 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const MESSAGE = "This {{type}}'s code block is the same as the block for the {{type}} on line {{line}}.";
const message = "This {{type}}'s code block is the same as the block for the {{type}} on line {{line}}.";
const rule = {
meta: {
messages: {
sameConditionalBlock: message,
sonarRuntime: '{{sonarRuntimeData}}',
},
type: 'problem',
docs: {
description: 'Two branches in a conditional structure should not have exactly the same implementation',
category: 'Possible Errors',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -55,6 +58,6 @@ schema: [

function visitIfStatement(ifStmt) {
if (nodes_1.isIfStatement(ifStmt.parent)) {
if ((0, nodes_1.isIfStatement)(ifStmt.parent)) {
return;
}
const { branches, endsWithElse } = conditions_1.collectIfBranches(ifStmt);
const { branches, endsWithElse } = (0, conditions_1.collectIfBranches)(ifStmt);
if (allEquivalentWithoutDefault(branches, endsWithElse)) {

@@ -76,5 +79,5 @@ branches.slice(1).forEach((branch, i) => reportIssue(branch, branches[i], 'branch'));

const { cases } = switchStmt;
const { endsWithDefault } = conditions_1.collectSwitchBranches(switchStmt);
const nonEmptyCases = cases.filter(c => conditions_1.takeWithoutBreak(expandSingleBlockStatement(c.consequent)).length > 0);
const casesWithoutBreak = nonEmptyCases.map(c => conditions_1.takeWithoutBreak(expandSingleBlockStatement(c.consequent)));
const { endsWithDefault } = (0, conditions_1.collectSwitchBranches)(switchStmt);
const nonEmptyCases = cases.filter(c => (0, conditions_1.takeWithoutBreak)(expandSingleBlockStatement(c.consequent)).length > 0);
const casesWithoutBreak = nonEmptyCases.map(c => (0, conditions_1.takeWithoutBreak)(expandSingleBlockStatement(c.consequent)));
if (allEquivalentWithoutDefault(casesWithoutBreak, endsWithDefault)) {

@@ -87,7 +90,7 @@ nonEmptyCases

for (let i = 1; i < cases.length; i++) {
const firstClauseWithoutBreak = conditions_1.takeWithoutBreak(expandSingleBlockStatement(cases[i].consequent));
const firstClauseWithoutBreak = (0, conditions_1.takeWithoutBreak)(expandSingleBlockStatement(cases[i].consequent));
if (hasRequiredSize(firstClauseWithoutBreak)) {
for (let j = 0; j < i; j++) {
const secondClauseWithoutBreak = conditions_1.takeWithoutBreak(expandSingleBlockStatement(cases[j].consequent));
if (equivalence_1.areEquivalent(firstClauseWithoutBreak, secondClauseWithoutBreak, context.getSourceCode())) {
const secondClauseWithoutBreak = (0, conditions_1.takeWithoutBreak)(expandSingleBlockStatement(cases[j].consequent));
if ((0, equivalence_1.areEquivalent)(firstClauseWithoutBreak, secondClauseWithoutBreak, context.getSourceCode())) {
reportIssue(cases[i], cases[j], 'case');

@@ -111,3 +114,3 @@ break;

function compareIfBranches(a, b) {
const equivalent = equivalence_1.areEquivalent(a, b, context.getSourceCode());
const equivalent = (0, equivalence_1.areEquivalent)(a, b, context.getSourceCode());
if (equivalent && b.loc) {

@@ -121,3 +124,3 @@ reportIssue(a, b, 'branch');

const node = nodes[0];
if (nodes_1.isBlockStatement(node)) {
if ((0, nodes_1.isBlockStatement)(node)) {
return node.body;

@@ -133,7 +136,11 @@ }

.slice(1)
.every((branch, index) => equivalence_1.areEquivalent(branch, branches[index], context.getSourceCode())));
.every((branch, index) => (0, equivalence_1.areEquivalent)(branch, branches[index], context.getSourceCode())));
}
function reportIssue(node, equivalentNode, type) {
const equivalentNodeLoc = equivalentNode.loc;
locations_1.report(context, { message: MESSAGE, data: { type, line: String(equivalentNode.loc.start.line) }, node }, [locations_1.issueLocation(equivalentNodeLoc, equivalentNodeLoc, 'Original')]);
(0, locations_1.report)(context, {
messageId: 'sameConditionalBlock',
data: { type, line: String(equivalentNode.loc.start.line) },
node,
}, [(0, locations_1.issueLocation)(equivalentNodeLoc, equivalentNodeLoc, 'Original')], message);
}

@@ -140,0 +147,0 @@ },

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -26,11 +26,14 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const message = (index, line) => `Verify this is the index that was intended; "${index}" was already set on line ${line}.`;
const message = 'Verify this is the index that was intended; "{{index}}" was already set on line {{line}}.';
const rule = {
meta: {
messages: {
verifyIntendedIndex: message,
sonarRuntime: '{{sonarRuntimeData}}',
},
type: 'problem',
docs: {
description: 'Collection elements should not be replaced unconditionally',
category: 'Possible Errors',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -66,3 +69,3 @@ schema: [

if (collection &&
!equivalence_1.areEquivalent(keyWriteUsage.collectionNode, collection, context.getSourceCode())) {
!(0, equivalence_1.areEquivalent)(keyWriteUsage.collectionNode, collection, context.getSourceCode())) {
usedKeys.clear();

@@ -74,8 +77,12 @@ }

const secondaryLocations = [
locations_1.issueLocation(sameKeyWriteUsageLoc, sameKeyWriteUsageLoc, 'Original value'),
(0, locations_1.issueLocation)(sameKeyWriteUsageLoc, sameKeyWriteUsageLoc, 'Original value'),
];
locations_1.report(context, {
(0, locations_1.report)(context, {
node: keyWriteUsage.node,
message: message(keyWriteUsage.indexOrKey, String(sameKeyWriteUsage.node.loc.start.line)),
}, secondaryLocations);
messageId: 'verifyIntendedIndex',
data: {
index: keyWriteUsage.indexOrKey,
line: sameKeyWriteUsage.node.loc.start.line,
},
}, secondaryLocations, message);
}

@@ -91,3 +98,3 @@ usedKeys.set(keyWriteUsage.indexOrKey, keyWriteUsage);

function getKeyWriteUsage(node) {
if (nodes_1.isExpressionStatement(node)) {
if ((0, nodes_1.isExpressionStatement)(node)) {
return arrayKeyWriteUsage(node.expression) || mapOrSetKeyWriteUsage(node.expression);

@@ -99,3 +106,3 @@ }

// a[b] = ...
if (isSimpleAssignment(node) && nodes_1.isMemberExpression(node.left) && node.left.computed) {
if (isSimpleAssignment(node) && (0, nodes_1.isMemberExpression)(node.left) && node.left.computed) {
const { left, right } = node;

@@ -114,5 +121,5 @@ const index = extractIndex(left.property);

function mapOrSetKeyWriteUsage(node) {
if (nodes_1.isCallExpression(node) && nodes_1.isMemberExpression(node.callee)) {
if ((0, nodes_1.isCallExpression)(node) && (0, nodes_1.isMemberExpression)(node.callee)) {
const propertyAccess = node.callee;
if (nodes_1.isIdentifier(propertyAccess.property)) {
if ((0, nodes_1.isIdentifier)(propertyAccess.property)) {
const methodName = propertyAccess.property.name;

@@ -136,7 +143,7 @@ const addMethod = methodName === 'add' && node.arguments.length === 1;

function extractIndex(node) {
if (nodes_1.isLiteral(node)) {
if ((0, nodes_1.isLiteral)(node)) {
const { value } = node;
return typeof value === 'number' || typeof value === 'string' ? String(value) : undefined;
}
else if (nodes_1.isIdentifier(node)) {
else if ((0, nodes_1.isIdentifier)(node)) {
return node.name;

@@ -170,5 +177,5 @@ }

function isSimpleAssignment(node) {
return nodes_1.isAssignmentExpression(node) && node.operator === '=';
return (0, nodes_1.isAssignmentExpression)(node) && node.operator === '=';
}
module.exports = rule;
//# sourceMappingURL=no-element-overwrite.js.map

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -74,8 +74,11 @@ "use strict";

meta: {
messages: {
reviewUsageOfIdentifier: 'Review this usage of "{{identifierName}}" as it can only be empty here.',
},
schema: [],
type: 'problem',
docs: {
description: 'Empty collections should not be accessed or iterated',
category: 'Possible Errors',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -134,3 +137,6 @@ },

context.report({
message: `Review this usage of "${ref.identifier.name}" as it can only be empty here.`,
messageId: 'reviewUsageOfIdentifier',
data: {
identifierName: ref.identifier.name,
},
node: ref.identifier,

@@ -142,3 +148,3 @@ });

function isReferenceAssigningEmptyCollection(ref) {
const declOrExprStmt = utils_1.findFirstMatchingAncestor(ref.identifier, n => n.type === 'VariableDeclarator' || n.type === 'ExpressionStatement');
const declOrExprStmt = (0, utils_1.findFirstMatchingAncestor)(ref.identifier, n => n.type === 'VariableDeclarator' || n.type === 'ExpressionStatement');
if (declOrExprStmt) {

@@ -151,3 +157,3 @@ if (declOrExprStmt.type === 'VariableDeclarator' && declOrExprStmt.init) {

return (expression.type === 'AssignmentExpression' &&
utils_1.isReferenceTo(ref, expression.left) &&
(0, utils_1.isReferenceTo)(ref, expression.left) &&
isEmptyCollectionType(expression.right));

@@ -163,3 +169,3 @@ }

else if (node && (node.type === 'CallExpression' || node.type === 'NewExpression')) {
return utils_1.isIdentifier(node.callee, ...utils_1.collectionConstructor) && node.arguments.length === 0;
return (0, utils_1.isIdentifier)(node.callee, ...utils_1.collectionConstructor) && node.arguments.length === 0;
}

@@ -176,3 +182,3 @@ return false;

if (memberExpressionParent && memberExpressionParent.type === 'CallExpression') {
return utils_1.isIdentifier(parent.property, ...strictlyReadingMethods);
return (0, utils_1.isIdentifier)(parent.property, ...strictlyReadingMethods);
}

@@ -183,3 +189,3 @@ }

function isForIterationPattern(ref) {
const forInOrOfStatement = utils_1.findFirstMatchingAncestor(ref.identifier, n => n.type === 'ForOfStatement' || n.type === 'ForInStatement');
const forInOrOfStatement = (0, utils_1.findFirstMatchingAncestor)(ref.identifier, n => n.type === 'ForOfStatement' || n.type === 'ForInStatement');
return forInOrOfStatement && forInOrOfStatement.right === ref.identifier;

@@ -192,3 +198,3 @@ }

function isElementWrite(memberExpression) {
const ancestors = utils_1.ancestorsChain(memberExpression, new Set());
const ancestors = (0, utils_1.ancestorsChain)(memberExpression, new Set());
const assignment = ancestors.find(n => n.type === 'AssignmentExpression');

@@ -195,0 +201,0 @@ if (assignment && assignment.operator === '=') {

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -25,10 +25,14 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const message = 'This function expects {{expectedArguments}}, but {{providedArguments}} provided.';
const rule = {
meta: {
messages: {
tooManyArguments: message,
sonarRuntime: '{{sonarRuntimeData}}',
},
type: 'problem',
docs: {
description: 'Function calls should not pass extra arguments',
category: 'Possible Errors',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -50,3 +54,3 @@ schema: [

const callExpr = node;
if (nodes_1.isIdentifier(callExpr.callee)) {
if ((0, nodes_1.isIdentifier)(callExpr.callee)) {
const reference = context

@@ -62,3 +66,3 @@ .getScope()

const { init } = definition.node;
if (init && (nodes_1.isFunctionExpression(init) || nodes_1.isArrowFunctionExpression(init))) {
if (init && ((0, nodes_1.isFunctionExpression)(init) || (0, nodes_1.isArrowFunctionExpression)(init))) {
checkFunction(callExpr, init);

@@ -69,4 +73,4 @@ }

}
else if (nodes_1.isArrowFunctionExpression(callExpr.callee) ||
nodes_1.isFunctionExpression(callExpr.callee)) {
else if ((0, nodes_1.isArrowFunctionExpression)(callExpr.callee) ||
(0, nodes_1.isFunctionExpression)(callExpr.callee)) {
// IIFE

@@ -78,3 +82,3 @@ checkFunction(callExpr, callExpr.callee);

const fn = node;
if (nodes_1.isBlockStatement(fn.body) && fn.body.body.length === 0 && fn.params.length === 0) {
if ((0, nodes_1.isBlockStatement)(fn.body) && fn.body.body.length === 0 && fn.params.length === 0) {
emptyFunctions.add(node);

@@ -113,3 +117,3 @@ }

const ancestors = context.getAncestors().reverse();
const fn = ancestors.find(node => nodes_1.isFunctionDeclaration(node) || nodes_1.isFunctionExpression(node));
const fn = ancestors.find(node => (0, nodes_1.isFunctionDeclaration)(node) || (0, nodes_1.isFunctionExpression)(node));
if (fn) {

@@ -142,7 +146,10 @@ usingArguments.add(fn);

`${argsLength} were`;
const message = `This function expects ${expectedArguments}, but ${providedArguments} provided.`;
locations_1.report(context, {
message,
(0, locations_1.report)(context, {
messageId: 'tooManyArguments',
data: {
expectedArguments,
providedArguments,
},
node: callExpr.callee,
}, getSecondaryLocations(callExpr, functionNode));
}, getSecondaryLocations(callExpr, functionNode), message);
}

@@ -155,9 +162,9 @@ function getSecondaryLocations(callExpr, functionNode) {

const endLoc = functionNode.params[paramLength - 1].loc;
secondaryLocations.push(locations_1.issueLocation(startLoc, endLoc, 'Formal parameters'));
secondaryLocations.push((0, locations_1.issueLocation)(startLoc, endLoc, 'Formal parameters'));
}
else {
// as we're not providing parent node, `getMainFunctionTokenLocation` may return `undefined`
const fnToken = locations_1.getMainFunctionTokenLocation(functionNode, undefined, context);
const fnToken = (0, locations_1.getMainFunctionTokenLocation)(functionNode, undefined, context);
if (fnToken) {
secondaryLocations.push(locations_1.issueLocation(fnToken, fnToken, 'Formal parameters'));
secondaryLocations.push((0, locations_1.issueLocation)(fnToken, fnToken, 'Formal parameters'));
}

@@ -168,3 +175,3 @@ }

if (index >= paramLength) {
secondaryLocations.push(locations_1.toSecondaryLocation(argument, 'Extra argument'));
secondaryLocations.push((0, locations_1.toSecondaryLocation)(argument, 'Extra argument'));
}

@@ -171,0 +178,0 @@ });

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -22,12 +22,17 @@ "use strict";

// https://sonarsource.github.io/rspec/#/rspec/S2589
const locations_1 = require("../utils/locations");
const nodes_1 = require("../utils/nodes");
const docs_url_1 = require("../utils/docs-url");
const message = 'This always evaluates to {{value}}. Consider refactoring this code.';
const rule = {
meta: {
messages: {
refactorBooleanExpression: message,
sonarRuntime: '{{sonarRuntimeData}}',
},
type: 'suggestion',
docs: {
description: 'Boolean expressions should not be gratuitous',
category: 'Best Practices',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -48,3 +53,3 @@ schema: [

if (test.type === 'Literal' && typeof test.value === 'boolean') {
report(test, undefined, context, test.value);
reportIssue(test, undefined, context, test.value);
}

@@ -54,3 +59,3 @@ },

const { parent } = node;
if (nodes_1.isIfStatement(parent)) {
if ((0, nodes_1.isIfStatement)(parent)) {
// we visit 'consequent' and 'alternate' and not if-statement directly in order to get scope for 'consequent'

@@ -63,3 +68,3 @@ const currentScope = context.getScope();

}
else if (parent.alternate === node && nodes_1.isIdentifier(parent.test)) {
else if (parent.alternate === node && (0, nodes_1.isIdentifier)(parent.test)) {
falsyMap.set(parent.alternate, transformAndFilter([parent.test], currentScope));

@@ -83,3 +88,3 @@ }

!isLogicalOrLhs(id, parent) &&
!nodes_1.isIfStatement(parent) &&
!(0, nodes_1.isIfStatement)(parent) &&
!isLogicalNegation(parent)) {

@@ -92,3 +97,3 @@ return;

if (ref) {
report(id, ref, context, truthy);
reportIssue(id, ref, context, truthy);
}

@@ -111,10 +116,10 @@ });

const checkExpr = (expr) => {
if (nodes_1.isIdentifier(expr)) {
if ((0, nodes_1.isIdentifier)(expr)) {
truthy.push(expr);
}
else if (isLogicalNegation(expr)) {
if (nodes_1.isIdentifier(expr.argument)) {
if ((0, nodes_1.isIdentifier)(expr.argument)) {
falsy.push(expr.argument);
}
else if (isLogicalNegation(expr.argument) && nodes_1.isIdentifier(expr.argument.argument)) {
else if (isLogicalNegation(expr.argument) && (0, nodes_1.isIdentifier)(expr.argument.argument)) {
truthy.push(expr.argument.argument);

@@ -187,12 +192,11 @@ }

}
function report(id, ref, context, truthy) {
function reportIssue(id, ref, context, truthy) {
const value = truthy ? 'truthy' : 'falsy';
const encodedMessage = {
message: `This always evaluates to ${value}. Consider refactoring this code.`,
secondaryLocations: getSecondaryLocations(ref, value),
};
context.report({
message: JSON.stringify(encodedMessage),
(0, locations_1.report)(context, {
messageId: 'refactorBooleanExpression',
data: {
value,
},
node: id,
});
}, getSecondaryLocations(ref, value), message);
}

@@ -199,0 +203,0 @@ function getSecondaryLocations(ref, truthy) {

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -26,10 +26,14 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const message = 'This branch duplicates the one on line {{line}}';
const rule = {
meta: {
messages: {
duplicatedBranch: message,
sonarRuntime: '{{sonarRuntimeData}}',
},
type: 'problem',
docs: {
description: 'Related "if/else if" statements should not have the same condition',
category: 'Possible Errors',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -50,10 +54,13 @@ schema: [

while (statement) {
if (nodes_1.isIfStatement(statement)) {
if (equivalence_1.areEquivalent(condition, statement.test, context.getSourceCode())) {
if ((0, nodes_1.isIfStatement)(statement)) {
if ((0, equivalence_1.areEquivalent)(condition, statement.test, context.getSourceCode())) {
const line = ifStmt.loc && ifStmt.loc.start.line;
if (line && condition.loc) {
locations_1.report(context, {
message: `This branch duplicates the one on line ${line}`,
(0, locations_1.report)(context, {
messageId: 'duplicatedBranch',
data: {
line,
},
node: statement.test,
}, [locations_1.issueLocation(condition.loc, condition.loc, 'Original')]);
}, [(0, locations_1.issueLocation)(condition.loc, condition.loc, 'Original')], message);
}

@@ -60,0 +67,0 @@ }

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -40,3 +40,2 @@ "use strict";

]);
const message = (operator) => `Correct one of the identical sub-expressions on both sides of operator "${operator}"`;
function hasRelevantOperator(node) {

@@ -47,15 +46,19 @@ return (RELEVANT_OPERATOR_TOKEN_KINDS.has(node.operator) ||

function hasIdentifierOperands(node) {
return nodes_1.isIdentifier(node.left) && nodes_1.isIdentifier(node.right);
return (0, nodes_1.isIdentifier)(node.left) && (0, nodes_1.isIdentifier)(node.right);
}
function isOneOntoOneShifting(node) {
return node.operator === '<<' && nodes_1.isLiteral(node.left) && node.left.value === 1;
return node.operator === '<<' && (0, nodes_1.isLiteral)(node.left) && node.left.value === 1;
}
const message = 'Correct one of the identical sub-expressions on both sides of operator "{{operator}}"';
const rule = {
meta: {
messages: {
correctIdenticalSubExpressions: message,
sonarRuntime: '{{sonarRuntimeData}}',
},
type: 'problem',
docs: {
description: 'Identical expressions should not be used on both sides of a binary operator',
category: 'Possible Errors',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -81,11 +84,14 @@ schema: [

!isOneOntoOneShifting(expr) &&
equivalence_1.areEquivalent(expr.left, expr.right, context.getSourceCode())) {
(0, equivalence_1.areEquivalent)(expr.left, expr.right, context.getSourceCode())) {
const secondaryLocations = [];
if (expr.left.loc) {
secondaryLocations.push(locations_1.issueLocation(expr.left.loc));
secondaryLocations.push((0, locations_1.issueLocation)(expr.left.loc));
}
locations_1.report(context, {
message: message(expr.operator),
(0, locations_1.report)(context, {
messageId: 'correctIdenticalSubExpressions',
data: {
operator: expr.operator,
},
node: isSonarRuntime() ? expr.right : expr,
}, secondaryLocations);
}, secondaryLocations, message);
}

@@ -92,0 +98,0 @@ }

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -25,11 +25,14 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const message = (line) => `Update this function so that its implementation is not identical to the one on line ${line}.`;
const message = 'Update this function so that its implementation is not identical to the one on line {{line}}.';
const rule = {
meta: {
messages: {
identicalFunctions: message,
sonarRuntime: '{{sonarRuntimeData}}',
},
type: 'problem',
docs: {
description: 'Functions should not have identical implementations',
category: 'Possible Errors',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -68,13 +71,16 @@ schema: [

const originalFunction = functions[j].function;
if (equivalence_1.areEquivalent(duplicatingFunction.body, originalFunction.body, context.getSourceCode()) &&
if ((0, equivalence_1.areEquivalent)(duplicatingFunction.body, originalFunction.body, context.getSourceCode()) &&
originalFunction.loc) {
const loc = locations_1.getMainFunctionTokenLocation(duplicatingFunction, functions[i].parent, context);
const originalFunctionLoc = locations_1.getMainFunctionTokenLocation(originalFunction, functions[j].parent, context);
const loc = (0, locations_1.getMainFunctionTokenLocation)(duplicatingFunction, functions[i].parent, context);
const originalFunctionLoc = (0, locations_1.getMainFunctionTokenLocation)(originalFunction, functions[j].parent, context);
const secondaryLocations = [
locations_1.issueLocation(originalFunctionLoc, originalFunctionLoc, 'Original implementation'),
(0, locations_1.issueLocation)(originalFunctionLoc, originalFunctionLoc, 'Original implementation'),
];
locations_1.report(context, {
message: message(String(originalFunction.loc.start.line)),
(0, locations_1.report)(context, {
messageId: 'identicalFunctions',
data: {
line: originalFunction.loc.start.line,
},
loc,
}, secondaryLocations);
}, secondaryLocations, message);
break;

@@ -81,0 +87,0 @@ }

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -172,12 +172,16 @@ "use strict";

meta: {
messages: {
useForEach: `Consider using "forEach" instead of "map" as its return value is not being used here.`,
returnValueMustBeUsed: 'The return value of "{{methodName}}" must be used.',
},
schema: [],
type: 'problem',
docs: {
description: 'Return values from functions without side effects should not be ignored',
category: 'Possible Errors',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},
},
create(context) {
if (!parser_services_1.isRequiredParserServices(context.parserServices)) {
if (!(0, parser_services_1.isRequiredParserServices)(context.parserServices)) {
return {};

@@ -199,6 +203,3 @@ }

!isReplaceWithCallback(methodName, call.arguments, services)) {
context.report({
message: message(methodName),
node,
});
context.report(reportDescriptor(methodName, node));
}

@@ -213,3 +214,3 @@ }

if (methodName === 'replace' && callArguments.length > 1) {
const type = utils_1.getTypeFromTreeNode(callArguments[1], services);
const type = (0, utils_1.getTypeFromTreeNode)(callArguments[1], services);
const typeNode = services.program.getTypeChecker().typeToTypeNode(type, undefined, undefined);

@@ -224,8 +225,15 @@ // dynamically import 'typescript' as classic 'import' will fail if project not using 'typescript' parser

}
function message(methodName) {
function reportDescriptor(methodName, node) {
if (methodName === 'map') {
return `Consider using "forEach" instead of "map" as its return value is not being used here.`;
return {
messageId: 'useForEach',
node,
};
}
else {
return `The return value of "${methodName}" must be used.`;
return {
messageId: 'returnValueMustBeUsed',
node,
data: { methodName },
};
}

@@ -232,0 +240,0 @@ }

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -24,3 +24,2 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const MESSAGE = 'Use the opposite operator ({{invertedOperator}}) instead.';
const invertedOperators = {

@@ -38,8 +37,11 @@ '==': '!=',

meta: {
messages: {
useOppositeOperator: 'Use the opposite operator ({{invertedOperator}}) instead.',
},
schema: [],
type: 'suggestion',
docs: {
description: 'Boolean checks should not be inverted',
category: 'Best Practices',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -56,3 +58,3 @@ fixable: 'code',

var _a;
if (unaryExpression.operator === '!' && nodes_1.isBinaryExpression(unaryExpression.argument)) {
if (unaryExpression.operator === '!' && (0, nodes_1.isBinaryExpression)(unaryExpression.argument)) {
const condition = unaryExpression.argument;

@@ -65,3 +67,3 @@ const invertedOperator = invertedOperators[condition.operator];

context.report({
message: MESSAGE,
messageId: 'useOppositeOperator',
data: { invertedOperator },

@@ -68,0 +70,0 @@ node: unaryExpression,

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -23,11 +23,13 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const message = 'Refactor the code to eliminate this nested "switch".';
const rule = {
meta: {
messages: {
removeNestedSwitch: 'Refactor the code to eliminate this nested "switch".',
},
schema: [],
type: 'suggestion',
docs: {
description: '"switch" statements should not be nested',
category: 'Best Practices',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -42,3 +44,3 @@ },

context.report({
message,
messageId: 'removeNestedSwitch',
loc: switchToken.loc,

@@ -45,0 +47,0 @@ });

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -23,11 +23,13 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const message = 'Refactor this code to not use nested template literals.';
const rule = {
meta: {
messages: {
nestedTemplateLiterals: 'Refactor this code to not use nested template literals.',
},
schema: [],
type: 'suggestion',
docs: {
description: 'Template literals should not be nested',
category: 'Best Practices',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -39,3 +41,3 @@ },

context.report({
message,
messageId: 'nestedTemplateLiterals',
node,

@@ -42,0 +44,0 @@ });

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -26,10 +26,14 @@ "use strict";

meta: {
messages: {
refactorLoop: 'Refactor this loop to do more than one iteration.',
},
schema: [],
type: 'problem',
docs: {
description: 'Loops with at most one iteration should be refactored',
category: 'Possible Errors',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},
},
// @ts-ignore The typings of @typescript-eslint/experimental-utils does not contain the 'onX' methods.
create(context) {

@@ -63,3 +67,3 @@ const loopingNodes = new Set();

onCodePathSegmentLoop(_, toSegment, node) {
if (nodes_1.isContinueStatement(node)) {
if ((0, nodes_1.isContinueStatement)(node)) {
loopsAndTheirSegments.forEach(({ segments, loop }) => {

@@ -79,3 +83,3 @@ if (segments.includes(toSegment)) {

context.report({
message: 'Refactor this loop to do more than one iteration.',
messageId: 'refactorLoop',
loc: context.getSourceCode().getFirstToken(loop).loc,

@@ -90,3 +94,3 @@ });

// and the corresponding event node is that "continue" statement. Current implementation is based on the fact
// that the "onCodePathSegmentLoop" event is triggerent with a loop node. To work this special case around,
// that the "onCodePathSegmentLoop" event is triggered with a loop node. To work this special case around,
// we visit loop children and collect corresponding path segments as these segments are "toSegment"

@@ -93,0 +97,0 @@ // in "onCodePathSegmentLoop" event.

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -24,11 +24,13 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const MESSAGE = 'Remove the unnecessary boolean literal.';
const rule = {
meta: {
messages: {
removeUnnecessaryBoolean: 'Remove the unnecessary boolean literal.',
},
schema: [],
type: 'suggestion',
docs: {
description: 'Boolean literals should not be redundant',
category: 'Best Practices',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -54,3 +56,3 @@ },

if (expression.operator === '||' &&
((nodes_1.isConditionalExpression(parent) && parent.test === expression) || nodes_1.isIfStatement(parent))) {
(((0, nodes_1.isConditionalExpression)(parent) && parent.test === expression) || (0, nodes_1.isIfStatement)(parent))) {
checkBooleanLiteral(expression.right);

@@ -67,4 +69,4 @@ }

function checkBooleanLiteral(expression) {
if (nodes_1.isBooleanLiteral(expression)) {
context.report({ message: MESSAGE, node: expression });
if ((0, nodes_1.isBooleanLiteral)(expression)) {
context.report({ messageId: 'removeUnnecessaryBoolean', node: expression });
}

@@ -71,0 +73,0 @@ }

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -23,12 +23,14 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const message = 'Remove this redundant jump.';
const loops = 'WhileStatement, ForStatement, DoWhileStatement, ForInStatement, ForOfStatement';
const rule = {
meta: {
messages: {
removeRedundantJump: 'Remove this redundant jump.',
},
schema: [],
type: 'suggestion',
docs: {
description: 'Jump statements should not be redundant',
category: 'Best Practices',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -43,3 +45,3 @@ },

context.report({
message,
messageId: 'removeRedundantJump',
node,

@@ -46,0 +48,0 @@ });

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -22,12 +22,16 @@ "use strict";

// https://sonarsource.github.io/rspec/#/rspec/S3972
const docs_url_1 = require("../utils/docs-url");
const locations_1 = require("../utils/locations");
const docs_url_1 = require("../utils/docs-url");
const message = 'Move this "if" to a new line or add the missing "else".';
const rule = {
meta: {
messages: {
sameLineCondition: message,
sonarRuntime: '{{sonarRuntimeData}}',
},
type: 'problem',
docs: {
description: 'Conditionals should start on new lines',
category: 'Possible Errors',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -54,8 +58,6 @@ schema: [

const followingIfToken = sourceCode.getFirstToken(followingIf);
context.report({
message: locations_1.toEncodedMessage(`Move this "if" to a new line or add the missing "else".`, [
precedingIfLastToken,
]),
(0, locations_1.report)(context, {
messageId: 'sameLineCondition',
loc: followingIfToken.loc,
});
}, [(0, locations_1.issueLocation)(precedingIfLastToken.loc)], message);
}

@@ -62,0 +64,0 @@ });

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -23,11 +23,13 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const MESSAGE = '"switch" statements should have at least 3 "case" clauses';
const rule = {
meta: {
messages: {
smallSwitch: '"switch" statements should have at least 3 "case" clauses',
},
schema: [],
type: 'suggestion',
docs: {
description: '"switch" statements should have at least 3 "case" clauses',
category: 'Best Practices',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -44,3 +46,6 @@ },

if (firstToken) {
context.report({ message: MESSAGE, loc: firstToken.loc });
context.report({
messageId: 'smallSwitch',
loc: firstToken.loc,
});
}

@@ -47,0 +52,0 @@ }

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -24,11 +24,13 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const message = "Either use this collection's contents or remove the collection.";
const rule = {
meta: {
messages: {
unusedCollection: "Either use this collection's contents or remove the collection.",
},
schema: [],
type: 'problem',
docs: {
description: 'Collection and array contents should be used',
category: 'Possible Errors',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -43,3 +45,3 @@ },

context.report({
message,
messageId: 'unusedCollection',
node: unusedArray.identifiers[0],

@@ -46,0 +48,0 @@ });

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -47,8 +47,11 @@ "use strict";

meta: {
messages: {
removeUseOfOutput: 'Remove this use of the output from "{{name}}"; "{{name}}" doesn\'t return anything.',
},
schema: [],
type: 'problem',
docs: {
description: "The output of functions that don't return anything should not be used",
category: 'Possible Errors',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -76,3 +79,3 @@ },

const { init } = definition.node;
if (init && (nodes_1.isFunctionExpression(init) || nodes_1.isArrowFunctionExpression(init))) {
if (init && ((0, nodes_1.isFunctionExpression)(init) || (0, nodes_1.isArrowFunctionExpression)(init))) {
callExpressionsToCheck.set(reference.identifier, init);

@@ -104,3 +107,3 @@ }

func.generator ||
(nodes_1.isBlockStatement(func.body) && func.body.body.length === 0)) {
((0, nodes_1.isBlockStatement)(func.body) && func.body.body.length === 0)) {
functionsWithReturnValue.add(func);

@@ -113,3 +116,3 @@ }

context.report({
message: `Remove this use of the output from "{{name}}"; "{{name}}" doesn't return anything.`,
messageId: 'removeUseOfOutput',
node: callee,

@@ -116,0 +119,0 @@ data: { name: callee.name },

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -25,11 +25,13 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const MESSAGE = 'Add logic to this catch clause or eliminate it and rethrow the exception automatically.';
const rule = {
meta: {
messages: {
uselessCatch: 'Add logic to this catch clause or eliminate it and rethrow the exception automatically.',
},
schema: [],
type: 'suggestion',
docs: {
description: '"catch" clauses should do more than rethrow',
category: 'Best Practices',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -50,3 +52,3 @@ },

context.report({
message: MESSAGE,
messageId: 'uselessCatch',
loc: catchKeyword.loc,

@@ -57,8 +59,8 @@ });

function onlyRethrows(statement, catchParam, sourceCode) {
return (nodes_1.isThrowStatement(statement) &&
return ((0, nodes_1.isThrowStatement)(statement) &&
catchParam !== null &&
statement.argument !== null &&
equivalence_1.areEquivalent(catchParam, statement.argument, sourceCode));
(0, equivalence_1.areEquivalent)(catchParam, statement.argument, sourceCode));
}
module.exports = rule;
//# sourceMappingURL=no-useless-catch.js.map

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -25,8 +25,11 @@ "use strict";

meta: {
messages: {
useExistingOperator: 'Was "{{operator}}=" meant instead?',
},
schema: [],
type: 'problem',
docs: {
description: 'Non-existent operators "=+", "=-" and "=!" should not be used',
category: 'Possible Errors',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -63,3 +66,6 @@ },

context.report({
message: `Was "${unaryNode.operator}=" meant instead?`,
messageId: 'useExistingOperator',
data: {
operator: unaryNode.operator,
},
loc: { start: assignmentOperatorToken.loc.start, end: unaryOperatorToken.loc.end },

@@ -66,0 +72,0 @@ });

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -26,8 +26,11 @@ "use strict";

meta: {
messages: {
doImmediateAction: 'Immediately {{action}} this expression instead of assigning it to the temporary variable "{{variable}}".',
},
schema: [],
type: 'suggestion',
docs: {
description: 'Local variables should not be declared and then immediately returned or thrown',
category: 'Best Practices',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -61,3 +64,7 @@ fixable: 'code',

context.report({
message: formatMessage(last, returnedIdentifier.name),
messageId: 'doImmediateAction',
data: {
action: (0, nodes_1.isReturnStatement)(last) ? 'return' : 'throw',
variable: returnedIdentifier.name,
},
node: declaredIdentifier.init,

@@ -84,5 +91,5 @@ fix: fixer => fix(fixer, last, lastButOne, declaredIdentifier.init, returnedIdentifier),

function getOnlyReturnedVariable(node) {
return (nodes_1.isReturnStatement(node) || nodes_1.isThrowStatement(node)) &&
return ((0, nodes_1.isReturnStatement)(node) || (0, nodes_1.isThrowStatement)(node)) &&
node.argument &&
nodes_1.isIdentifier(node.argument)
(0, nodes_1.isIdentifier)(node.argument)
? node.argument

@@ -92,5 +99,5 @@ : undefined;

function getOnlyDeclaredVariable(node) {
if (nodes_1.isVariableDeclaration(node) && node.declarations.length === 1) {
if ((0, nodes_1.isVariableDeclaration)(node) && node.declarations.length === 1) {
const { id, init } = node.declarations[0];
if (nodes_1.isIdentifier(id) && init && !id.typeAnnotation) {
if ((0, nodes_1.isIdentifier)(id) && init && !id.typeAnnotation) {
return { id, init };

@@ -101,6 +108,2 @@ }

}
function formatMessage(node, variable) {
const action = nodes_1.isReturnStatement(node) ? 'return' : 'throw';
return `Immediately ${action} this expression instead of assigning it to the temporary variable "${variable}".`;
}
function getVariables(context) {

@@ -107,0 +110,0 @@ const { variableScope, variables: currentScopeVariables } = context.getScope();

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -25,11 +25,13 @@ "use strict";

const docs_url_1 = require("../utils/docs-url");
const MESSAGE = 'Declare one or more properties of this object inside of the object literal syntax instead of using separate statements.';
const rule = {
meta: {
messages: {
declarePropertiesInsideObject: 'Declare one or more properties of this object inside of the object literal syntax instead of using separate statements.',
},
schema: [],
type: 'suggestion',
docs: {
description: 'Object literal syntax should be used',
category: 'Best Practices',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -41,3 +43,3 @@ },

Program: (node) => {
const statements = node.body.filter((statement) => !nodes_1.isModuleDeclaration(statement));
const statements = node.body.filter((statement) => !(0, nodes_1.isModuleDeclaration)(statement));
checkObjectInitialization(statements, context);

@@ -53,5 +55,5 @@ },

// eslint-disable-next-line sonarjs/no-collapsible-if
if (objectDeclaration && nodes_1.isIdentifier(objectDeclaration.id)) {
if (objectDeclaration && (0, nodes_1.isIdentifier)(objectDeclaration.id)) {
if (isPropertyAssignment(statements[index + 1], objectDeclaration.id, context.getSourceCode())) {
context.report({ message: MESSAGE, node: objectDeclaration });
context.report({ messageId: 'declarePropertiesInsideObject', node: objectDeclaration });
}

@@ -63,3 +65,3 @@ }

function getObjectDeclaration(statement) {
if (nodes_1.isVariableDeclaration(statement)) {
if ((0, nodes_1.isVariableDeclaration)(statement)) {
return statement.declarations.find(declaration => !!declaration.init && isEmptyObjectExpression(declaration.init));

@@ -70,11 +72,11 @@ }

function isEmptyObjectExpression(expression) {
return nodes_1.isObjectExpression(expression) && expression.properties.length === 0;
return (0, nodes_1.isObjectExpression)(expression) && expression.properties.length === 0;
}
function isPropertyAssignment(statement, objectIdentifier, sourceCode) {
if (nodes_1.isExpressionStatement(statement) && nodes_1.isAssignmentExpression(statement.expression)) {
if ((0, nodes_1.isExpressionStatement)(statement) && (0, nodes_1.isAssignmentExpression)(statement.expression)) {
const { left, right } = statement.expression;
if (nodes_1.isMemberExpression(left)) {
if ((0, nodes_1.isMemberExpression)(left)) {
return (!left.computed &&
isSingleLineExpression(right, sourceCode) &&
equivalence_1.areEquivalent(left.object, objectIdentifier, sourceCode));
(0, equivalence_1.areEquivalent)(left.object, objectIdentifier, sourceCode));
}

@@ -81,0 +83,0 @@ }

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -6,8 +6,11 @@ "use strict";

meta: {
messages: {
replaceIfThenElseByReturn: 'Replace this if-then-else statement by a single return statement.',
},
schema: [],
type: 'suggestion',
docs: {
description: 'Return of boolean expressions should not be wrapped into an "if-then-else" statement',
category: 'Best Practices',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -21,3 +24,3 @@ },

// ignore `else if`
!nodes_1.isIfStatement(ifStmt.parent) &&
!(0, nodes_1.isIfStatement)(ifStmt.parent) &&
// `ifStmt.alternate` can be `null`, replace it with `undefined` in this case

@@ -27,3 +30,3 @@ returnsBoolean(ifStmt.alternate || undefined) &&

context.report({
message: 'Replace this if-then-else statement by a single return statement.',
messageId: 'replaceIfThenElseByReturn',
node: ifStmt,

@@ -39,3 +42,3 @@ });

function isBlockReturningBooleanLiteral(statement) {
return (nodes_1.isBlockStatement(statement) &&
return ((0, nodes_1.isBlockStatement)(statement) &&
statement.body.length === 1 &&

@@ -46,3 +49,3 @@ isSimpleReturnBooleanLiteral(statement.body[0]));

// `statement.argument` can be `null`, replace it with `undefined` in this case
return nodes_1.isReturnStatement(statement) && nodes_1.isBooleanLiteral(statement.argument || undefined);
return (0, nodes_1.isReturnStatement)(statement) && (0, nodes_1.isBooleanLiteral)(statement.argument || undefined);
}

@@ -49,0 +52,0 @@ },

@@ -1,3 +0,3 @@

import { Rule } from '../utils/types';
declare const rule: Rule.RuleModule;
import type { TSESLint } from '@typescript-eslint/experimental-utils';
declare const rule: TSESLint.RuleModule<string, string[]>;
export = rule;

@@ -25,8 +25,11 @@ "use strict";

meta: {
messages: {
replaceForWithWhileLoop: 'Replace this "for" loop with a "while" loop.',
},
schema: [],
type: 'suggestion',
docs: {
description: 'A "while" loop should be used instead of a "for" loop',
category: 'Best Practices',
recommended: 'error',
url: docs_url_1.default(__filename),
url: (0, docs_url_1.default)(__filename),
},

@@ -42,3 +45,3 @@ fixable: 'code',

context.report({
message: `Replace this "for" loop with a "while" loop.`,
messageId: `replaceForWithWhileLoop`,
loc: forKeyword.loc,

@@ -45,0 +48,0 @@ fix: getFix(forLoop),

@@ -11,3 +11,3 @@ "use strict";

while (statement) {
if (nodes_1.isIfStatement(statement)) {
if ((0, nodes_1.isIfStatement)(statement)) {
branches.push(statement.consequent);

@@ -14,0 +14,0 @@ statement = statement.alternate;

import type { TSESTree, TSESLint } from '@typescript-eslint/experimental-utils';
import { Rule } from './types';
declare type Writeable<T> = {
-readonly [P in keyof T]: T[P];
};
export declare type MutableReportDescriptor = Writeable<TSESLint.ReportDescriptor<string>>;
export interface IssueLocation {

@@ -9,2 +12,3 @@ column: number;

message?: string;
data?: Record<string, unknown>;
}

@@ -22,3 +26,3 @@ export interface EncodedMessage {

*/
export declare function getMainFunctionTokenLocation(fn: TSESTree.FunctionLike, parent: TSESTree.Node | undefined, context: Rule.RuleContext): TSESTree.SourceLocation;
export declare function getMainFunctionTokenLocation<T = string>(fn: TSESTree.FunctionLike, parent: TSESTree.Node | undefined, context: TSESLint.RuleContext<string, T[]>): TSESTree.SourceLocation;
/**

@@ -29,10 +33,10 @@ * Wrapper for `context.report`, supporting secondary locations and cost.

*/
export declare function report(context: Rule.RuleContext, reportDescriptor: Rule.ReportDescriptor, secondaryLocations?: IssueLocation[], cost?: number): void;
export declare function report<T = string>(context: TSESLint.RuleContext<string, T[]>, reportDescriptor: MutableReportDescriptor, secondaryLocations: IssueLocation[], message: string, cost?: number): void;
/**
* Converts `SourceLocation` range into `IssueLocation`
*/
export declare function issueLocation(startLoc: TSESTree.SourceLocation, endLoc?: TSESTree.SourceLocation, message?: string): IssueLocation;
export declare function toEncodedMessage(message: string, secondaryLocationsHolder: Array<TSESLint.AST.Token | TSESTree.Node>, secondaryMessages?: string[], cost?: number): string;
export declare function issueLocation(startLoc: TSESTree.SourceLocation, endLoc?: TSESTree.SourceLocation, message?: string, data?: Record<string, unknown>): IssueLocation;
export declare function toSecondaryLocation(locationHolder: TSESLint.AST.Token | TSESTree.Node, message?: string): IssueLocation;
export declare function getFirstTokenAfter(node: TSESTree.Node, context: Rule.RuleContext): TSESLint.AST.Token | null;
export declare function getFirstToken(node: TSESTree.Node, context: Rule.RuleContext): TSESLint.AST.Token;
export declare function getFirstTokenAfter<T = string>(node: TSESTree.Node, context: TSESLint.RuleContext<string, T[]>): TSESLint.AST.Token | null;
export declare function getFirstToken<T = string>(node: TSESTree.Node, context: TSESLint.RuleContext<string, T[]>): TSESLint.AST.Token;
export {};

@@ -22,3 +22,3 @@ "use strict";

Object.defineProperty(exports, "__esModule", { value: true });
exports.getFirstToken = exports.getFirstTokenAfter = exports.toSecondaryLocation = exports.toEncodedMessage = exports.issueLocation = exports.report = exports.getMainFunctionTokenLocation = void 0;
exports.getFirstToken = exports.getFirstTokenAfter = exports.toSecondaryLocation = exports.issueLocation = exports.report = exports.getMainFunctionTokenLocation = void 0;
/**

@@ -67,16 +67,38 @@ * Returns a location of the "main" function token:

*/
function report(context, reportDescriptor, secondaryLocations = [], cost) {
const { message } = reportDescriptor;
if (context.options[context.options.length - 1] === 'sonar-runtime') {
const encodedMessage = { secondaryLocations, message: message, cost };
reportDescriptor.message = JSON.stringify(encodedMessage);
function report(context, reportDescriptor, secondaryLocations, message, cost) {
if (context.options[context.options.length - 1] !== 'sonar-runtime') {
context.report(reportDescriptor);
return;
}
const encodedMessage = {
secondaryLocations,
message: expandMessage(message, reportDescriptor.data),
cost,
};
reportDescriptor.messageId = 'sonarRuntime';
if (reportDescriptor.data === undefined) {
reportDescriptor.data = {};
}
reportDescriptor.data.sonarRuntimeData =
JSON.stringify(encodedMessage);
context.report(reportDescriptor);
}
exports.report = report;
function expandMessage(message, reportDescriptorData) {
let expandedMessage = message;
if (reportDescriptorData !== undefined) {
for (const [key, value] of Object.entries(reportDescriptorData)) {
expandedMessage = replaceAll(expandedMessage, `{{${key}}}`, value.toString());
}
}
return expandedMessage;
}
function replaceAll(target, search, replacement) {
return target.split(search).join(replacement);
}
/**
* Converts `SourceLocation` range into `IssueLocation`
*/
function issueLocation(startLoc, endLoc = startLoc, message = '') {
return {
function issueLocation(startLoc, endLoc = startLoc, message = '', data = {}) {
const issueLocation = {
line: startLoc.start.line,

@@ -88,13 +110,8 @@ column: startLoc.start.column,

};
if (data !== undefined && Object.keys(data).length > 0) {
issueLocation.data = data;
}
return issueLocation;
}
exports.issueLocation = issueLocation;
function toEncodedMessage(message, secondaryLocationsHolder, secondaryMessages, cost) {
const encodedMessage = {
message,
cost,
secondaryLocations: secondaryLocationsHolder.map((locationHolder, index) => toSecondaryLocation(locationHolder, secondaryMessages ? secondaryMessages[index] : undefined)),
};
return JSON.stringify(encodedMessage);
}
exports.toEncodedMessage = toEncodedMessage;
function toSecondaryLocation(locationHolder, message) {

@@ -101,0 +118,0 @@ const { loc } = locationHolder;

{
"name": "eslint-plugin-sonarjs",
"version": "0.10.0",
"version": "0.11.0",
"description": "SonarJS rules for ESLint",

@@ -19,3 +19,3 @@ "main": "lib/index.js",

"engines": {
"node": ">=10"
"node": ">=12"
},

@@ -34,20 +34,21 @@ "scripts": {

"peerDependencies": {
"eslint": "^5.0.0 || ^6.0.0 || ^7.0.0"
"eslint": "^5.0.0 || ^6.0.0 || ^7.0.0|| ^8.0.0"
},
"devDependencies": {
"@types/jest": "26.0.20",
"@types/eslint": "7.29.0",
"@types/jest": "27.0.2",
"@types/lodash": "4.14.106",
"@types/minimist": "1.2.0",
"@types/node": "14.14.25",
"@typescript-eslint/experimental-utils": "4.28.0",
"@typescript-eslint/parser": "4.28.0",
"@typescript-eslint/experimental-utils": "5.3.1",
"@typescript-eslint/parser": "5.3.1",
"babel-eslint": "8.2.2",
"eslint": "7.19.0",
"eslint": "8.1.0",
"eslint-config-prettier": "2.9.0",
"eslint-plugin-import": "2.18.2",
"eslint-plugin-import": "2.25.2",
"eslint-plugin-notice": "0.6.7",
"eslint-plugin-sonarjs": "0.9.1",
"jest": "26.6.3",
"eslint-plugin-sonarjs": "0.10.0",
"jest": "27.3.1",
"jest-sonar-reporter": "2.0.0",
"lint-staged": "7.3.0",
"lint-staged": "12.1.2",
"lodash": "4.17.21",

@@ -57,5 +58,5 @@ "minimist": "1.2.3",

"rimraf": "2.6.2",
"ts-jest": "26.5.1",
"ts-jest": "27.0.7",
"ts-node": "9.1.1",
"typescript": "4.3.4"
"typescript": "4.5.2"
},

@@ -62,0 +63,0 @@ "prettier": {

@@ -84,4 +84,4 @@ # eslint-plugin-sonarjs [![npm version](https://badge.fury.io/js/eslint-plugin-sonarjs.svg)](https://badge.fury.io/js/eslint-plugin-sonarjs) [![Build Status](https://api.cirrus-ci.com/github/SonarSource/eslint-plugin-sonarjs.svg?branch=master)](https://cirrus-ci.com/github/SonarSource/eslint-plugin-sonarjs) [![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=eslint-plugin-sonarjs&metric=alert_status)](https://sonarcloud.io/dashboard?id=eslint-plugin-sonarjs) [![Coverage](https://sonarcloud.io/api/project_badges/measure?project=eslint-plugin-sonarjs&metric=coverage)](https://sonarcloud.io/dashboard?id=eslint-plugin-sonarjs)

* Node.js (>=10.x).
* ESLint 5.x, 6.x or 7.x (peer dependency for the plugin).
* Node.js (>=12.x).
* ESLint 5.x, 6.x, 7.x or 8.x (peer dependency for the plugin).

@@ -88,0 +88,0 @@ ## Usage

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc