How to use eslint-plugin-sonarjs - 10 common examples

To help you get started, we’ve selected a few eslint-plugin-sonarjs examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github SonarSource / SonarJS / eslint-bridge / src / rules / no-redundant-parentheses.ts View on Github external
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,
    });
  });
github SonarSource / SonarJS / eslint-bridge / src / rules / deprecation.ts View on Github external
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);
github SonarSource / SonarJS / eslint-bridge / src / rules / no-gratuitous-expressions.ts View on Github external
":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));
          }
        }
      },
github SonarSource / SonarJS / eslint-bridge / src / rules / cyclomatic-complexity.ts View on Github external
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":
github SonarSource / SonarJS / eslint-bridge / src / rules / no-gratuitous-expressions.ts View on Github external
":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));
          }
        }
      },
github swissquote / crafty / packages / eslint-plugin-swissquote / src / best-practices.js View on Github external
"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];
  }
});
github SonarSource / SonarJS / eslint-bridge / src / rules / function-inside-loop.ts View on Github external
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;
}
github SonarSource / SonarJS / eslint-bridge / src / rules / no-array-delete.ts View on Github external
function raiseIssue(context: Rule.RuleContext): void {
  const deleteKeyword = context.getSourceCode().getFirstToken(getParent(context)!);
  context.report({
    message: `Remove this use of "delete".`,
    loc: deleteKeyword!.loc,
  });
}
github SonarSource / SonarJS / eslint-bridge / src / rules / prefer-type-guard.ts View on Github external
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),
      });
    }
  }
}
github SonarSource / SonarJS / eslint-bridge / src / rules / elseif-without-else.ts View on Github external
function isElseIf(node: estree.IfStatement, context: Rule.RuleContext) {
  const parent = getParent(context);
  return parent && parent.type === "IfStatement" && parent.alternate === node;
}