eslint-plugin-sonarjs
eslint-plugin-sonarjs copied to clipboard
Working with ESLint 9
I want to request a feature.
Projects wishing to future-proof their code are now unable to use SonarJS with the alpha versions of ESLint 9.0.0 at least in one instance because of some API changes (dropping context.getScope
; see https://eslint.org/blog/2023/09/preparing-custom-rules-eslint-v9/#context.getscope() ). This is the more serious road-block as there are no workarounds.
Hello @brettz9,
Thank you for highlighting this concern.
The migration of our ESLint plugin to ESLint's new flat config is indeed a recognized issue (https://github.com/SonarSource/eslint-plugin-sonarjs/issues/403, https://github.com/SonarSource/SonarJS/issues/3968), and we fully acknowledge its significance.
Unfortunately, providing a specific timeframe for addressing this issue is challenging at the moment. However, I will take this matter to the team for discussion, and we will consider when we can prioritize and work on it.
I appreciate your patience, and I will keep you informed of any updates.
Thank you. Just a heads up though that the API change mentioned in the original post is the most critical issue, as one can still use the package @eslint/eslintrc
to keep the legacy non-flat behavior even if you haven't yet migrated to supporting flat configs, whereas ESLint 9 won't work at all without the API fix.
ESLint 9.0.0 has been released. This plugin still does not work with it.
just hit this when upgrading to eslint 9
Same. This is really unfortunate. I tried using the FlatCompat API and it still doesn't work.
For information, we are working on it. There is no ETA yet, but as soon as we have one, we'll update this issue, so stay tuned.
This issue has been migrated to Jira. ESLINTJS-30
is there not support for eslint 9 yet?
any update?
v1.0.0 breaks with eslint v8.57.0, I think it's not backwards compatible.
Versions:
"@typescript-eslint/parser": "7.8.0",
"eslint": "8.57.0",
"eslint-plugin-sonarjs": "1.0.0",
I'm on node v20.12.2
Error:
Property "plugins" is the wrong type (expected array but got '{"sonarjs" // Basically got an object instead of an array
The whole error:
api:lint: > eslint --quiet src/**/*.ts
api:lint: Oops! Something went wrong! :(
api:lint: ESLint: 8.57.0
api:lint: Error: ESLint configuration in .eslintrc.js » plugin:sonarjs/recommended is invalid:
api:lint: - Property "plugins" is the wrong type (expected array but got `{"sonarjs":{"rules":{"cognitive-complexity":{"defaultOptions":[],"meta":{"messages":{"refactorFunction":"Refactor this function to reduce its Cognitive Complexity from {{complexityAmount}} to the {{threshold}} allowed.","sonarRuntime":"{{sonarRuntimeData}}","fileComplexity":"{{complexityAmount}}"},"type":"suggestion","docs":{"description":"Cognitive Complexity of functions should not be too high","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/cognitive-complexity.md"},"schema":[{"type":"integer","minimum":0},{"type":"string","enum":["sonar-runtime","metric"]}]},"default":{"defaultOptions":[],"meta":{"messages":{"refactorFunction":"Refactor this function to reduce its Cognitive Complexity from {{complexityAmount}} to the {{threshold}} allowed.","sonarRuntime":"{{sonarRuntimeData}}","fileComplexity":"{{complexityAmount}}"},"type":"suggestion","docs":{"description":"Cognitive Complexity of functions should not be too high","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/cognitive-complexity.md"},"schema":[{"type":"integer","minimum":0},{"type":"string","enum":["sonar-runtime","metric"]}]}}},"elseif-without-else":{"defaultOptions":[],"meta":{"messages":{"addMissingElseClause":"Add the missing \"else\" clause."},"schema":[],"type":"suggestion","docs":{"description":"\"if ... else if\" constructs should end with \"else\" clauses","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/elseif-without-else.md"}},"default":{"defaultOptions":[],"meta":{"messages":{"addMissingElseClause":"Add the missing \"else\" clause."},"schema":[],"type":"suggestion","docs":{"description":"\"if ... else if\" constructs should end with \"else\" clauses","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/elseif-without-else.md"}}}},"max-switch-cases":{"defaultOptions":[30],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/max-switch-cases.md"},"schema":[{"type":"integer","minimum":0}]},"default":{"defaultOptions":[30],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/max-switch-cases.md"},"schema":[{"type":"integer","minimum":0}]}}},"no-all-duplicated-branches":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-all-duplicated-branches.md"}},"default":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-all-duplicated-branches.md"}}}},"no-collapsible-if":{"defaultOptions":[],"meta":{"messages":{"mergeNestedIfStatement":"Merge this if statement with the nested one.","sonarRuntime":"{{sonarRuntimeData}}"},"type":"suggestion","docs":{"description":"Collapsible \"if\" statements should be merged","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-collapsible-if.md"},"schema":[{"type":"string","enum":["sonar-runtime"]}]},"default":{"defaultOptions":[],"meta":{"messages":{"mergeNestedIfStatement":"Merge this if statement with the nested one.","sonarRuntime":"{{sonarRuntimeData}}"},"type":"suggestion","docs":{"description":"Collapsible \"if\" statements should be merged","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-collapsible-if.md"},"schema":[{"type":"string","enum":["sonar-runtime"]}]}}},"no-collection-size-mischeck":{"defaultOptions":[],"meta":{"messages":{"fixCollectionSizeCheck":"Fix this expression; {{propertyName}} of \"{{objectName}}\" is always greater or equal to zero.","suggestFixedSizeCheck":"Use \"{{operator}}\" for {{operation}} check"},"schema":[],"type":"problem","hasSuggestions":true,"docs":{"description":"Collection sizes and array length comparisons should make sense","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-collection-size-mischeck.md"}},"default":{"defaultOptions":[],"meta":{"messages":{"fixCollectionSizeCheck":"Fix this expression; {{propertyName}} of \"{{objectName}}\" is always greater or equal to zero.","suggestFixedSizeCheck":"Use \"{{operator}}\" for {{operation}} check"},"schema":[],"type":"problem","hasSuggestions":true,"docs":{"description":"Collection sizes and array length comparisons should make sense","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-collection-size-mischeck.md"}}}},"no-duplicate-string":{"defaultOptions":[{"threshold":3,"ignoreStrings":"application/json"}],"meta":{"messages":{"defineConstant":"Define a constant instead of duplicating this literal {{times}} times.","sonarRuntime":"{{sonarRuntimeData}}"},"type":"suggestion","docs":{"description":"String literals should not be duplicated","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-duplicate-string.md"},"schema":[{"type":"object","properties":{"threshold":{"type":"integer","minimum":2},"ignoreStrings":{"type":"string","default":"application/json"}}},{"type":"string","enum":["sonar-runtime"]}]},"default":{"defaultOptions":[{"threshold":3,"ignoreStrings":"application/json"}],"meta":{"messages":{"defineConstant":"Define a constant instead of duplicating this literal {{times}} times.","sonarRuntime":"{{sonarRuntimeData}}"},"type":"suggestion","docs":{"description":"String literals should not be duplicated","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-duplicate-string.md"},"schema":[{"type":"object","properties":{"threshold":{"type":"integer","minimum":2},"ignoreStrings":{"type":"string","default":"application/json"}}},{"type":"string","enum":["sonar-runtime"]}]}}},"no-duplicated-branches":{"defaultOptions":[],"meta":{"messages":{"sameConditionalBlock":"This {{type}}'s code block is the same as the block for the {{type}} on line {{line}}.","sonarRuntime":"{{sonarRuntimeData}}"},"type":"problem","docs":{"description":"Two branches in a conditional structure should not have exactly the same implementation","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-duplicated-branches.md"},"schema":[{"type":"string","enum":["sonar-runtime"]}]},"default":{"defaultOptions":[],"meta":{"messages":{"sameConditionalBlock":"This {{type}}'s code block is the same as the block for the {{type}} on line {{line}}.","sonarRuntime":"{{sonarRuntimeData}}"},"type":"problem","docs":{"description":"Two branches in a conditional structure should not have exactly the same implementation","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-duplicated-branches.md"},"schema":[{"type":"string","enum":["sonar-runtime"]}]}}},"no-element-overwrite":{"defaultOptions":[],"meta":{"messages":{"verifyIntendedIndex":"Verify this is the index that was intended; \"{{index}}\" was already set on line {{line}}.","sonarRuntime":"{{sonarRuntimeData}}"},"type":"problem","docs":{"description":"Collection elements should not be replaced unconditionally","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-element-overwrite.md"},"schema":[{"type":"string","enum":["sonar-runtime"]}]},"default":{"defaultOptions":[],"meta":{"messages":{"verifyIntendedIndex":"Verify this is the index that was intended; \"{{index}}\" was already set on line {{line}}.","sonarRuntime":"{{sonarRuntimeData}}"},"type":"problem","docs":{"description":"Collection elements should not be replaced unconditionally","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-element-overwrite.md"},"schema":[{"type":"string","enum":["sonar-runtime"]}]}}},"no-empty-collection":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-empty-collection.md"}},"default":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-empty-collection.md"}}}},"no-extra-arguments":{"defaultOptions":[],"meta":{"messages":{"tooManyArguments":"This function expects {{expectedArguments}}, but {{providedArguments}} provided.","sonarRuntime":"{{sonarRuntimeData}}"},"type":"problem","docs":{"description":"Function calls should not pass extra arguments","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-extra-arguments.md"},"schema":[{"type":"string","enum":["sonar-runtime"]}]},"default":{"defaultOptions":[],"meta":{"messages":{"tooManyArguments":"This function expects {{expectedArguments}}, but {{providedArguments}} provided.","sonarRuntime":"{{sonarRuntimeData}}"},"type":"problem","docs":{"description":"Function calls should not pass extra arguments","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-extra-arguments.md"},"schema":[{"type":"string","enum":["sonar-runtime"]}]}}},"no-gratuitous-expressions":{"defaultOptions":[],"meta":{"messages":{"refactorBooleanExpression":"This always evaluates to {{value}}. Consider refactoring this code.","sonarRuntime":"{{sonarRuntimeData}}"},"type":"suggestion","docs":{"description":"Boolean expressions should not be gratuitous","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-gratuitous-expressions.md"},"schema":[{"type":"string","enum":["sonar-runtime"]}]},"default":{"defaultOptions":[],"meta":{"messages":{"refactorBooleanExpression":"This always evaluates to {{value}}. Consider refactoring this code.","sonarRuntime":"{{sonarRuntimeData}}"},"type":"suggestion","docs":{"description":"Boolean expressions should not be gratuitous","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-gratuitous-expressions.md"},"schema":[{"type":"string","enum":["sonar-runtime"]}]}}},"no-identical-conditions":{"defaultOptions":[],"meta":{"messages":{"duplicatedCondition":"This condition is covered by the one on line {{line}}","duplicatedCase":"This case duplicates the one on line {{line}}","sonarRuntime":"{{sonarRuntimeData}}"},"type":"problem","docs":{"description":"Related \"if-else-if\" and \"switch-case\" statements should not have the same condition","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-identical-conditions.md"},"schema":[{"type":"string","enum":["sonar-runtime"]}]},"default":{"defaultOptions":[],"meta":{"messages":{"duplicatedCondition":"This condition is covered by the one on line {{line}}","duplicatedCase":"This case duplicates the one on line {{line}}","sonarRuntime":"{{sonarRuntimeData}}"},"type":"problem","docs":{"description":"Related \"if-else-if\" and \"switch-case\" statements should not have the same condition","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-identical-conditions.md"},"schema":[{"type":"string","enum":["sonar-runtime"]}]}}},"no-identical-expressions":{"defaultOptions":[],"meta":{"messages":{"correctIdenticalSubExpressions":"Correct one of the identical sub-expressions on both sides of operator \"{{operator}}\"","sonarRuntime":"{{sonarRuntimeData}}"},"type":"problem","docs":{"description":"Identical expressions should not be used on both sides of a binary operator","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-identical-expressions.md"},"schema":[{"type":"string","enum":["sonar-runtime"]}]},"default":{"defaultOptions":[],"meta":{"messages":{"correctIdenticalSubExpressions":"Correct one of the identical sub-expressions on both sides of operator \"{{operator}}\"","sonarRuntime":"{{sonarRuntimeData}}"},"type":"problem","docs":{"description":"Identical expressions should not be used on both sides of a binary operator","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-identical-expressions.md"},"schema":[{"type":"string","enum":["sonar-runtime"]}]}}},"no-identical-functions":{"defaultOptions":[3],"meta":{"messages":{"identicalFunctions":"Update this function so that its implementation is not identical to the one on line {{line}}.","sonarRuntime":"{{sonarRuntimeData}}"},"type":"problem","docs":{"description":"Functions should not have identical implementations","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-identical-functions.md"},"schema":[{"type":"integer","minimum":3},{"type":"string","enum":["sonar-runtime"]}]},"default":{"defaultOptions":[3],"meta":{"messages":{"identicalFunctions":"Update this function so that its implementation is not identical to the one on line {{line}}.","sonarRuntime":"{{sonarRuntimeData}}"},"type":"problem","docs":{"description":"Functions should not have identical implementations","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-identical-functions.md"},"schema":[{"type":"integer","minimum":3},{"type":"string","enum":["sonar-runtime"]}]}}},"no-ignored-return":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-ignored-return.md"}},"default":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-ignored-return.md"}}}},"no-inverted-boolean-check":{"defaultOptions":[],"meta":{"messages":{"useOppositeOperator":"Use the opposite operator ({{invertedOperator}}) instead.","suggestOperationInversion":"Invert inner operation (apply if NaN is not expected)"},"schema":[],"type":"suggestion","docs":{"description":"Boolean checks should not be inverted","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-inverted-boolean-check.md"},"hasSuggestions":true,"fixable":"code"},"default":{"defaultOptions":[],"meta":{"messages":{"useOppositeOperator":"Use the opposite operator ({{invertedOperator}}) instead.","suggestOperationInversion":"Invert inner operation (apply if NaN is not expected)"},"schema":[],"type":"suggestion","docs":{"description":"Boolean checks should not be inverted","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-inverted-boolean-check.md"},"hasSuggestions":true,"fixable":"code"}}},"no-nested-switch":{"defaultOptions":[],"meta":{"messages":{"removeNestedSwitch":"Refactor the code to eliminate this nested \"switch\"."},"schema":[],"type":"suggestion","docs":{"description":"\"switch\" statements should not be nested","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-nested-switch.md"}},"default":{"defaultOptions":[],"meta":{"messages":{"removeNestedSwitch":"Refactor the code to eliminate this nested \"switch\"."},"schema":[],"type":"suggestion","docs":{"description":"\"switch\" statements should not be nested","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-nested-switch.md"}}}},"no-nested-template-literals":{"defaultOptions":[],"meta":{"messages":{"nestedTemplateLiterals":"Refactor this code to not use nested template literals."},"schema":[],"type":"suggestion","docs":{"description":"Template literals should not be nested","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-nested-template-literals.md"}},"default":{"defaultOptions":[],"meta":{"messages":{"nestedTemplateLiterals":"Refactor this code to not use nested template literals."},"schema":[],"type":"suggestion","docs":{"description":"Template literals should not be nested","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-nested-template-literals.md"}}}},"no-one-iteration-loop":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-one-iteration-loop.md"}},"default":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-one-iteration-loop.md"}}}},"no-redundant-boolean":{"defaultOptions":[],"meta":{"messages":{"removeUnnecessaryBoolean":"Refactor the code to avoid using this boolean literal."},"schema":[],"type":"suggestion","docs":{"description":"Boolean literals should not be redundant","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-redundant-boolean.md"}},"default":{"defaultOptions":[],"meta":{"messages":{"removeUnnecessaryBoolean":"Refactor the code to avoid using this boolean literal."},"schema":[],"type":"suggestion","docs":{"description":"Boolean literals should not be redundant","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-redundant-boolean.md"}}}},"no-redundant-jump":{"defaultOptions":[],"meta":{"messages":{"removeRedundantJump":"Remove this redundant jump.","suggestJumpRemoval":"Remove this redundant jump"},"schema":[],"type":"suggestion","hasSuggestions":true,"docs":{"description":"Jump statements should not be redundant","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-redundant-jump.md"}},"default":{"defaultOptions":[],"meta":{"messages":{"removeRedundantJump":"Remove this redundant jump.","suggestJumpRemoval":"Remove this redundant jump"},"schema":[],"type":"suggestion","hasSuggestions":true,"docs":{"description":"Jump statements should not be redundant","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-redundant-jump.md"}}}},"no-same-line-conditional":{"defaultOptions":[],"meta":{"messages":{"sameLineCondition":"Move this \"if\" to a new line or add the missing \"else\".","sonarRuntime":"{{sonarRuntimeData}}","suggestAddingElse":"Add \"else\" keyword","suggestAddingNewline":"Move this \"if\" to a new line"},"type":"problem","hasSuggestions":true,"docs":{"description":"Conditionals should start on new lines","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-same-line-conditional.md"},"schema":[{"type":"string","enum":["sonar-runtime"]}]},"default":{"defaultOptions":[],"meta":{"messages":{"sameLineCondition":"Move this \"if\" to a new line or add the missing \"else\".","sonarRuntime":"{{sonarRuntimeData}}","suggestAddingElse":"Add \"else\" keyword","suggestAddingNewline":"Move this \"if\" to a new line"},"type":"problem","hasSuggestions":true,"docs":{"description":"Conditionals should start on new lines","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-same-line-conditional.md"},"schema":[{"type":"string","enum":["sonar-runtime"]}]}}},"no-small-switch":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-small-switch.md"}},"default":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-small-switch.md"}}}},"no-unused-collection":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-unused-collection.md"}},"default":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-unused-collection.md"}}}},"no-use-of-empty-return-value":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-use-of-empty-return-value.md"}},"default":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-use-of-empty-return-value.md"}}}},"no-useless-catch":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-useless-catch.md"}},"default":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/no-useless-catch.md"}}}},"non-existent-operator":{"defaultOptions":[],"meta":{"messages":{"useExistingOperator":"Was \"{{operator}}=\" meant instead?","suggestExistingOperator":"Replace with \"{{operator}}\" operator"},"schema":[],"type":"problem","hasSuggestions":true,"docs":{"description":"Non-existent operators \"=+\", \"=-\" and \"=!\" should not be used","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/non-existent-operator.md"}},"default":{"defaultOptions":[],"meta":{"messages":{"useExistingOperator":"Was \"{{operator}}=\" meant instead?","suggestExistingOperator":"Replace with \"{{operator}}\" operator"},"schema":[],"type":"problem","hasSuggestions":true,"docs":{"description":"Non-existent operators \"=+\", \"=-\" and \"=!\" should not be used","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/non-existent-operator.md"}}}},"prefer-immediate-return":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/prefer-immediate-return.md"},"fixable":"code"},"default":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/prefer-immediate-return.md"},"fixable":"code"}}},"prefer-object-literal":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/prefer-object-literal.md"}},"default":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/prefer-object-literal.md"}}}},"prefer-single-boolean-return":{"defaultOptions":[],"meta":{"messages":{"replaceIfThenElseByReturn":"Replace this if-then-else flow by a single return statement.","suggest":"Replace with single return statement","suggestCast":"Replace with single return statement using \"!!\" cast","suggestBoolean":"Replace with single return statement without cast (condition should be boolean!)"},"schema":[],"type":"suggestion","hasSuggestions":true,"docs":{"description":"Return of boolean expressions should not be wrapped into an \"if-then-else\" statement","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/prefer-single-boolean-return.md"}},"default":{"defaultOptions":[],"meta":{"messages":{"replaceIfThenElseByReturn":"Replace this if-then-else flow by a single return statement.","suggest":"Replace with single return statement","suggestCast":"Replace with single return statement using \"!!\" cast","suggestBoolean":"Replace with single return statement without cast (condition should be boolean!)"},"schema":[],"type":"suggestion","hasSuggestions":true,"docs":{"description":"Return of boolean expressions should not be wrapped into an \"if-then-else\" statement","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/prefer-single-boolean-return.md"}}}},"prefer-while":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/prefer-while.md"},"fixable":"code"},"default":{"defaultOptions":[],"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","recommended":"recommended","url":"https://github.com/SonarSource/eslint-plugin-sonarjs/blob/master/docs/rules/prefer-while.md"},"fixable":"code"}}}}}}`).
@snigdha920 , thanks for the report. I assume you are extending plugin:sonarjs/recommended
. If so, can you please try extending plugin:sonarjs/recommended-legacy
instead?
This is documented there.
@snigdha920 , thanks for the report. I assume you are extending
plugin:sonarjs/recommended
. If so, can you please try extendingplugin:sonarjs/recommended-legacy
instead?This is documented there.
It works!! thanks !!🎉
@snigdha920 , thanks for the report. I assume you are extending
plugin:sonarjs/recommended
. If so, can you please try extendingplugin:sonarjs/recommended-legacy
instead?This is documented there.
Sorry I missed that 😅 Thank you, that works!
Actually, the documentation was partially wrong, which may explain why you missed it. We are fixing it right now.
but how can I use it in eslint with flat config? this is my "eslint.config.mjs" file:
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
import typeScriptParser from "@typescript-eslint/parser";
import typeScriptPlugin from "@typescript-eslint/eslint-plugin";
import prettierRecommended from "eslint-plugin-prettier/recommended";
export default tseslint.config(
eslint.configs.recommended,
...tseslint.configs.recommended,
prettierRecommended,
{
languageOptions: {
parser: typeScriptParser,
parserOptions: {
project: "tsconfig.json",
tsconfigRootDir: ".",
ecmaVersion: 2020,
sourceType: "module",
},
},
plugins: {
"@typescript-eslint": typeScriptPlugin,
},
files: ["src/**/*.ts", "apps/**/*.ts", "libs/**/*.ts", "test/**/*.ts"],
ignores: ["eslint.config.mjs", "/*.js", "node_modules", "dist"],
rules: {
"prefer-template": "error",...
Hi @ocsoares, You can use the SonarJS plugin exactly like you would any other plugin, following the instructions in the ESLint plugin documentation.
For example, if you want to use the recommended configuration of the plugin, you can use it this way:
import sonarJSPlugin from "eslint-plugin-sonars";
export default tseslint.config(
sonarJSPlugin.configs.recommended,
// ...
);
Note that you do not need to reference it in the plugins
record if you want to use the recommended config. You need to do so only if you don't want to use the recommended config and prefer to cherry-pick the rules that you are interested in.
import sonarJSPlugin from "eslint-plugin-sonars";
export default tseslint.config(
{
plugins: {
sonarjs: sonarJSPlugin
},
rules: {
'sonarjs/no-empty-collection': "warn"
}
},
// ...
);
You can mix both approaches; for example, import all the recommended rules but change only the severity level of some. Note that in this case, you don't need to reference the plugin in the plugins
record either.
import sonarJSPlugin from "eslint-plugin-sonars";
export default tseslint.config(
sonarJSPlugin.configs.recommended,
{
rules: {
'sonarjs/no-empty-collection': "warn"
}
},
// ...
);
@ericmorand-sonarsource thanks, it works !
@snigdha920 , thanks for the report. I assume you are extending
plugin:sonarjs/recommended
. If so, can you please try extendingplugin:sonarjs/recommended-legacy
instead?This is documented there.
It doesn't work:
"plugins": [
"unused-imports",
"sonarjs"
],
"extends": [
"plugin:@angular-eslint/recommended",
"plugin:@angular-eslint/template/process-inline-templates",
"plugin:sonarjs/recommended-legacy"
],
An unhandled exception occurred: Error while loading rule 'sonarjs/no-collection-size-mischeck': Cannot read properties of undefined (reading 'parserServices')
- node: v16.20.2
- npm: 8.19.4
- eslint: 8.22.0
- eslint-plugin-sonarjs: 1.0.3
I can't just import plugin
// @ts-check
import tseslint from 'typescript-eslint';
import sonarJSPlugin from "eslint-plugin-sonarjs";
export default tseslint.config(
sonarJSPlugin.configs.recommended,
// ...
);
Having type error:
Argument of type 'Config' is not assignable to parameter of type 'ConfigWithExtends'.
Types of property 'languageOptions' are incompatible.
I can't just import plugin
// @ts-check import tseslint from 'typescript-eslint'; import sonarJSPlugin from "eslint-plugin-sonarjs"; export default tseslint.config( sonarJSPlugin.configs.recommended, // ... );
Having type error:
Argument of type 'Config' is not assignable to parameter of type 'ConfigWithExtends'. Types of property 'languageOptions' are incompatible.
Same thing for me Version - 1.0.4-alpha.1
Hello @unnamed92 @mmospanenko,
can you try latest 1.0.4-alpha.2?
Thanks!
1.0.4-alpha.2
has all sorts of issues that didn't happen with 1.0.3:
-
"sonarjs/sonar-no-fallthrough" - TypeError: Cannot read properties of undefined (reading 'some')
-
"sonarjs/rules-of-hooks" - context.getSource is not a function
- at least one more, but I stopped here
FWIW, while I'd love to help out debugging and fixing the alpha, the "Issue" setup on this project puts so many barriers in my way that I won't:
- Jira: I can't create issues on, and honestly wouldn't create an account just to do this anyway
- Community forum: there's no clear place to log issues about this project, nevermind your alpha release. (and frankly this feedback needs to go straight to the dev team involved -- not the community, who obviously can't do anything about it)
Hi @bmulholland,
Thanks for the feedback. Please share as much as possible; these alpha versions are a big change from the current stable version, including all SonarJS rules instead of the small list that was available in this repo (this repo will be archived, by the way).
I'll try to reproduce those 2 errors you point out.
As for issue reporting, please go through the community forum and just explain that this is about the eslint-plugin-sonarjs
, it will reach us, the dev team, pretty quickly.
Thanks again!
Sure, I'm out of time today but I can help out here if that works for you :)
FYI, these errors are in a vue project. Let me know if you can't easily repro and I'll see what I can do to get you more info.
yes, we can keep the conversation here as well as you are already some users reporting issues with alpha.
Thanks for the vue hint.
Hi, I'd like to second @bmulholland's sentiment about issue reporting. I can relate to wanting to centralize things, but it takes more time to go through a forum sign up process (+ adjusting notification settings) than to report 90% of bugs. Some days ago I noticed that alpha versions are being marked as latest on npm, which is a mistake, tried Jira, realized that it's read-only for outsiders, and stopped, as it was starting to eat into my workday. Why not sync Jira with GitHub issues?
Hi @bmulholland,
sorry, I was not able to reproduce any of the issues (both sonarjs/sonar-no-fallthrough
and sonarjs/rules-of-hooks
.
I was able to raise issues from both rules on my code snippets. What ESLint version are you using? I've tested with ESLint 8 and 9 and did not get any errors.
If you can share some code that makes eslint fail would be very helpful.
Cheers!
Hi @alecmev,
I understand that for many developers who are used to Github issues, this is not ideal. But this has been a Sonar-wide move to centralize everything in Jira + Sonar Community forum.
FYI: https://community.sonarsource.com/t/sonarjs-eslint-plugin-publishing-alpha-releases-to-latest-tag/119550/3
@alecmev It's fixed now. I'm using the tag next
for the new alpha versions and republished 1.0.4 to reset latest
.