Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
function checkRedundantParentheses(
sourceCode: SourceCode,
node: estree.Node,
context: Rule.RuleContext,
) {
const parenthesesPairsAroundNode = getParenthesesPairsAround(sourceCode, node, node);
const parent = getParent(context);
// Ignore parentheses pair from the parent node
if (!!parent && isInParentNodeParentheses(node, parent)) {
parenthesesPairsAroundNode.pop();
}
// One pair of parentheses is allowed for readability purposes
parenthesesPairsAroundNode.shift();
parenthesesPairsAroundNode.forEach(parentheses => {
context.report({
message: toEncodedMessage(`Remove these useless parentheses.`, [
parentheses.closingParenthesis,
]),
loc: parentheses.openingParenthesis.loc,
});
});
function getSymbol(
id: estree.Identifier,
services: RequiredParserServices,
context: Rule.RuleContext,
tc: tsTypes.TypeChecker,
) {
let symbol: tsTypes.Symbol | undefined;
const tsId = services.esTreeNodeToTSNodeMap.get(id as TSESTree.Node) as tsTypes.Identifier;
const parent = services.esTreeNodeToTSNodeMap.get(getParent(
context,
) as TSESTree.Node) as tsTypes.Node;
if (parent.kind === ts.SyntaxKind.BindingElement) {
symbol = tc.getTypeAtLocation(parent.parent).getProperty(tsId.text);
} else if (
(isPropertyAssignment(parent) && parent.name === tsId) ||
(isShorthandPropertyAssignment(parent) && parent.name === tsId)
) {
try {
symbol = tc.getPropertySymbolOfDestructuringAssignment(tsId);
} catch (e) {
// do nothing, we are in object literal, not destructuring
// no obvious easy way to check that in advance
}
} else {
symbol = tc.getSymbolAtLocation(tsId);
":statement": (node: estree.Node) => {
const parent = getParent(context);
if (parent && isIfStatement(parent)) {
// we visit 'consequent' and 'alternate' and not if-statement directly in order to get scope for 'consequent'
const currentScope = context.getScope();
if (parent.consequent === node) {
const { truthy, falsy } = collectKnownIdentifiers(parent.test);
truthyMap.set(parent.consequent, transformAndFilter(truthy, currentScope));
falsyMap.set(parent.consequent, transformAndFilter(falsy, currentScope));
} else if (parent.alternate === node && isIdentifier(parent.test)) {
falsyMap.set(parent.alternate, transformAndFilter([parent.test], currentScope));
}
}
},
const visitNode = (node: estree.Node) => {
let token: ComplexityToken | undefined | null;
if (isFunctionNode(node)) {
if (node !== this.root) {
return;
} else {
token = { loc: getMainFunctionTokenLocation(node, this.parent, this.context) };
}
} else {
switch (node.type) {
case "ConditionalExpression":
token = this.context
.getSourceCode()
.getFirstTokenBetween(node.test, node.consequent, token => token.value === "?");
break;
case "SwitchCase":
// ignore default case
if (!node.test) {
break;
}
case "IfStatement":
case "ForStatement":
case "ForInStatement":
":statement": (node: estree.Node) => {
const parent = getParent(context);
if (parent && isIfStatement(parent)) {
// we visit 'consequent' and 'alternate' and not if-statement directly in order to get scope for 'consequent'
const currentScope = context.getScope();
if (parent.consequent === node) {
const { truthy, falsy } = collectKnownIdentifiers(parent.test);
truthyMap.set(parent.consequent, transformAndFilter(truthy, currentScope));
falsyMap.set(parent.consequent, transformAndFilter(falsy, currentScope));
} else if (parent.alternate === node && isIdentifier(parent.test)) {
falsyMap.set(parent.alternate, transformAndFilter([parent.test], currentScope));
}
}
},
"error",
{
requireReturn: false,
requireReturnDescription: false
}
],
"valid-typeof": "error",
"@swissquote/swissquote/sonarjs/no-duplicate-string": ["error", 10]
}
};
// Eslint can't load plugins transitively (from a shared config)
// So we have to include the file ourselves and include the rules as if they were ours.
// Solution proposed by @nzakas himself : https://github.com/eslint/eslint/issues/3458#issuecomment-257161846
// replaces `extends: "plugin:sonarjs/recommended",`
const sonarRules = require("eslint-plugin-sonarjs").configs.recommended.rules;
Object.keys(sonarRules).forEach(ruleName => {
// Only define the rules we don't have configured yet
const key = `@swissquote/swissquote/${ruleName}`;
if (!module.exports.rules.hasOwnProperty(key)) {
module.exports.rules[key] = sonarRules[ruleName];
}
});
function isAllowedCallbacks(context: Rule.RuleContext) {
const parent = getParent(context);
if (parent && parent.type === "CallExpression") {
const callee = parent.callee;
if (callee.type === "MemberExpression") {
return (
callee.property.type === "Identifier" && allowedCallbacks.includes(callee.property.name)
);
}
}
return false;
}
function raiseIssue(context: Rule.RuleContext): void {
const deleteKeyword = context.getSourceCode().getFirstToken(getParent(context)!);
context.report({
message: `Remove this use of "delete".`,
loc: deleteKeyword!.loc,
});
}
function checkCastedType(
node: FunctionLikeDeclaration,
expression: TSESTree.Expression,
context: Rule.RuleContext,
) {
const sourceCode = context.getSourceCode();
const castedType = getCastTupleFromMemberExpression(expression);
if (castedType && (castedType[1] as TSESTree.Node).type !== "TSAnyKeyword") {
const nOfParam = node.params.length;
if (nOfParam === 1 || (nOfParam === 0 && castedType[0].type === "ThisExpression")) {
const castedExpressionText = sourceCode.getText(castedType[0]);
const castedTypeText = sourceCode.getText(castedType[1]);
context.report({
message: `Declare this function return type using type predicate "${castedExpressionText} is ${castedTypeText}".`,
loc: getMainFunctionTokenLocation(node as estree.Function, getParent(context), context),
});
}
}
}
function isElseIf(node: estree.IfStatement, context: Rule.RuleContext) {
const parent = getParent(context);
return parent && parent.type === "IfStatement" && parent.alternate === node;
}