├── .gitmodules ├── mise.toml ├── slang-testing ├── src │ ├── test │ │ ├── resources │ │ │ ├── no-issue.code │ │ │ ├── primary.code │ │ │ ├── wrong-message.code │ │ │ ├── file-issue.code │ │ │ ├── primary-and-secondary.code │ │ │ ├── no-issue.code.json │ │ │ ├── file-issue.code.json │ │ │ ├── primary.code.json │ │ │ ├── wrong-message.code.json │ │ │ └── primary-and-secondary.code.json │ │ └── java │ │ │ └── org │ │ │ └── sonarsource │ │ │ ├── test │ │ │ └── TestCheck.java │ │ │ └── slang │ │ │ └── testing │ │ │ └── PackageScannerTest.java │ └── main │ │ └── java │ │ └── org │ │ └── sonarsource │ │ └── slang │ │ └── testing │ │ └── package-info.java └── build.gradle ├── .github ├── CODEOWNERS ├── workflows │ ├── pr-cleanup.yml │ ├── release.yml │ ├── mark-prs-stale.yml │ ├── slack_notify.yml │ ├── ToggleLockBranch.yml │ ├── PullRequestClosed.yml │ ├── RequestReview.yml │ ├── SubmitReview.yml │ └── PullRequestCreated.yml └── PULL_REQUEST_TEMPLATE.md ├── slang-plugin ├── src │ ├── test │ │ └── resources │ │ │ ├── propertyHandler │ │ │ └── dummyReport.txt │ │ │ └── sensitive-data.txt │ └── main │ │ └── java │ │ └── org │ │ └── sonarsource │ │ └── slang │ │ └── plugin │ │ ├── package-info.java │ │ ├── VisibleForTesting.java │ │ ├── caching │ │ └── package-info.java │ │ └── converter │ │ └── package-info.java └── build.gradle ├── slang-checks ├── src │ ├── test │ │ ├── resources │ │ │ └── org │ │ │ │ └── sonarsource │ │ │ │ └── slang │ │ │ │ └── checks │ │ │ │ ├── Tabs_compliant.slang │ │ │ │ ├── TooLongLine_40.slang │ │ │ │ ├── fileheader │ │ │ │ ├── Compliant.slang │ │ │ │ ├── Noncompliant.slang │ │ │ │ ├── NoFirstLine.slang │ │ │ │ └── Multiline.slang │ │ │ │ ├── Tabs_noncompliant.slang │ │ │ │ ├── TooComplexExpression_2.slang │ │ │ │ ├── TooManyLinesOfCodeFile.max_5.slang │ │ │ │ ├── BadFunctionName.slang │ │ │ │ ├── TooManyCases_4.slang │ │ │ │ ├── EmptyComment.slang │ │ │ │ ├── TooManyParameters.threshold.3.slang │ │ │ │ ├── TooLongFunction_4.slang │ │ │ │ ├── BadFunctionName.uppercase.slang │ │ │ │ ├── CommentedCode.slang │ │ │ │ ├── SelfAssignment.slang │ │ │ │ ├── TooDeeplyNestedStatements.max_2.slang │ │ │ │ ├── TooManyLinesOfCodeFile.max_4.slang │ │ │ │ ├── OctalValues.slang │ │ │ │ ├── RedundantParentheses.slang │ │ │ │ ├── MatchCaseTooBig_5.slang │ │ │ │ ├── StringLiteralDuplicated.threshold_4.slang │ │ │ │ ├── UnusedLocalVariable.slang │ │ │ │ ├── TooLongLine_120.slang │ │ │ │ ├── BooleanInversion.slang │ │ │ │ ├── TooManyCases_3.slang │ │ │ │ ├── BadClassName.slang │ │ │ │ ├── EmptyFunction.slang │ │ │ │ ├── TooComplexExpression_3.slang │ │ │ │ ├── EmptyBlock.slang │ │ │ │ ├── IdenticalBinaryOperand.slang │ │ │ │ ├── TooLongFunction_3.slang │ │ │ │ ├── MatchCaseTooBig_3.slang │ │ │ │ ├── WrongAssignmentOperator.slang │ │ │ │ ├── IdenticalConditions.slang │ │ │ │ ├── TodoComment.slang │ │ │ │ ├── OneStatementPerLine.slang │ │ │ │ ├── FixMeComment.slang │ │ │ │ ├── IfConditionalAlwaysTrueOrFalse.slang │ │ │ │ ├── VariableAndParameterName.slang │ │ │ │ ├── FunctionCognitiveComplexity.slang │ │ │ │ ├── AllBranchesIdentical.slang │ │ │ │ ├── CollapsibleIfStatements.slang │ │ │ │ ├── TooManyParameters.slang │ │ │ │ ├── CodeAfterJump.slang │ │ │ │ ├── MatchWithoutElse.slang │ │ │ │ ├── NestedMatch.slang │ │ │ │ └── ElseIfWithoutElse.slang │ │ └── java │ │ │ └── org │ │ │ └── sonarsource │ │ │ └── slang │ │ │ └── checks │ │ │ ├── BooleanLiteralCheckTest.java │ │ │ ├── EmptyBlockCheckTest.java │ │ │ ├── EmptyCommentCheckTest.java │ │ │ ├── EmptyFunctionCheckTest.java │ │ │ ├── NestedMatchCheckTest.java │ │ │ ├── ElseIfWithoutElseCheckTest.java │ │ │ ├── HardcodedIpCheckTest.java │ │ │ ├── DuplicateBranchCheckTest.java │ │ │ ├── OctalValuesCheckTest.java │ │ │ ├── TodoCommentCheckTest.java │ │ │ ├── BadClassNameCheckTest.java │ │ │ ├── FixMeCommentCheckTest.java │ │ │ ├── CodeAfterJumpCheckTest.java │ │ │ ├── SelfAssignmentCheckTest.java │ │ │ ├── AllBranchesIdenticalCheckTest.java │ │ │ ├── BooleanInversionCheckTest.java │ │ │ ├── CollapsibleIfStatementsCheckTest.java │ │ │ ├── MatchWithoutElseCheckTest.java │ │ │ ├── OneStatementPerLineCheckTest.java │ │ │ ├── IdenticalConditionsCheckTest.java │ │ │ ├── UnusedLocalVariableCheckTest.java │ │ │ ├── UnusedPrivateMethodCheckTest.java │ │ │ ├── HardcodedCredentialsCheckTest.java │ │ │ ├── RedundantParenthesesCheckTest.java │ │ │ ├── WrongAssignmentOperatorCheckTest.java │ │ │ ├── IdenticalBinaryOperandCheckTest.java │ │ │ ├── UnusedFunctionParameterCheckTest.java │ │ │ ├── VariableAndParameterNameCheckTest.java │ │ │ ├── IfConditionalAlwaysTrueOrFalseCheckTest.java │ │ │ ├── DuplicatedFunctionImplementationCheckTest.java │ │ │ ├── CommentedCodeCheckTest.java │ │ │ ├── TabsCheckTest.java │ │ │ ├── FunctionCognitiveComplexityCheckTest.java │ │ │ ├── TooLongFunctionCheckTest.java │ │ │ ├── TooManyCasesCheckTest.java │ │ │ ├── MatchCaseTooBigCheckTest.java │ │ │ ├── BadFunctionNameCheckTest.java │ │ │ ├── TooLongLineCheckTest.java │ │ │ ├── TooManyParametersCheckTest.java │ │ │ ├── TooComplexExpressionCheckTest.java │ │ │ ├── TooManyLinesOfCodeFileCheckTest.java │ │ │ ├── TooDeeplyNestedStatementsCheckTest.java │ │ │ └── StringLiteralDuplicatedCheckTest.java │ └── main │ │ └── java │ │ └── org │ │ └── sonarsource │ │ └── slang │ │ └── checks │ │ ├── package-info.java │ │ ├── utils │ │ ├── package-info.java │ │ ├── PropertyDefaultValues.java │ │ └── PropertyDefaultValue.java │ │ ├── complexity │ │ └── package-info.java │ │ └── ParsingErrorCheck.java ├── README.md └── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── checkstyle-import ├── src │ ├── test │ │ └── resources │ │ │ └── externalreport │ │ │ ├── invalid-file.xml │ │ │ ├── not-checkstyle-file.xml │ │ │ ├── TabCharacter.go │ │ │ ├── A.kt │ │ │ ├── main.kt │ │ │ ├── golandci-lint-report.xml │ │ │ ├── detekt-checkstyle.xml │ │ │ └── detekt-checkstyle-with-errors.xml │ └── main │ │ └── java │ │ └── org │ │ └── sonarsource │ │ └── slang │ │ └── externalreport │ │ └── package-info.java └── build.gradle ├── slang-api ├── src │ ├── test │ │ └── resources │ │ │ └── org │ │ │ └── sonarsource │ │ │ └── slang │ │ │ └── persistence │ │ │ ├── token_other.json │ │ │ ├── token_keyword.json │ │ │ ├── comment.json │ │ │ ├── literal.json │ │ │ ├── identifier.json │ │ │ ├── integer_literal.json │ │ │ ├── tree_metadata_provider.json │ │ │ ├── modifier.json │ │ │ ├── place_holder.json │ │ │ ├── throw_nothing.json │ │ │ ├── string_literal.json │ │ │ ├── nullable_child_can_be_omitted.json │ │ │ ├── error_unary_expression_without_child.json │ │ │ ├── unary_expression.json │ │ │ ├── error_unary_expression_with_null_child.json │ │ │ ├── throw_tree.json │ │ │ ├── import_declaration.json │ │ │ ├── block.json │ │ │ ├── jump.json │ │ │ ├── package_declaration.json │ │ │ ├── native_tree_empty_kind.json │ │ │ ├── error_invalid_json_tree.json │ │ │ ├── catch_tree_without_parameter.json │ │ │ ├── return_true.json │ │ │ ├── native_tree_with_kind.json │ │ │ ├── top_level.json │ │ │ ├── exception_handling_without_catch.json │ │ │ ├── class_declaration_anonymous.json │ │ │ ├── error_invalid_tree_type.json │ │ │ ├── parenthesized_expression.json │ │ │ ├── error_missing_type.json │ │ │ ├── catch_tree.json │ │ │ ├── assignment_expression.json │ │ │ ├── match_case.json │ │ │ ├── binary_expression.json │ │ │ ├── loop.json │ │ │ ├── error_unexpected_match_child_class.json │ │ │ ├── native_tree.json │ │ │ ├── if_tree_without_else.json │ │ │ ├── variable_declaration.json │ │ │ ├── class_declaration.json │ │ │ ├── parameter.json │ │ │ ├── if_tree.json │ │ │ ├── match.json │ │ │ ├── exception_handling.json │ │ │ └── function_declaration.json │ └── main │ │ └── java │ │ └── org │ │ └── sonarsource │ │ └── slang │ │ ├── api │ │ ├── NativeKind.java │ │ ├── package-info.java │ │ ├── HasKeyword.java │ │ ├── ImportDeclarationTree.java │ │ ├── PackageDeclarationTree.java │ │ ├── HasTextRange.java │ │ ├── CodeVerifier.java │ │ ├── LiteralTree.java │ │ ├── NativeTree.java │ │ ├── StringLiteralTree.java │ │ ├── PlaceHolderTree.java │ │ ├── BlockTree.java │ │ ├── MemberSelectTree.java │ │ ├── Comment.java │ │ ├── FunctionInvocationTree.java │ │ ├── ReturnTree.java │ │ ├── ThrowTree.java │ │ ├── ModifierTree.java │ │ ├── ParenthesizedExpressionTree.java │ │ ├── Token.java │ │ ├── ClassDeclarationTree.java │ │ ├── CatchTree.java │ │ ├── IdentifierTree.java │ │ ├── TextPointer.java │ │ ├── MatchTree.java │ │ ├── Annotation.java │ │ ├── UnaryExpressionTree.java │ │ ├── TextRange.java │ │ ├── TopLevelTree.java │ │ ├── JumpTree.java │ │ ├── VariableDeclarationTree.java │ │ ├── MatchCaseTree.java │ │ ├── TreeMetaData.java │ │ ├── ExceptionHandlingTree.java │ │ ├── LoopTree.java │ │ ├── ParameterTree.java │ │ ├── AssignmentExpressionTree.java │ │ ├── Tree.java │ │ ├── IntegerLiteralTree.java │ │ ├── FunctionDeclarationTree.java │ │ └── BinaryExpressionTree.java │ │ ├── impl │ │ ├── package-info.java │ │ └── BaseTreeImpl.java │ │ ├── utils │ │ └── package-info.java │ │ ├── visitors │ │ └── package-info.java │ │ ├── checks │ │ └── api │ │ │ ├── package-info.java │ │ │ ├── SlangCheck.java │ │ │ └── InitContext.java │ │ └── persistence │ │ ├── package-info.java │ │ └── conversion │ │ └── package-info.java └── build.gradle ├── gradle.properties ├── slang-antlr ├── src │ ├── test │ │ └── resources │ │ │ ├── binary.slang │ │ │ ├── conditional.slang │ │ │ └── annotations.slang │ └── main │ │ └── java │ │ └── org │ │ └── sonarsource │ │ └── slang │ │ └── parser │ │ └── package-info.java └── build.gradle ├── .gitattributes ├── .gitignore ├── LICENSE_HEADER └── SECURITY.md /.gitmodules: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mise.toml: -------------------------------------------------------------------------------- 1 | [tools] 2 | java = "17" 3 | gradle = "7.6" 4 | -------------------------------------------------------------------------------- /slang-testing/src/test/resources/no-issue.code: -------------------------------------------------------------------------------- 1 | foo 2 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | .github/CODEOWNERS @SonarSource/quality-jvm-squad 2 | -------------------------------------------------------------------------------- /slang-testing/src/test/resources/primary.code: -------------------------------------------------------------------------------- 1 | foo // Noncompliant 2 | -------------------------------------------------------------------------------- /slang-plugin/src/test/resources/propertyHandler/dummyReport.txt: -------------------------------------------------------------------------------- 1 | placeholder 2 | -------------------------------------------------------------------------------- /slang-plugin/src/test/resources/sensitive-data.txt: -------------------------------------------------------------------------------- 1 | president-password=123456 2 | -------------------------------------------------------------------------------- /slang-testing/src/test/resources/wrong-message.code: -------------------------------------------------------------------------------- 1 | foo // Noncompliant {{wrong message}} 2 | -------------------------------------------------------------------------------- /slang-testing/src/test/resources/file-issue.code: -------------------------------------------------------------------------------- 1 | // Noncompliant@0 {{file-issue.code length 48}} 2 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/Tabs_compliant.slang: -------------------------------------------------------------------------------- 1 | a = 1; 2 | b = 4; 3 | x = 1; -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SonarSource/slang/HEAD/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /slang-testing/src/test/resources/primary-and-secondary.code: -------------------------------------------------------------------------------- 1 | a b // Noncompliant {{primary}} 2 | // ^ ^< {{secondary}} 3 | -------------------------------------------------------------------------------- /checkstyle-import/src/test/resources/externalreport/invalid-file.xml: -------------------------------------------------------------------------------- 1 | 2 | invalid xml file 3 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/token_other.json: -------------------------------------------------------------------------------- 1 | { 2 | "textRange": "3:7::10", 3 | "text": "foo" 4 | } 5 | -------------------------------------------------------------------------------- /checkstyle-import/src/test/resources/externalreport/not-checkstyle-file.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/token_keyword.json: -------------------------------------------------------------------------------- 1 | { 2 | "textRange": "1:2::5", 3 | "text": "key", 4 | "type": "KEYWORD" 5 | } 6 | -------------------------------------------------------------------------------- /checkstyle-import/src/test/resources/externalreport/TabCharacter.go: -------------------------------------------------------------------------------- 1 | // S105 2 | package samples 3 | 4 | func three() int { 5 | x := 3 6 | return x // Noncompliant 7 | } 8 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/TooLongLine_40.slang: -------------------------------------------------------------------------------- 1 | int fun (p1, p2, p3) {} 2 | 3 | // Noncompliant@+1 4 | int fun funWithLongName(p1, p2, p3) { println(10);} -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/fileheader/Compliant.slang: -------------------------------------------------------------------------------- 1 | // copyright 2018 2 | // comment 3 | 4 | if (cond) { 5 | a = b + 1 6 | }; 7 | 8 | x = 4; 9 | x; -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/comment.json: -------------------------------------------------------------------------------- 1 | { 2 | "text": "// hello", 3 | "contentText": " hello", 4 | "range": "3:7::15", 5 | "contentRange": "3:9::15" 6 | } 7 | -------------------------------------------------------------------------------- /checkstyle-import/src/test/resources/externalreport/A.kt: -------------------------------------------------------------------------------- 1 | package externalreport.detekt 2 | 3 | class A { 4 | override fun equals(other: Any?): Boolean { 5 | return super.equals(other) 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /checkstyle-import/src/test/resources/externalreport/main.kt: -------------------------------------------------------------------------------- 1 | fun main(args: Array) { 2 | val magicNumber = Integer.parseInt(args[0]) 3 | if (magicNumber == 42) { 4 | } 5 | println("hello world") 6 | } 7 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/fileheader/Noncompliant.slang: -------------------------------------------------------------------------------- 1 | // Noncompliant@0 {{Add or update the header of this file.}} 2 | // comment 3 | 4 | if (cond) { 5 | a = b + 1 6 | }; 7 | 8 | x = 4; 9 | x; -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/Tabs_noncompliant.slang: -------------------------------------------------------------------------------- 1 | // Noncompliant@0 {{Replace all tab characters in this file "Tabs_noncompliant.slang" by sequences of white-spaces.}} 2 | a = 1; 3 | tabOnTheLeft = 1; 4 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/fileheader/NoFirstLine.slang: -------------------------------------------------------------------------------- 1 | 2 | // copyright 2018 3 | 4 | if (cond) { 5 | a = b + 1 6 | }; 7 | 8 | x = 4; 9 | x; 10 | // Noncompliant@0 {{Add or update the header of this file.}} -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/TooComplexExpression_2.slang: -------------------------------------------------------------------------------- 1 | a && b; 2 | a && b || c; 3 | a && b || c && d; // Noncompliant {{Reduce the number of conditional operators (3) used in the expression (maximum allowed 2).}} 4 | -------------------------------------------------------------------------------- /gradle.properties: -------------------------------------------------------------------------------- 1 | group=org.sonarsource.slang 2 | version=1.21-SNAPSHOT 3 | description=SonarSource Language analyzer 4 | projectTitle=SLang 5 | org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError -Xms256m -Xmx1024m 6 | org.gradle.caching=true 7 | 8 | -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.5-bin.zip 4 | networkTimeout=10000 5 | zipStoreBase=GRADLE_USER_HOME 6 | zipStorePath=wrapper/dists 7 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/TooManyLinesOfCodeFile.max_5.slang: -------------------------------------------------------------------------------- 1 | // comment - not a line of code 2 | 3 | if (cond) { 4 | a = b + 1 5 | }; 6 | 7 | 8 | x = 4; 9 | 10 | x; 11 | 12 | /* 13 | * There are 5 lines of code in this file 14 | */ 15 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/BadFunctionName.slang: -------------------------------------------------------------------------------- 1 | void fun fooBar() {} // OK 2 | fun () {} // OK 3 | void fun foo_bar() {} // Noncompliant {{Rename function "foo_bar" to match the regular expression ^[a-z][a-zA-Z0-9]*$}} 4 | // ^^^^^^^ 5 | -------------------------------------------------------------------------------- /.github/workflows/pr-cleanup.yml: -------------------------------------------------------------------------------- 1 | name: Cleanup PR Resources 2 | on: 3 | pull_request: 4 | types: [closed] 5 | 6 | jobs: 7 | cleanup: 8 | runs-on: sonar-xs 9 | permissions: 10 | actions: write 11 | steps: 12 | - uses: SonarSource/ci-github-actions/pr_cleanup@v1 13 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/literal.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::4", "text": "true"} 6 | ] 7 | }, 8 | "tree": {"@type": "Literal", "metaData": "1:0::4", "value": "true"} 9 | } 10 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/TooManyCases_4.slang: -------------------------------------------------------------------------------- 1 | match (x) { 2 | 1 -> 'a'; 3 | 2 -> 'b'; 4 | 3 -> 'c'; 5 | 4 -> 'd'; 6 | }; 7 | 8 | match (x) { // Noncompliant 9 | 1 -> 'a'; 10 | 2 -> 'b'; 11 | 3 -> 'c'; 12 | 4 -> 'd'; 13 | 5 -> 'e'; 14 | }; 15 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/identifier.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::3", "text": "foo"} 6 | ] 7 | }, 8 | "tree": {"@type": "Identifier", "metaData": "1:0::3", "name": "foo"} 9 | } 10 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/fileheader/Multiline.slang: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 1999-2001 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | */ 6 | // comment 7 | 8 | if (cond) { 9 | a = b + 1 10 | }; 11 | 12 | x = 4; 13 | x; 14 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/EmptyComment.slang: -------------------------------------------------------------------------------- 1 | /* Some comment */ 2 | 3 | /**/ // Noncompliant 4 | 5 | /* */ // Noncompliant 6 | //^^^^^^ 7 | 8 | // Noncompliant@+1 9 | /* 10 | 11 | */ 12 | 13 | // The next line should be compliant 14 | // 15 | // Comment line 16 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/TooManyParameters.threshold.3.slang: -------------------------------------------------------------------------------- 1 | int fun foo(p1, p2, p3) {} 2 | int fun foo(p1, p2, p3, p4, p5, p6, p7, p8) {} // Noncompliant {{This function has 8 parameters, which is greater than the 3 authorized.}} 3 | // ^^^ ^^< ^^< ^^< ^^< ^^< 4 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/integer_literal.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::4", "text": "0xFF"} 6 | ] 7 | }, 8 | "tree": {"@type": "IntegerLiteral", "metaData": "1:0::4", "value": "0xFF"} 9 | } 10 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/tree_metadata_provider.json: -------------------------------------------------------------------------------- 1 | { 2 | "comments": [ 3 | {"text": "// hello", "contentText": " hello", "range": "1:0::8", "contentRange": "1:2::8"} 4 | ], 5 | "tokens": [ 6 | {"textRange": "2:0::3", "text": "fun", "type": "KEYWORD"} 7 | ] 8 | } 9 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/TooLongFunction_4.slang: -------------------------------------------------------------------------------- 1 | fun f1() { // Noncompliant {{This function has 5 lines of code, which is greater than the 4 authorized. Split it into smaller functions.}} 2 | a; 3 | a; 4 | a; 5 | } 6 | 7 | fun f1() { 8 | a; 9 | 10 | a; 11 | } 12 | -------------------------------------------------------------------------------- /checkstyle-import/src/test/resources/externalreport/golandci-lint-report.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/BadFunctionName.uppercase.slang: -------------------------------------------------------------------------------- 1 | void fun FOOBAR() {} // OK 2 | void fun foo() {} // Noncompliant {{Rename function "foo" to match the regular expression ^[A-Z]*$}} 3 | // ^^^ 4 | 5 | class A { 6 | fun constructor() {} // Compliant, constructor 7 | } 8 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/modifier.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::6", "text": "public", "type": "KEYWORD"} 6 | ] 7 | }, 8 | "tree": {"@type": "Modifier", "metaData": "1:0::6", "kind": "PUBLIC"} 9 | } 10 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/place_holder.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::1", "text": "_", "type": "KEYWORD"} 6 | ] 7 | }, 8 | "tree": {"@type": "PlaceHolder", "metaData": "1:0::1", "placeHolderToken": "1:0::1"} 9 | } 10 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/throw_nothing.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::5", "text": "throw", "type": "KEYWORD"} 6 | ] 7 | }, 8 | "tree": {"@type": "Throw", "metaData": "1:0::5", "keyword": "1:0::5", "body": null} 9 | } 10 | -------------------------------------------------------------------------------- /slang-antlr/src/test/resources/binary.slang: -------------------------------------------------------------------------------- 1 | // Example method in slang 2 | a = 2; 3 | b = K + 1; 4 | c = a - a; 5 | d = "hello world"; 6 | e = 'c' + 'h'; 7 | true && false; 8 | f = e; 9 | 10 | native ["DEFER"] { 11 | [ a = 1; ] 12 | [ b = 2; 13 | c = b + 1; 14 | ] 15 | }; 16 | 17 | public int fun test() 18 | { 19 | e = a / c; 20 | } 21 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text eol=lf 2 | *.bat -text 3 | *.jar -text 4 | *.cls -text 5 | *.trigger -text 6 | private/its/sources/** -text 7 | private/its/plugin/projects/** -text 8 | its/sources/** -text 9 | its/plugin/projects/** -text 10 | **/src/test/resources/** -text 11 | 12 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | Part of 2 | 8 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/string_literal.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::3", "text": "\"a\"", "type": "STRING_LITERAL"} 6 | ] 7 | }, 8 | "tree": {"@type": "StringLiteral", "metaData": "1:0::3", "content": "a", "value": "\"a\""} 9 | } 10 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/CommentedCode.slang: -------------------------------------------------------------------------------- 1 | // Noncompliant@+2 {{Remove this commented out code.}} 2 | foo(); 3 | // if(a) { print(b); }; 4 | foo(); 5 | // this is a normal comment 6 | bar(); 7 | // Noncompliant@+2 8 | a = 1; 9 | /* 10 | fun foo() { 11 | print(a); 12 | if (a) return "hello world!" 13 | } 14 | */ 15 | -------------------------------------------------------------------------------- /slang-antlr/src/test/resources/conditional.slang: -------------------------------------------------------------------------------- 1 | public int fun test(int a){ 2 | if (a > 0) { 3 | return 0; 4 | }; 5 | 6 | if (a > 1) { 7 | if (a > 2) { 8 | return 2; 9 | } else { 10 | return 3; 11 | } 12 | }; 13 | 14 | if (a > 2) { 15 | return 2; 16 | } else if (a > 3) { 17 | return 3; 18 | } else { 19 | return 4; 20 | }; 21 | } -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/SelfAssignment.slang: -------------------------------------------------------------------------------- 1 | x = 1; 2 | x = x + 1; 3 | x += x; 4 | x = x; // Noncompliant {{Remove or correct this useless self-assignment.}} 5 | //^^^^^ 6 | native[] { [x] } = x; // Ex: this.x = x 7 | 8 | // Ex: this.x = this.x 9 | // Noncompliant@+1 10 | native[] { [x] } = native[] { 11 | [ 12 | x; 13 | ] 14 | }; -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/nullable_child_can_be_omitted.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0:1:5", "text": "break", "type": "KEYWORD"} 6 | ] 7 | }, 8 | "tree": { 9 | "@type": "Jump", 10 | "metaData": "1:0:1:5", 11 | "keyword": "1:0:1:5", 12 | "kind": "BREAK" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/TooDeeplyNestedStatements.max_2.slang: -------------------------------------------------------------------------------- 1 | if (true) {} 2 | //^^> 3 | else if (true) {} 4 | else if (true) { 5 | if (true) { // Compliant 6 | // ^^> 7 | if (true) {// Noncompliant {{Refactor this code to not nest more than 2 control flow statements.}} 8 | // ^^ 9 | if (true) { 10 | }; 11 | }; 12 | }; 13 | }; -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/TooManyLinesOfCodeFile.max_4.slang: -------------------------------------------------------------------------------- 1 | // Noncompliant@0 {{File "TooManyLinesOfCodeFile.max_4.slang" has 5 lines, which is greater than 4 authorized. Split it into smaller files.}} 2 | // comment - not a line of code 3 | 4 | if (cond) { 5 | a = b + 1 6 | }; 7 | 8 | 9 | x = 4; 10 | 11 | x; 12 | 13 | /* 14 | * There are 5 lines of code in this file 15 | */ 16 | -------------------------------------------------------------------------------- /slang-testing/src/test/resources/no-issue.code.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0:1:3", "text": "foo", "type": "OTHER"} 6 | ] 7 | }, 8 | "tree": { 9 | "@type": "TopLevel", 10 | "metaData": "1:0:1:3", 11 | "declarations": [ 12 | {"@type": "Identifier", "metaData": "1:0:1:3", "name": "foo"} 13 | ], 14 | "firstCpdToken": "1:0:1:3" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/error_unary_expression_without_child.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0:1:1", "text": "-", "type": "OTHER"}, 6 | {"textRange": "1:1:1:2", "text": "x", "type": "OTHER"} 7 | ] 8 | }, 9 | "tree": { 10 | "@type": "UnaryExpression", 11 | "metaData": "1:0:1:2", 12 | "operator": "MINUS" 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/OctalValues.slang: -------------------------------------------------------------------------------- 1 | 17000; 2 | 3 | 02522; // Noncompliant {{Use decimal values instead of octal ones.}} 4 | // ^^^^^ 5 | 0o2522; // Noncompliant 6 | 0O2522; // Noncompliant 7 | 8 | "0o2522"; 9 | "02522"; 10 | "0O2522"; 11 | 12 | a + 022; // Noncompliant 13 | // ^^^ 14 | 15 | 02; // Compliant - part of exceptions 16 | 0077; // Compliant - part of exceptions 17 | 0o077; // Compliant - part of exceptions -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/unary_expression.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::1", "text": "-"}, 6 | {"textRange": "1:1::2", "text": "x"} 7 | ] 8 | }, 9 | "tree": { 10 | "@type": "UnaryExpression", 11 | "metaData": "1:0::2", 12 | "operator": "MINUS", 13 | "operand": {"@type": "Identifier", "metaData": "1:1::2", "name": "x"} 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/error_unary_expression_with_null_child.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0:1:1", "text": "-", "type": "OTHER"}, 6 | {"textRange": "1:1:1:2", "text": "x", "type": "OTHER"} 7 | ] 8 | }, 9 | "tree": { 10 | "@type": "UnaryExpression", 11 | "metaData": "1:0:1:2", 12 | "operator": "MINUS", 13 | "operand": null 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/throw_tree.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::5", "text": "throw", "type": "KEYWORD"}, 6 | {"textRange": "1:6::8", "text": "ex"} 7 | ] 8 | }, 9 | "tree": { 10 | "@type": "Throw", 11 | "metaData": "1:0::8", 12 | "keyword": "1:0::5", 13 | "body": {"@type": "Identifier", "metaData": "1:6::8", "name": "ex"} 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/RedundantParentheses.slang: -------------------------------------------------------------------------------- 1 | x = x + 1; 2 | x = (x + 1); 3 | x = ((x + 1)); // Noncompliant 4 | // ^ ^< 5 | x = (((x + 1))); // Noncompliant 2 6 | x = (x + 1) * (x + 2); 7 | x = x + (1 * x) + 2; 8 | x = x + ((1 * x)) + 2; // Noncompliant 9 | x = (1); 10 | x = ((1)); // Noncompliant 11 | // ^ ^< 12 | 13 | if (x && (x + 1 > 0)) {}; 14 | if (x && ((x + 1 > 0))) {}; // Noncompliant 15 | if (x && ((x + 1) > 0)) {}; 16 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/import_declaration.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::6", "text": "import", "type": "KEYWORD"}, 6 | {"textRange": "1:7::10", "text": "lib"} 7 | ] 8 | }, 9 | "tree": { 10 | "@type": "ImportDeclaration", 11 | "metaData": "1:0::10", 12 | "children": [ 13 | {"@type": "Identifier", "metaData": "1:7::10", "name": "lib"} 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/MatchCaseTooBig_5.slang: -------------------------------------------------------------------------------- 1 | match (x) { 2 | expression -> { // Noncompliant {{Reduce this case clause number of lines from 8 to at most 5, for example by extracting code into methods.}} 3 | // ^^^^^^^^^^^^^ 4 | a = 1; 5 | foo(); 6 | bar(); 7 | if (a == 1) { 8 | print(1); 9 | }; 10 | }; 11 | else -> b; 12 | }; 13 | 14 | match (x) { 15 | 1 -> foo(); // OK 16 | else -> b; 17 | }; 18 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/block.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::1", "text": "{"}, 6 | {"textRange": "1:2::3", "text": "x"}, 7 | {"textRange": "1:4::5", "text": "}"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "Block", 12 | "metaData": "1:0::5", 13 | "statementOrExpressions": [ 14 | {"@type": "Identifier", "metaData": "1:2::3", "name": "x"} 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/jump.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::5", "text": "break", "type": "KEYWORD"}, 6 | {"textRange": "1:6::10", "text": "hard"} 7 | ] 8 | }, 9 | "tree": { 10 | "@type": "Jump", 11 | "metaData": "1:0::10", 12 | "label": {"@type": "Identifier", "metaData": "1:6::10", "name": "hard"}, 13 | "keyword": "1:0::5", 14 | "kind": "BREAK" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/package_declaration.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::7", "text": "package", "type": "KEYWORD"}, 6 | {"textRange": "1:8::13", "text": "hello"} 7 | ] 8 | }, 9 | "tree": { 10 | "@type": "PackageDeclaration", 11 | "metaData": "1:0::13", 12 | "children": [ 13 | {"@type": "Identifier", "metaData": "1:8::13", "name": "hello"} 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/StringLiteralDuplicated.threshold_4.slang: -------------------------------------------------------------------------------- 1 | "string literal1"; "string literal1"; "string literal1"; // Compliant - only appears 3 times which is less than the custom threshold of 4 2 | "string literal2"; // Noncompliant {{Define a constant instead of duplicating this literal "string literal2" 4 times.}} 3 | //^^^^^^^^^^^^^^^^^ 4 | "string literal2"; "string literal2"; "string literal2"; 5 | //<^^^^^^^^^^^^^^^^^ <^^^^^^^^^^^^^^^^^ <^^^^^^^^^^^^^^^^^ 6 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: release 2 | # This workflow is triggered when publishing a new github release 3 | # yamllint disable-line rule:truthy 4 | on: 5 | release: 6 | types: 7 | - published 8 | 9 | jobs: 10 | release: 11 | permissions: 12 | id-token: write 13 | contents: write 14 | uses: SonarSource/gh-action_release/.github/workflows/main.yaml@v6 15 | with: 16 | publishToBinaries: true 17 | mavenCentralSync: true 18 | slackChannel: squad-jvm-notifs 19 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/native_tree_empty_kind.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [ 4 | 5 | ], 6 | "tokens": [ 7 | { 8 | "textRange": "1:0::1", 9 | "text": "x" 10 | } 11 | ] 12 | }, 13 | "tree": { 14 | "@type": "Native", 15 | "metaData": "1:0::1", 16 | "children": [ 17 | { 18 | "@type": "Identifier", 19 | "metaData": "1:0::1", 20 | "name": "MyClass" 21 | } 22 | ] 23 | } 24 | } -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/error_invalid_json_tree.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0:1:6", "text": "return", "type": "KEYWORD"}, 6 | {"textRange": "1:7:1:11", "text": "1234", "type": "OTHER"}, 7 | {"textRange": "1:11:1:12", "text": ";", "type": "OTHER"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "Return", 12 | "metaData": "1:0:1:12", 13 | "body": 1234, 14 | "keyword": "1:0:1:6" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /slang-checks/README.md: -------------------------------------------------------------------------------- 1 | # Slang Checks 2 | 3 | SLang Checks contains checks that are common for all languages. 4 | 5 | ## Partially mapped language 6 | 7 | The different checks for a language don't always require all Slang nodes. 8 | The following array is here to track which trees are still mapped to native node, despite the fact that 9 | an equivalent Slang node exists. 10 | 11 | 12 | | Node | Language(s) | 13 | | ------ | ----------- | 14 | | MemberSelect | Scala, Ruby, Go | 15 | | FunctionInvocation | Scala, Ruby, Go | 16 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/catch_tree_without_parameter.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::5", "text": "catch", "type": "KEYWORD"}, 6 | {"textRange": "1:10::11", "text": "y"} 7 | ] 8 | }, 9 | "tree": { 10 | "@type": "Catch", 11 | "metaData": "1:0::11", 12 | "catchParameter": null, 13 | "catchBlock": {"@type": "Identifier", "metaData": "1:10::11", "name": "y"}, 14 | "keyword": "1:0::5" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/return_true.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::6", "text": "return", "type": "KEYWORD"}, 6 | {"textRange": "1:7::11", "text": "true"}, 7 | {"textRange": "1:11::12", "text": ";"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "Return", 12 | "metaData": "1:0::12", 13 | "body": {"@type": "Literal", "metaData": "1:7::11", "value": "true"}, 14 | "keyword": "1:0::6" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/UnusedLocalVariable.slang: -------------------------------------------------------------------------------- 1 | int var global; // Compliant 2 | 3 | void fun fooBar() { 4 | int val a = 0; // Compliant 5 | 6 | int val b; // Noncompliant {{Remove this unused "b" local variable.}} 7 | // ^ 8 | 9 | int var c; // Noncompliant {{Remove this unused "c" local variable.}} 10 | // ^ 11 | 12 | int var d; // Compliant 13 | d = 0; 14 | 15 | int var e; // Compliant 16 | e = d + a; 17 | } 18 | -------------------------------------------------------------------------------- /slang-testing/src/test/resources/file-issue.code.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [ 4 | { 5 | "text": "// Noncompliant@0 {{file-issue.code length 48}}", 6 | "contentText": " Noncompliant@0 {{file-issue.code length 48}}", 7 | "range": "1:0:1:47", 8 | "contentRange": "1:2:1:47" 9 | } 10 | ], 11 | "tokens": [] 12 | }, 13 | "tree": { 14 | "@type": "TopLevel", 15 | "metaData": "1:0:1:47", 16 | "declarations": [], 17 | "firstCpdToken": null 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/native_tree_with_kind.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [ 4 | 5 | ], 6 | "tokens": [ 7 | { 8 | "textRange": "1:0::1", 9 | "text": "x" 10 | } 11 | ] 12 | }, 13 | "tree": { 14 | "@type": "Native", 15 | "metaData": "1:0::1", 16 | "nativeKind": "kind", 17 | "children": [ 18 | { 19 | "@type": "Identifier", 20 | "metaData": "1:0::1", 21 | "name": "MyClass" 22 | } 23 | ] 24 | } 25 | } -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/top_level.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [ 4 | {"text": "// hello", "contentText": " hello", "range": "1:0::8", "contentRange": "1:2::8"} 5 | ], 6 | "tokens": [ 7 | {"textRange": "2:0::4", "text": "true"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "TopLevel", 12 | "metaData": "1:0:2:4", 13 | "declarations": [ 14 | {"@type": "Literal", "metaData": "2:0::4", "value": "true"} 15 | ], 16 | "firstCpdToken": "2:0::4" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /slang-testing/src/test/resources/primary.code.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [ 4 | {"text": "// Noncompliant", "contentText": " Noncompliant", "range": "1:4:1:19", "contentRange": "1:6:1:19"} 5 | ], 6 | "tokens": [ 7 | {"textRange": "1:0:1:3", "text": "foo", "type": "OTHER"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "TopLevel", 12 | "metaData": "1:0:1:19", 13 | "declarations": [ 14 | {"@type": "Identifier", "metaData": "1:0:1:3", "name": "foo"} 15 | ], 16 | "firstCpdToken": "1:0:1:3" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/exception_handling_without_catch.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::3", "text": "try", "type": "KEYWORD"}, 6 | {"textRange": "1:10::11", "text": "x"} 7 | ] 8 | }, 9 | "tree": { 10 | "@type": "ExceptionHandling", 11 | "metaData": "1:0::11", 12 | "tryBlock": {"@type": "Identifier", "metaData": "1:10::11", "name": "x"}, 13 | "tryKeyword": "1:0::3", 14 | "catchBlocks": [], 15 | "finallyBlock": null 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/class_declaration_anonymous.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::5", "text": "class", "type": "KEYWORD"}, 6 | {"textRange": "1:8::9", "text": "{"}, 7 | {"textRange": "1:10::11", "text": "}"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "ClassDeclaration", 12 | "metaData": "1:0::11", 13 | "identifier": null, 14 | "classTree": {"@type": "Native", "metaData": "1:8::11", "nativeKind": "CLASS", "children": []} 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/error_invalid_tree_type.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0:1:6", "text": "return", "type": "KEYWORD"}, 6 | {"textRange": "1:7:1:11", "text": "true", "type": "OTHER"}, 7 | {"textRange": "1:11:1:12", "text": ";", "type": "OTHER"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "Return", 12 | "metaData": "1:0:1:12", 13 | "body": {"@type": "UnsupportedType", "metaData": "1:7:1:11"}, 14 | "keyword": "1:0:1:6" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/TooLongLine_120.slang: -------------------------------------------------------------------------------- 1 | int fun (p1, p2) {} 2 | 3 | // short comment 4 | 5 | // Noncompliant@+1 {{Split this 124 characters long line (which is greater than 120 authorized).}} 6 | int fun fooVeryLongName(fooVeryLongName1, fooVeryLongName2, fooVeryLongName3, fooVeryLongName4, fooVeryLongName5, p6, p7) {} 7 | 8 | // Noncompliant@+1 {{Split this 125 characters long line (which is greater than 120 authorized).}} 9 | // this is a very comment that should raise an issue when its length is greater that 120 characters that is the default value -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/parenthesized_expression.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::1", "text": "("}, 6 | {"textRange": "1:1::2", "text": "x"}, 7 | {"textRange": "1:2::3", "text": ")"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "ParenthesizedExpression", 12 | "metaData": "1:0::3", 13 | "expression": {"@type": "Identifier", "metaData": "1:1::2", "name": "x"}, 14 | "leftParenthesis": "1:0::1", 15 | "rightParenthesis": "1:2::3" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/error_missing_type.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0:1:6", "text": "return", "type": "KEYWORD"}, 6 | {"textRange": "1:7:1:11", "text": "true", "type": "OTHER"}, 7 | {"textRange": "1:11:1:12", "text": ";", "type": "OTHER"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "Return", 12 | "metaData": "1:0:1:12", 13 | "body": {"invalid_type": "Literal", "metaData": "1:7:1:11", "value": "true"}, 14 | "keyword": "1:0:1:6" 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /slang-testing/src/test/resources/wrong-message.code.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [ 4 | {"text": "// Noncompliant {{wrong message}}", "contentText": " Noncompliant {{wrong message}}", "range": "1:4:1:37", "contentRange": "1:6:1:37"} 5 | ], 6 | "tokens": [ 7 | {"textRange": "1:0:1:3", "text": "foo", "type": "OTHER"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "TopLevel", 12 | "metaData": "1:0:1:37", 13 | "declarations": [ 14 | {"@type": "Identifier", "metaData": "1:0:1:3", "name": "foo"} 15 | ], 16 | "firstCpdToken": "1:0:1:3" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/catch_tree.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::5", "text": "catch", "type": "KEYWORD"}, 6 | {"textRange": "1:8::9", "text": "x"}, 7 | {"textRange": "1:10::11", "text": "y"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "Catch", 12 | "metaData": "1:0::11", 13 | "catchParameter": {"@type": "Identifier", "metaData": "1:8::9", "name": "x"}, 14 | "catchBlock": {"@type": "Identifier", "metaData": "1:10::11", "name": "y"}, 15 | "keyword": "1:0::5" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/BooleanInversion.slang: -------------------------------------------------------------------------------- 1 | if (!(a == 2)) { }; // Noncompliant {{Use the opposite operator ("!=") instead.}} 2 | // ^^^^^^^^^ 3 | !(i < 10); // Noncompliant {{Use the opposite operator (">=") instead.}} 4 | !(i > 10); // Noncompliant {{Use the opposite operator ("<=") instead.}} 5 | !(i != 10); // Noncompliant {{Use the opposite operator ("==") instead.}} 6 | !(i <= 10); // Noncompliant {{Use the opposite operator (">") instead.}} 7 | !(i >= 10); // Noncompliant {{Use the opposite operator ("<") instead.}} 8 | 9 | if (a != 2) { }; 10 | (i >= 10); 11 | !(a + i); -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/assignment_expression.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::1", "text": "x"}, 6 | {"textRange": "1:2::3", "text": "="}, 7 | {"textRange": "1:4::5", "text": "2"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "AssignmentExpression", 12 | "metaData": "1:0::5", 13 | "operator": "EQUAL", 14 | "leftHandSide": {"@type": "Identifier", "metaData": "1:0::1", "name": "x"}, 15 | "statementOrExpression": {"@type": "IntegerLiteral", "metaData": "1:4::5", "value": "2"} 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/match_case.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::4", "text": "case", "type": "KEYWORD"}, 6 | {"textRange": "1:5::6", "text": "7"}, 7 | {"textRange": "1:7::8", "text": ":"}, 8 | {"textRange": "1:9::10", "text": "x"} 9 | ] 10 | }, 11 | "tree": { 12 | "@type": "MatchCase", 13 | "metaData": "1:0::10", 14 | "expression": {"@type": "IntegerLiteral", "metaData": "1:5::6", "value": "7"}, 15 | "body": {"@type": "Identifier", "metaData": "1:9::10", "name": "x"} 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/TooManyCases_3.slang: -------------------------------------------------------------------------------- 1 | match (x) { 2 | 1 -> 'a'; 3 | 2 -> 'b'; 4 | 3 -> 'c'; 5 | }; 6 | 7 | match (x) { // Noncompliant {{Reduce the number of match branches from 4 to at most 3.}} 8 | 1 -> 'a'; 9 | 2 -> 'b'; 10 | 3 -> 'c'; 11 | 4 -> 'd'; 12 | }; 13 | 14 | match (x) { 15 | 1 -> 'a'; 16 | 2 -> 'b'; 17 | else -> 'c'; 18 | }; 19 | 20 | match (x) { // Noncompliant 21 | //^^^^^ 22 | 1 -> 'a'; 23 | // ^^^^< 24 | 2 -> 'b'; 25 | // ^^^^< 26 | 3 -> 'c'; 27 | // ^^^^< 28 | else -> 'd'; 29 | // ^^^^^^^< 30 | }; 31 | -------------------------------------------------------------------------------- /slang-api/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation libs.jsr305 3 | implementation libs.minimal.json 4 | 5 | testImplementation libs.slf4j.api 6 | testImplementation libs.logback.classic 7 | testImplementation testLibs.assertj.core 8 | testImplementation testLibs.mockito.core 9 | testImplementation testLibs.junit.jupiter.api 10 | 11 | testRuntimeOnly testLibs.junit.jupiter.engine 12 | } 13 | 14 | publishing { 15 | publications { 16 | mavenJava(MavenPublication) { 17 | artifact jar 18 | artifact sourcesJar 19 | artifact javadocJar 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/binary_expression.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::1", "text": "x"}, 6 | {"textRange": "1:2::3", "text": "<"}, 7 | {"textRange": "1:4::5", "text": "y"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "BinaryExpression", 12 | "metaData": "1:0::5", 13 | "operator": "LESS_THAN", 14 | "operatorToken": "1:2::3", 15 | "leftOperand": {"@type": "Identifier", "metaData": "1:0::1", "name": "x"}, 16 | "rightOperand": {"@type": "Identifier", "metaData": "1:4::5", "name": "y"} 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/BadClassName.slang: -------------------------------------------------------------------------------- 1 | class myClass{} // Noncompliant {{Rename class "myClass" to match the regular expression ^[A-Z][a-zA-Z0-9]*$.}} 2 | // ^^^^^^^ 3 | 4 | class My_Class{} // Noncompliant {{Rename class "My_Class" to match the regular expression ^[A-Z][a-zA-Z0-9]*$.}} 5 | 6 | class my_class{} // Noncompliant {{Rename class "my_class" to match the regular expression ^[A-Z][a-zA-Z0-9]*$.}} 7 | 8 | class MyClass{} // Compliant 9 | 10 | class MyClassC{} // Compliant 11 | 12 | class MyClass${} // Noncompliant {{Rename class "MyClass$" to match the regular expression ^[A-Z][a-zA-Z0-9]*$.}} 13 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/loop.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::5", "text": "while", "type": "KEYWORD"}, 6 | {"textRange": "1:6::10", "text": "true"}, 7 | {"textRange": "1:11::12", "text": "x", "type": "KEYWORD"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "Loop", 12 | "metaData": "1:0::12", 13 | "condition": {"@type": "Literal", "metaData": "1:6::10", "value": "true"}, 14 | "body": {"@type": "Identifier", "metaData": "1:11::12", "name": "x"}, 15 | "kind": "WHILE", 16 | "keyword": "1:0::5" 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/error_unexpected_match_child_class.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0:1:6", "text": "switch", "type": "KEYWORD"}, 6 | {"textRange": "1:9:1:16", "text": "default", "type": "KEYWORD"}, 7 | {"textRange": "1:17:1:19", "text": "42", "type": "OTHER"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "Match", 12 | "metaData": "1:0:1:19", 13 | "expression": null, 14 | "cases": [ 15 | {"@type": "IntegerLiteral", "metaData": "1:17:1:19", "value": "42"} 16 | ], 17 | "keyword": "1:0:1:6" 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/EmptyFunction.slang: -------------------------------------------------------------------------------- 1 | fun noBody(); 2 | 3 | fun notEmpty() { bar() } 4 | 5 | // Noncompliant@+1 6 | fun empty() {} 7 | // ^^ 8 | 9 | fun containingOnlyAComment() { /* comment */ } 10 | 11 | fun emptyWithEndOfLineComment1() {} // end of line comment 12 | 13 | fun emptyWithEndOfLineComment2() { } /* comment */ 14 | 15 | fun emptyWithEndOfLineCommentOnMultipleLine() { } /* comment 16 | */ 17 | 18 | fun emptyOnSeveralLine() { 19 | } // comment 20 | 21 | // Noncompliant@+1 22 | fun empty() { 23 | } 24 | 25 | class A { 26 | // Compliant, constructor 27 | fun constructor() { 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # --- Gradle 2 | .gradle/ 3 | build/ 4 | 5 | # ---- Maven 6 | target/ 7 | dependency-reduced-pom.xml 8 | 9 | # ---- SonarQube analysis 10 | .scannerwork/ 11 | .sonar/ 12 | 13 | # ---- IntelliJ IDEA 14 | *.iws 15 | *.iml 16 | *.ipr 17 | .idea/ 18 | out/ 19 | bin/ 20 | 21 | # ---- Eclipse 22 | .classpath 23 | .project 24 | .settings 25 | 26 | # ---- Mac OS X 27 | .DS_Store 28 | Icon? 29 | # Thumbnails 30 | ._* 31 | # Files that might appear on external disk 32 | .Spotlight-V100 33 | .Trashes 34 | 35 | # ---- Windows 36 | # Windows image file caches 37 | Thumbs.db 38 | # Folder config file 39 | Desktop.ini 40 | 41 | .java-version 42 | test-report.out 43 | 44 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/TooComplexExpression_3.slang: -------------------------------------------------------------------------------- 1 | a && b; 2 | a && b || c; 3 | a && b || c && d; 4 | a && b || c && d || e; // Noncompliant {{Reduce the number of conditional operators (4) used in the expression (maximum allowed 3).}} [[effortToFix=1]] 5 | a && b || c && d || e && f; // Noncompliant [[effortToFix=2]] 6 | //^^^^^^^^^^^^^^^^^^^^^^^^^^ 7 | if (a && b || c && d || e && f) {}; // Noncompliant 8 | if (a && (b || c) && (d || e && f)) {}; // Noncompliant 9 | if (a && b || c) {}; 10 | if (!(a && b || c && d)) {}; 11 | if (!(a && b || c && d || e)) {}; // Noncompliant 12 | foo(a && b) && foo(a || b) && foo(a && b); 13 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/native_tree.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "10:0::7", "text": "token10"}, 6 | {"textRange": "21:0::7", "text": "token21"}, 7 | {"textRange": "22:0::7", "text": "token22"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "Native", 12 | "metaData": "10:0:22:7", 13 | "nativeKind": "PARENT", 14 | "children": [ 15 | {"@type": "Native", "metaData": "21:0::7", "nativeKind": "CHILD", "children": []}, 16 | {"@type": "Native", "metaData": "22:0::7", "nativeKind": "CHILD", "children": []} 17 | ] 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/if_tree_without_else.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::2", "text": "if", "type": "KEYWORD"}, 6 | {"textRange": "1:3::7", "text": "true"}, 7 | {"textRange": "1:8::9", "text": "x"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "If", 12 | "metaData": "1:0::9", 13 | "condition": {"@type": "Literal", "metaData": "1:3::7", "value": "true"}, 14 | "thenBranch": {"@type": "Identifier", "metaData": "1:8::9", "name": "x"}, 15 | "elseBranch": null, 16 | "ifKeyword": "1:0::2", 17 | "elseKeyword": null 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /slang-checks/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compileOnly libs.sonar.plugin.api 3 | 4 | implementation project(':slang-api') 5 | implementation libs.sonar.analyzer.commons 6 | 7 | testImplementation project(':slang-antlr') 8 | testImplementation project(':slang-testing') 9 | testImplementation testLibs.assertj.core 10 | testImplementation testLibs.junit.jupiter.api 11 | 12 | testRuntimeOnly testLibs.junit.jupiter.engine 13 | } 14 | 15 | publishing { 16 | publications { 17 | mavenJava(MavenPublication) { 18 | artifact jar 19 | artifact sourcesJar 20 | artifact javadocJar 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /checkstyle-import/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compileOnly libs.sonar.plugin.api 3 | 4 | implementation libs.sonar.xml.parsing 5 | 6 | testImplementation project(':slang-testing') 7 | testImplementation libs.slf4j.api 8 | testImplementation testLibs.assertj.core 9 | testImplementation testLibs.junit.jupiter.api 10 | testImplementation testLibs.sonar.plugin.api.impl 11 | 12 | testRuntimeOnly testLibs.junit.jupiter.engine 13 | } 14 | 15 | publishing { 16 | publications { 17 | mavenJava(MavenPublication) { 18 | artifact jar 19 | artifact sourcesJar 20 | artifact javadocJar 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.github/workflows/mark-prs-stale.yml: -------------------------------------------------------------------------------- 1 | name: 'Close stale PRs' 2 | on: 3 | workflow_dispatch: 4 | schedule: 5 | - cron: '30 2 * * *' 6 | 7 | jobs: 8 | stale: 9 | runs-on: sonar-runner 10 | permissions: 11 | issues: write 12 | pull-requests: write 13 | steps: 14 | - uses: actions/stale@v9 15 | with: 16 | stale-pr-message: 'This PR is stale because it has been open 7 days with no activity. If there is no activity in the next 7 days it will be closed automatically' 17 | stale-pr-label: 'stale' 18 | days-before-stale: 7 19 | days-before-close: 7 20 | exempt-pr-labels: 'do-not-close,External Contribution' 21 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/variable_declaration.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::3", "text": "int"}, 6 | {"textRange": "1:4::5", "text": "x"}, 7 | {"textRange": "1:6::8", "text": "42"} 8 | ] 9 | }, 10 | "tree": { 11 | "@type": "VariableDeclaration", 12 | "metaData": "1:0::8", 13 | "identifier": {"@type": "Identifier", "metaData": "1:4::5", "name": "x"}, 14 | "type": {"@type": "Identifier", "metaData": "1:0::3", "name": "int"}, 15 | "initializer": {"@type": "IntegerLiteral", "metaData": "1:6::8", "value": "42"}, 16 | "isVal": true 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/EmptyBlock.slang: -------------------------------------------------------------------------------- 1 | void fun a() {} 2 | 3 | void fun b() { 4 | // comment 5 | } 6 | 7 | fun () { 8 | // comment 9 | } 10 | 11 | fun () { 12 | // Noncompliant@+1 13 | if (x > 0) { }; 14 | } 15 | 16 | void fun c(int x) { 17 | // Noncompliant@+1 18 | if (x > 0) { }; 19 | 20 | if (x > 1) { 21 | // comment 22 | }; 23 | 24 | match (x) { 25 | // comment 26 | }; 27 | 28 | // Noncompliant@+1 29 | match (x) { 30 | 31 | }; 32 | 33 | match (x) { 34 | // Noncompliant@+1 35 | 1 -> { }; 36 | 2 -> x; 37 | else -> { x; }; 38 | }; 39 | 40 | while (cond) {} // Compliant - exception to the rule 41 | } -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/IdenticalBinaryOperand.slang: -------------------------------------------------------------------------------- 1 | x == 1; 2 | 1 == 1; // Noncompliant {{Correct one of the identical sub-expressions on both sides this operator}} 3 | 1 == (1); // Noncompliant {{Correct one of the identical sub-expressions on both sides this operator}} 4 | (1 + 2) == 1 + 2; // Noncompliant 5 | (1 + 2) == ((1 + 2)); // Noncompliant 6 | (1 + 2) == ((1 + 2 + 3)); 7 | x 8 | //^> 9 | == x; // Noncompliant 10 | // ^ 11 | 1 == 2; 12 | x = x; 13 | x + x; 14 | x * x; 15 | x <= x; // Noncompliant 16 | _x <= _x; // Noncompliant 17 | x_ <= x_; // Noncompliant 18 | _x <= x_; 19 | x <= _; 20 | _ <= y; 21 | _ <= _; 22 | -------------------------------------------------------------------------------- /slang-testing/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | implementation project(':slang-api') 3 | implementation libs.logback.classic 4 | 5 | implementation testLibs.classgraph 6 | implementation testLibs.assertj.core 7 | implementation testLibs.mockito.core 8 | implementation testLibs.junit.jupiter.engine 9 | implementation testLibs.sonar.plugin.api.impl 10 | implementation testLibs.sonar.analyzer.test.commons 11 | testImplementation testLibs.junit.jupiter.api 12 | } 13 | 14 | publishing { 15 | publications { 16 | mavenJava(MavenPublication) { 17 | artifact jar 18 | artifact sourcesJar 19 | artifact javadocJar 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /checkstyle-import/src/test/resources/externalreport/detekt-checkstyle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/TooLongFunction_3.slang: -------------------------------------------------------------------------------- 1 | fun f1() { 2 | a; a; 3 | } 4 | 5 | fun f1() { // Noncompliant {{This function has 4 lines of code, which is greater than the 3 authorized. Split it into smaller functions.}} 6 | // ^^ 7 | a; 8 | a; 9 | } 10 | 11 | fun f1() { 12 | 13 | a; 14 | } 15 | 16 | fun f1() { 17 | // comment 18 | a; 19 | } 20 | 21 | int fun foo( // Compliant, no line of code 22 | p1, 23 | p2, 24 | p3, 25 | p4) 26 | { 27 | } 28 | 29 | int fun foo( 30 | p1, 31 | p2, 32 | p3, 33 | p4); 34 | 35 | int fun ( 36 | p1, 37 | p2, 38 | p3, 39 | p4); 40 | 41 | int fun () // Noncompliant 42 | // ^^^^^^^^^^ 43 | { 44 | a; 45 | a; 46 | a; 47 | a; 48 | } 49 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/MatchCaseTooBig_3.slang: -------------------------------------------------------------------------------- 1 | match (x) { 2 | 1 -> { // Noncompliant {{Reduce this case clause number of lines from 4 to at most 3, for example by extracting code into methods.}} 3 | // ^^^^ 4 | a = 1; 5 | print(a); 6 | }; 7 | else -> b; 8 | }; 9 | 10 | match (x) { 11 | 1 -> foo(); 12 | else -> { // Noncompliant {{Reduce this case clause number of lines from 4 to at most 3, for example by extracting code into methods.}} 13 | // ^^^^^^^ 14 | a = 1; 15 | print(a); 16 | }; 17 | }; 18 | 19 | match (x) { 20 | 1 -> foo(); // OK 21 | // comments should be ignored 22 | // another comment 23 | 24 | else -> b; 25 | }; 26 | -------------------------------------------------------------------------------- /.github/workflows/slack_notify.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Slack Notifications 3 | on: 4 | check_suite: 5 | types: [completed] 6 | 7 | permissions: 8 | contents: read 9 | checks: read 10 | id-token: write 11 | 12 | jobs: 13 | slack-notifications: 14 | if: >- 15 | contains(fromJSON('["main", "master"]'), github.event.check_suite.head_branch) || startsWith(github.event.check_suite.head_branch, 'dogfood-') || startsWith(github.event.check_suite.head_branch, 'branch-') 16 | runs-on: sonar-runner 17 | steps: 18 | - name: Send Slack Notification 19 | env: 20 | GITHUB_TOKEN: ${{ github.token }} 21 | uses: SonarSource/gh-action_slack-notify@v1 22 | with: 23 | slackChannel: squad-jvm-notifs 24 | -------------------------------------------------------------------------------- /LICENSE_HEADER: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-$YEAR SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/class_declaration.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::5", "text": "class", "type": "KEYWORD"}, 6 | {"textRange": "1:6::7", "text": "A"}, 7 | {"textRange": "1:8::9", "text": "{"}, 8 | {"textRange": "1:10::11", "text": "}"} 9 | ] 10 | }, 11 | "tree": { 12 | "@type": "ClassDeclaration", 13 | "metaData": "1:0::11", 14 | "identifier": "1:6::7", 15 | "classTree": { 16 | "@type": "Native", 17 | "metaData": "1:6::11", 18 | "nativeKind": "CLASS", 19 | "children": [ 20 | {"@type": "Identifier", "metaData": "1:6::7", "name": "A"} 21 | ] 22 | } 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /checkstyle-import/src/test/resources/externalreport/detekt-checkstyle-with-errors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /slang-antlr/src/test/resources/annotations.slang: -------------------------------------------------------------------------------- 1 | @MyAnnotation 2 | @MyAnnotation("Something") 3 | @MyAnnotation(value = "Something") 4 | @MyAnnotation(value = {"Something"}) 5 | @MyAnnotation(value = {"Something", "else"}) 6 | @MyAnnotation("something", "else") 7 | @MyAnnotation("something", value = "else") 8 | @MyAnnotation(value = "something", value = {"else", "and", "more"}) 9 | class { 10 | @MyFieldAnnotation 11 | int val x; 12 | 13 | @MyMethodAnnotation 14 | int fun test() { 15 | @MyLocalVariableAnnotation 16 | int val y; 17 | } 18 | 19 | int fun test(@MyParameterAnnotation int a) {} 20 | 21 | int fun foo(int a, @B int b, @C int c, int d) {} 22 | 23 | void fun bar(@Suppress("slang:S1764") int a = (1 == 1), int b = (1 == 1)) {} 24 | 25 | } 26 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/parameter.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::9", "text": "@Nullable"}, 6 | {"textRange": "2:0::1", "text": "x"}, 7 | {"textRange": "2:2::5", "text": "int"}, 8 | {"textRange": "2:6::8", "text": "42"} 9 | ] 10 | }, 11 | "tree": { 12 | "@type": "Parameter", 13 | "metaData": "1:0:2:8", 14 | "identifier": {"@type": "Identifier", "metaData": "2:0::1", "name": "x"}, 15 | "type": {"@type": "Identifier", "metaData": "2:2::5", "name": "int"}, 16 | "defaultValue": {"@type": "IntegerLiteral", "metaData": "2:6::8", "value": "42"}, 17 | "modifiers": [ 18 | {"@type": "Identifier", "metaData": "1:0::9", "name": "@Nullable"} 19 | ] 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/if_tree.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::2", "text": "if", "type": "KEYWORD"}, 6 | {"textRange": "1:3::7", "text": "true"}, 7 | {"textRange": "1:8::9", "text": "x"}, 8 | {"textRange": "1:10::14", "text": "else"}, 9 | {"textRange": "1:15::16", "text": "y"} 10 | ] 11 | }, 12 | "tree": { 13 | "@type": "If", 14 | "metaData": "1:0::16", 15 | "condition": {"@type": "Literal", "metaData": "1:3::7", "value": "true"}, 16 | "thenBranch": {"@type": "Identifier", "metaData": "1:8::9", "name": "x"}, 17 | "elseBranch": {"@type": "Identifier", "metaData": "1:15::16", "name": "y"}, 18 | "ifKeyword": "1:0::2", 19 | "elseKeyword": "1:10::14" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/match.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::6", "text": "switch", "type": "KEYWORD"}, 6 | {"textRange": "1:7::8", "text": "x"}, 7 | {"textRange": "1:9::16", "text": "default", "type": "KEYWORD"}, 8 | {"textRange": "1:17::19", "text": "42"} 9 | ] 10 | }, 11 | "tree": { 12 | "@type": "Match", 13 | "metaData": "1:0::19", 14 | "expression": {"@type": "Identifier", "metaData": "1:7::8", "name": "x"}, 15 | "cases": [ 16 | { 17 | "@type": "MatchCase", 18 | "metaData": "1:9::19", 19 | "expression": null, 20 | "body": {"@type": "IntegerLiteral", "metaData": "1:17::19", "value": "42"} 21 | } 22 | ], 23 | "keyword": "1:0::6" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/WrongAssignmentOperator.slang: -------------------------------------------------------------------------------- 1 | target =-num; // Noncompliant {{Was "-=" meant instead?}} 2 | // ^^ 3 | target = 4 | -num; 5 | target = -num; // Compliant intent to assign inverse value of num is clear 6 | target =--num; 7 | 8 | target += num; 9 | target =+ num; // Noncompliant {{Was "+=" meant instead?}} 10 | // ^^ 11 | target = 12 | + num; 13 | target = 14 | +num; 15 | target = +num; 16 | target =++num; 17 | target=+num; // Compliant - no spaces between variable, operator and expression 18 | 19 | a = b != c; 20 | a = b =! c; // Noncompliant {{Was "!=" meant instead?}} [[sc=11;ec=13]] 21 | a = b =!! c; // Noncompliant 22 | a = b = !c; 23 | a =! c; // Noncompliant {{Add a space between "=" and "!" to avoid confusion.}} 24 | a = ! c; 25 | a = !c; 26 | a = 27 | !c; 28 | -------------------------------------------------------------------------------- /slang-testing/src/test/resources/primary-and-secondary.code.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [ 4 | {"text": "// Noncompliant {{primary}}", "contentText": " Noncompliant {{primary}}", "range": "1:7:1:34", "contentRange": "1:9:1:34"}, 5 | {"text": "// ^ ^< {{secondary}}", "contentText": " ^ ^< {{secondary}}", "range": "2:0:2:21", "contentRange": "2:2:2:21"} 6 | ], 7 | "tokens": [ 8 | {"textRange": "1:3:1:4", "text": "a", "type": "OTHER"}, 9 | {"textRange": "1:5:1:6", "text": "b", "type": "OTHER"} 10 | ] 11 | }, 12 | "tree": { 13 | "@type": "TopLevel", 14 | "metaData": "1:0:2:21", 15 | "declarations": [ 16 | {"@type": "Identifier", "metaData": "1:3:1:4", "name": "a"}, 17 | {"@type": "Identifier", "metaData": "1:5:1:6", "name": "b"} 18 | ], 19 | "firstCpdToken": "1:3:1:4" 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/IdenticalConditions.slang: -------------------------------------------------------------------------------- 1 | // if 2 | 3 | if (x) { 4 | } else if (x) { // Noncompliant {{This condition duplicates the one on line 3.}} 5 | }; 6 | 7 | if (x) {}; 8 | if (x) {} else {}; 9 | if (x) {} else if (y) {}; 10 | if (x) {} else if (x) {}; // Noncompliant 11 | // ^> ^ 12 | if (x) {} else if (y) {} else if (z) {}; 13 | if (x) {} else if (y) {} else if (y) {}; // Noncompliant 14 | // ^> ^ 15 | if (x) {} else if (x) {} else if (x) {}; // Noncompliant 2 16 | if (x) {} else if (y) {} else if ((y)) {}; // Noncompliant 17 | 18 | 19 | // match 20 | 21 | match (x) { 1 -> a; }; 22 | match (x) { 1 -> a; else -> b; }; 23 | match (x) { 1 -> a; 2 -> b; }; 24 | match (x) { 1 -> a; 1 -> b; }; // Noncompliant 25 | // ^> ^ 26 | match (x) { 1 -> a; (1) -> b; }; // Noncompliant 27 | -------------------------------------------------------------------------------- /slang-plugin/build.gradle: -------------------------------------------------------------------------------- 1 | dependencies { 2 | compileOnly libs.sonar.plugin.api 3 | 4 | implementation project(':slang-api') 5 | implementation project(':slang-checks') 6 | implementation libs.sonar.analyzer.commons 7 | implementation libs.commons.codec 8 | 9 | testImplementation project(':slang-antlr') 10 | testImplementation project(':slang-testing') 11 | testImplementation testLibs.mockito.core 12 | testImplementation testLibs.assertj.core 13 | testImplementation testLibs.junit.jupiter.api 14 | testImplementation testLibs.sonar.plugin.api.impl 15 | 16 | testRuntimeOnly testLibs.junit.jupiter.engine 17 | } 18 | 19 | publishing { 20 | publications { 21 | mavenJava(MavenPublication) { 22 | artifact jar 23 | artifact sourcesJar 24 | artifact javadocJar 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/NativeKind.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface NativeKind { 20 | } 21 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | @javax.annotation.ParametersAreNonnullByDefault 18 | package org.sonarsource.slang.api; 19 | -------------------------------------------------------------------------------- /.github/workflows/ToggleLockBranch.yml: -------------------------------------------------------------------------------- 1 | name: Toggle lock branch 2 | 3 | on: 4 | workflow_dispatch: # Triggered manually from the GitHub UI / Actions 5 | 6 | jobs: 7 | ToggleLockBranch_job: 8 | name: Toggle lock branch 9 | runs-on: sonar-runner 10 | permissions: 11 | id-token: write 12 | steps: 13 | - id: secrets 14 | uses: SonarSource/vault-action-wrapper@v3 15 | with: 16 | secrets: | 17 | development/github/token/{REPO_OWNER_NAME_DASH}-lock token | lock_token; 18 | development/kv/data/slack token | slack_api_token; 19 | - uses: sonarsource/gh-action-lt-backlog/ToggleLockBranch@v2 20 | with: 21 | github-token: ${{ fromJSON(steps.secrets.outputs.vault).lock_token }} 22 | slack-token: ${{ fromJSON(steps.secrets.outputs.vault).slack_api_token }} 23 | slack-channel: squad-jvm-notifs 24 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/impl/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | @javax.annotation.ParametersAreNonnullByDefault 18 | package org.sonarsource.slang.impl; 19 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/utils/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | @javax.annotation.ParametersAreNonnullByDefault 18 | package org.sonarsource.slang.utils; 19 | -------------------------------------------------------------------------------- /slang-antlr/src/main/java/org/sonarsource/slang/parser/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | @javax.annotation.ParametersAreNonnullByDefault 18 | package org.sonarsource.slang.parser; 19 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/visitors/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | @javax.annotation.ParametersAreNonnullByDefault 18 | package org.sonarsource.slang.visitors; 19 | -------------------------------------------------------------------------------- /slang-checks/src/main/java/org/sonarsource/slang/checks/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | @javax.annotation.ParametersAreNonnullByDefault 18 | package org.sonarsource.slang.checks; 19 | -------------------------------------------------------------------------------- /slang-plugin/src/main/java/org/sonarsource/slang/plugin/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | @javax.annotation.ParametersAreNonnullByDefault 18 | package org.sonarsource.slang.plugin; 19 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/checks/api/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | @javax.annotation.ParametersAreNonnullByDefault 18 | package org.sonarsource.slang.checks.api; 19 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/TodoComment.slang: -------------------------------------------------------------------------------- 1 | // comment 1 2 | 3 | // Noncompliant@+1 4 | // TODO 5 | 6 | // Noncompliant@+1 7 | // TODO just do it 8 | // ^^^^ 9 | 10 | // Noncompliant@+1 11 | // Todo just do it 12 | 13 | // Noncompliant@+1 14 | // This is a TODO just do it 15 | 16 | // This is not aTODO comment 17 | 18 | /* 19 | Multiline comment 20 | */ 21 | 22 | // Noncompliant@+2 23 | /* 24 | TODO Multiline comment */ 25 | //^^^^ 26 | 27 | // Noncompliant@+2 28 | /* 29 | TODO Multiline comment */ 30 | 31 | // Noncompliant@+1 32 | //todo comment 33 | //^^^^ 34 | 35 | // notatodo comment 36 | 37 | // not2todo comment 38 | 39 | // a todolist 40 | 41 | // Noncompliant@+1 42 | // todo: things to do 43 | 44 | // Noncompliant@+1 45 | // :TODO: things to do 46 | 47 | // Noncompliant@+1 48 | // valid end of line todo 49 | 50 | // Noncompliant@+1 51 | // valid end of file todo -------------------------------------------------------------------------------- /slang-testing/src/main/java/org/sonarsource/slang/testing/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | @javax.annotation.ParametersAreNonnullByDefault 18 | package org.sonarsource.slang.testing; 19 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/persistence/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | @javax.annotation.ParametersAreNonnullByDefault 18 | package org.sonarsource.slang.persistence; 19 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/OneStatementPerLine.slang: -------------------------------------------------------------------------------- 1 | print("Hello World!"); print("Hello World!"); //Noncompliant {{Reformat the code to have only one statement per line.}} 2 | 3 | if (a) {}; if (b) {}; // Noncompliant 4 | // ^^^^^^^^^ 5 | 6 | fun foo() {} fun foo() {} // Noncompliant 7 | // ^^^^^^^^^^^^ 8 | 9 | fun foo() { 10 | if (a) {}; if (b) {}; // Noncompliant 11 | // ^^^^^^^^^ 12 | } 13 | 14 | if (a) { 15 | a(); b(); // Noncompliant 16 | // ^^^ 17 | }; 18 | 19 | a(); b(); c(); // Noncompliant 20 | // ^^^ ^^^< 21 | 22 | if(a) { foo(); // FN 23 | b = 2; 24 | }; 25 | 26 | val a = 1; val b = 1; // Noncompliant 27 | 28 | match (x) { 29 | 1 -> { 30 | a(); b(); // Noncompliant 31 | }; 32 | else -> print(1); 33 | }; 34 | 35 | fun foo() { print(); } // OK 36 | 37 | fun foo() { print(); 38 | foo(); 39 | } // OK 40 | 41 | if (a) { b; }; // OK -------------------------------------------------------------------------------- /slang-plugin/src/main/java/org/sonarsource/slang/plugin/VisibleForTesting.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.plugin; 18 | 19 | public @interface VisibleForTesting { 20 | } 21 | -------------------------------------------------------------------------------- /slang-checks/src/main/java/org/sonarsource/slang/checks/utils/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | @javax.annotation.ParametersAreNonnullByDefault 18 | package org.sonarsource.slang.checks.utils; 19 | -------------------------------------------------------------------------------- /slang-plugin/src/main/java/org/sonarsource/slang/plugin/caching/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | @javax.annotation.ParametersAreNonnullByDefault 18 | package org.sonarsource.slang.plugin.caching; 19 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/HasKeyword.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface HasKeyword { 20 | 21 | Token keyword(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/ImportDeclarationTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface ImportDeclarationTree extends Tree { 20 | } 21 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/PackageDeclarationTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface PackageDeclarationTree extends Tree { 20 | } 21 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/FixMeComment.slang: -------------------------------------------------------------------------------- 1 | // comment 1 2 | 3 | // Noncompliant@+1 4 | // FIXME 5 | 6 | // Noncompliant@+1 7 | // FIXME just do it 8 | // ^^^^^ 9 | 10 | // Noncompliant@+1 11 | // Fixme just do it 12 | 13 | // Noncompliant@+1 14 | // This is a FIXME just do it 15 | 16 | // This is not aFIXME comment 17 | 18 | /* 19 | Multiline comment 20 | */ 21 | 22 | // Noncompliant@+2 23 | /* 24 | FiXmE Multiline comment */ 25 | //^^^^^ 26 | 27 | // Noncompliant@+2 28 | /* 29 | fixme Multiline comment */ 30 | 31 | // Noncompliant@+1 32 | //fixme comment 33 | //^^^^^ 34 | 35 | // notafixme comment 36 | 37 | // not2fixme comment 38 | 39 | // a fixmelist 40 | 41 | // Noncompliant@+1 42 | // fixme: things to do 43 | 44 | // Noncompliant@+1 45 | // :fixme: things to do 46 | 47 | // Noncompliant@+1 48 | // valid end of line fixme 49 | 50 | // Noncompliant@+1 51 | // valid end of file fixme -------------------------------------------------------------------------------- /slang-plugin/src/main/java/org/sonarsource/slang/plugin/converter/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | @javax.annotation.ParametersAreNonnullByDefault 18 | package org.sonarsource.slang.plugin.converter; 19 | -------------------------------------------------------------------------------- /slang-checks/src/main/java/org/sonarsource/slang/checks/complexity/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | @javax.annotation.ParametersAreNonnullByDefault 18 | package org.sonarsource.slang.checks.complexity; 19 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/HasTextRange.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface HasTextRange { 20 | 21 | TextRange textRange(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/persistence/conversion/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | @javax.annotation.ParametersAreNonnullByDefault 18 | package org.sonarsource.slang.persistence.conversion; 19 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/CodeVerifier.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface CodeVerifier { 20 | boolean containsCode(String content); 21 | } 22 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/LiteralTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface LiteralTree extends Tree { 20 | 21 | String value(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/NativeTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface NativeTree extends Tree { 20 | 21 | NativeKind nativeKind(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/IfConditionalAlwaysTrueOrFalse.slang: -------------------------------------------------------------------------------- 1 | if (true) { // Noncompliant {{Remove this useless "if" statement.}} 2 | // ^^^^ 3 | return 1 4 | }; 5 | 6 | if (false) { // Noncompliant 7 | return 1 8 | }; 9 | 10 | if (condition) { 11 | return 1 12 | } else if (true) { // Noncompliant 13 | return 1 14 | }; 15 | 16 | if (true) // Noncompliant 17 | return 1; 18 | 19 | if (((true))) // Noncompliant 20 | return 1; 21 | 22 | if (!true) // Noncompliant 23 | return 1 24 | else if (cond && false) { // Noncompliant 25 | return 1 26 | } else if (cond || false) 27 | return 1 28 | else if (cond1 || cond2 || true) // Noncompliant 29 | return 1 30 | else if (cond && cond2 && !true && cond3) { // Noncompliant 31 | return 1 32 | } else if (cond && !(cond2 && (!true && cond3))) { // Noncompliant 33 | return 1 34 | }; 35 | 36 | 37 | x = if (true) 1 else 2; // Noncompliant 38 | x = if (!condition) 1 else 2; -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/StringLiteralTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface StringLiteralTree extends LiteralTree { 20 | 21 | String content(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/checks/api/SlangCheck.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks.api; 18 | 19 | public interface SlangCheck { 20 | 21 | void initialize(InitContext init); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/VariableAndParameterName.slang: -------------------------------------------------------------------------------- 1 | var NOT_LOCAL; 2 | 3 | fun localVariables() { 4 | var localVar; 5 | var INVALID_LOCAL; // Noncompliant {{Rename this local variable to match the regular expression "^[_a-z][a-zA-Z0-9]*$".}} 6 | // ^^^^^^^^^^^^^ 7 | var invalid_local; // Noncompliant 8 | } 9 | 10 | fun parameters(param1, PARAM2, param3) { // Noncompliant {{Rename this parameter to match the regular expression "^[_a-z][a-zA-Z0-9]*$".}} 11 | // ^^^^^^ 12 | } 13 | 14 | native [] { 15 | [ 16 | var POSSIBLY_NOT_LOCAL; 17 | ] 18 | }; 19 | 20 | class A { 21 | fun constructor(param1, PARAM2) { // Noncompliant 22 | // ^^^^^^ 23 | } 24 | fun method(param1, PARAM2) { // Noncompliant 25 | // ^^^^^^ 26 | } 27 | } 28 | 29 | fun method(_) { } 30 | 31 | // testing corner case where the identifier syntax is not supported 32 | fun method(__) { } -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/PlaceHolderTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface PlaceHolderTree extends IdentifierTree { 20 | 21 | Token placeHolderToken(); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/FunctionCognitiveComplexity.slang: -------------------------------------------------------------------------------- 1 | fun ok() { 2 | if (x) { 3 | if (y) { 4 | foo(); 5 | }; 6 | }; 7 | if (z) { 8 | foo(); 9 | }; 10 | } 11 | 12 | fun ko() { // Noncompliant {{Refactor this method to reduce its Cognitive Complexity from 5 to the 4 allowed.}} [[effortToFix=1]] 13 | // ^^ 14 | if (x) { 15 | //^^< {{+1}} 16 | if (y) { 17 | // ^^< {{+2 (incl 1 for nesting)}} 18 | foo(); 19 | }; 20 | if (z) { 21 | // ^^< {{+2 (incl 1 for nesting)}} 22 | foo(); 23 | }; 24 | }; 25 | } 26 | 27 | fun logical_operators() { // Noncompliant 28 | // ^^^^^^^^^^^^^^^^^ 29 | if (a 30 | //^^< 31 | && b && c 32 | // ^^< 33 | || d || e 34 | // ^^< 35 | && f 36 | // ^^< 37 | || g) { 38 | // ^^< 39 | foo(); 40 | } 41 | } 42 | 43 | fun nesting_anonymous() { // Noncompliant 44 | fun() { 45 | a && b || c && d || e && f; 46 | } 47 | } 48 | 49 | -------------------------------------------------------------------------------- /checkstyle-import/src/main/java/org/sonarsource/slang/externalreport/package-info.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | @ParametersAreNonnullByDefault 18 | package org.sonarsource.slang.externalreport; 19 | 20 | import javax.annotation.ParametersAreNonnullByDefault; 21 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/AllBranchesIdentical.slang: -------------------------------------------------------------------------------- 1 | 2 | if (x) { foo; }; 3 | if (x) { foo; } else { bar; }; 4 | if (x) { foo; } else { foo; }; // Noncompliant 5 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 6 | 7 | if (x) { foo; } else if (y) { foo; }; 8 | 9 | if (x) { foo; } else if (y) { foo; } else { bar }; 10 | 11 | if (x) { foo; } else if (y) { foo; } else { foo }; // Noncompliant 12 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 13 | 14 | if (x) if (y) return foo else return foo else return bar; // Noncompliant 15 | // ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 16 | 17 | match (x) { }; 18 | match (x) { 1 -> a; }; 19 | match (x) { 1 -> a; else -> b; }; 20 | match (x) { 1 -> a; else -> a; }; // Noncompliant 21 | //^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 22 | match (x) { 1 -> a; 2 -> a; else -> b; }; 23 | match (x) { 1 -> a; 2 -> a; else -> a; }; // Noncompliant 24 | match (x) { else -> b; }; // Compliant: only default case 25 | -------------------------------------------------------------------------------- /slang-antlr/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'antlr' 2 | 3 | dependencies { 4 | antlr (libs.antlr4) { 5 | exclude group: 'org.glassfish', module: 'javax.json' 6 | } 7 | 8 | implementation project(':slang-api') 9 | implementation libs.sonar.analyzer.commons 10 | 11 | testImplementation project(':slang-testing') 12 | testImplementation testLibs.assertj.core 13 | testImplementation testLibs.junit.jupiter.api 14 | 15 | testRuntimeOnly testLibs.junit.jupiter.engine 16 | } 17 | 18 | generateGrammarSource { 19 | maxHeapSize = "64m" 20 | arguments += ['-visitor', '-package', 'org.sonarsource.slang.parser'] 21 | } 22 | 23 | sourceSets { 24 | main { 25 | antlr.srcDirs = [ "$projectDir/src/main/antlr4" ] 26 | } 27 | } 28 | 29 | publishing { 30 | publications { 31 | mavenJava(MavenPublication) { 32 | artifact jar 33 | artifact sourcesJar 34 | artifact javadocJar 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/BlockTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import java.util.List; 20 | 21 | public interface BlockTree extends Tree { 22 | 23 | List statementOrExpressions(); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/MemberSelectTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface MemberSelectTree extends Tree { 20 | 21 | Tree expression(); 22 | 23 | IdentifierTree identifier(); 24 | } 25 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/Comment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface Comment extends HasTextRange { 20 | 21 | String contentText(); 22 | 23 | String text(); 24 | 25 | TextRange contentRange(); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /.github/workflows/PullRequestClosed.yml: -------------------------------------------------------------------------------- 1 | name: Pull Request Closed 2 | 3 | on: 4 | pull_request: 5 | types: [closed] 6 | 7 | jobs: 8 | PullRequestMerged_job: 9 | name: Pull Request Merged 10 | runs-on: sonar-runner 11 | permissions: 12 | id-token: write 13 | pull-requests: read 14 | # For external PR, ticket should be moved manually 15 | if: | 16 | github.event.pull_request.head.repo.full_name == github.repository 17 | steps: 18 | - id: secrets 19 | uses: SonarSource/vault-action-wrapper@v3 20 | with: 21 | secrets: | 22 | development/kv/data/jira user | JIRA_USER; 23 | development/kv/data/jira token | JIRA_TOKEN; 24 | - uses: sonarsource/gh-action-lt-backlog/PullRequestClosed@v2 25 | with: 26 | github-token: ${{secrets.GITHUB_TOKEN}} 27 | jira-user: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_USER }} 28 | jira-token: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_TOKEN }} 29 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/FunctionInvocationTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import java.util.List; 20 | 21 | public interface FunctionInvocationTree extends Tree { 22 | 23 | Tree memberSelect(); 24 | 25 | List arguments(); 26 | } 27 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/ReturnTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import javax.annotation.CheckForNull; 20 | 21 | public interface ReturnTree extends Tree, HasKeyword { 22 | @CheckForNull 23 | Tree body(); 24 | 25 | Token keyword(); 26 | } 27 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/ThrowTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import javax.annotation.CheckForNull; 20 | 21 | public interface ThrowTree extends Tree, HasKeyword { 22 | @CheckForNull 23 | Tree body(); 24 | 25 | Token keyword(); 26 | } 27 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/ModifierTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface ModifierTree extends Tree { 20 | 21 | enum Kind { 22 | PUBLIC, 23 | PRIVATE, 24 | OVERRIDE, 25 | PROTECTED 26 | } 27 | 28 | Kind kind(); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/ParenthesizedExpressionTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface ParenthesizedExpressionTree extends Tree { 20 | 21 | Tree expression(); 22 | 23 | Token leftParenthesis(); 24 | 25 | Token rightParenthesis(); 26 | 27 | } 28 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/CollapsibleIfStatements.slang: -------------------------------------------------------------------------------- 1 | if (a) { 2 | print(a); 3 | print(b); 4 | }; 5 | 6 | if (a) { 7 | } else if (b) { 8 | if (c) { 9 | } 10 | } else { 11 | }; 12 | 13 | if (a) 14 | if (b) { 15 | } else { 16 | }; 17 | 18 | if (a) { // Noncompliant {{Merge this "if" statement with the nested one.}} 19 | // ^^ 20 | if (b) {} 21 | // ^^< 22 | }; 23 | 24 | if (a) { 25 | } else { 26 | if (c) { // Noncompliant {{Merge this "if" statement with the nested one.}} 27 | if (b) {} 28 | } 29 | }; 30 | 31 | if (a) // Noncompliant {{Merge this "if" statement with the nested one.}} 32 | if (b) 33 | print(); 34 | 35 | 36 | if (a) { // Noncompliant 37 | if (b) { 38 | } 39 | }; 40 | 41 | if (a) { // Noncompliant 42 | if (b) { // Noncompliant 43 | if (c) { 44 | } 45 | } 46 | }; 47 | 48 | if (a) { // Noncompliant 49 | if (b) { 50 | if (c) { 51 | } else { 52 | } 53 | } 54 | }; 55 | 56 | if (a) // Noncompliant 57 | if (b) { 58 | }; 59 | 60 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/Token.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface Token extends HasTextRange { 20 | 21 | public enum Type { 22 | KEYWORD, 23 | STRING_LITERAL, 24 | OTHER 25 | } 26 | 27 | String text(); 28 | 29 | Type type(); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/BooleanLiteralCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class BooleanLiteralCheckTest { 22 | @Test 23 | void test() { Verifier.verify("BooleanLiteral.slang", new BooleanLiteralCheck()); } 24 | } -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/EmptyBlockCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class EmptyBlockCheckTest { 22 | 23 | @Test 24 | void test() { Verifier.verify("EmptyBlock.slang", new EmptyBlockCheck()); } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/TooManyParameters.slang: -------------------------------------------------------------------------------- 1 | int fun foo(p1, p2, p3, p4, p5, p6, p7) {} 2 | int fun (p1, p2, p3, p4, p5, p6, p7) {} 3 | 4 | int fun (p1, p2, p3, p4, p5, p6, p7, p8) {} // Noncompliant 5 | int fun foo(p1, p2, p3, p4, p5, p6, p7, p8) {} // Noncompliant {{This function has 8 parameters, which is greater than the 7 authorized.}} 6 | // ^^^ ^^< 7 | 8 | int fun foo(int p1, int p2, int p3, int p4, int p5, int p6, int p7) {} 9 | int fun foo(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) {} // Noncompliant 10 | 11 | override int fun foo(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) {} // OK 12 | private int fun foo(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) {} // Noncompliant 13 | native [] {} int fun foo(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) {} // Noncompliant 14 | 15 | class A { 16 | fun constructor(int p1, int p2, int p3, int p4, int p5, int p6, int p7, int p8) {} // Compliant, constructor 17 | } 18 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/ClassDeclarationTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import javax.annotation.CheckForNull; 20 | 21 | public interface ClassDeclarationTree extends Tree { 22 | 23 | @CheckForNull 24 | IdentifierTree identifier(); 25 | 26 | Tree classTree(); 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/EmptyCommentCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class EmptyCommentCheckTest { 22 | 23 | @Test 24 | void test() { Verifier.verify("EmptyComment.slang", new EmptyCommentCheck()); } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/EmptyFunctionCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class EmptyFunctionCheckTest { 22 | 23 | @Test 24 | void test() { Verifier.verify("EmptyFunction.slang", new EmptyFunctionCheck()); } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/NestedMatchCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class NestedMatchCheckTest { 22 | @Test 23 | void test() { 24 | Verifier.verify("NestedMatch.slang", new NestedMatchCheck()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/CatchTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import javax.annotation.CheckForNull; 20 | 21 | public interface CatchTree extends Tree { 22 | 23 | Token keyword(); 24 | 25 | @CheckForNull 26 | Tree catchParameter(); 27 | 28 | Tree catchBlock(); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/IdentifierTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface IdentifierTree extends Tree { 20 | 21 | String name(); 22 | 23 | // identifier is used for equivalence comparison 24 | default String identifier() { 25 | return name(); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/TextPointer.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface TextPointer extends Comparable { 20 | 21 | /** 22 | * Starts at 1 23 | */ 24 | int line(); 25 | 26 | /** 27 | * Starts at 0 28 | */ 29 | int lineOffset(); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/ElseIfWithoutElseCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class ElseIfWithoutElseCheckTest { 22 | @Test 23 | void test() { Verifier.verify("ElseIfWithoutElse.slang", new ElseIfWithoutElseCheck()); } 24 | } 25 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/HardcodedIpCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class HardcodedIpCheckTest { 22 | @Test 23 | void test() { 24 | Verifier.verify("HardcodedIp.slang", new HardcodedIpCheck()); 25 | } 26 | 27 | } 28 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/DuplicateBranchCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class DuplicateBranchCheckTest { 22 | 23 | @Test 24 | void test() { Verifier.verify("DuplicateBranch.slang", new DuplicateBranchCheck()); } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/OctalValuesCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class OctalValuesCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("OctalValues.slang", new OctalValuesCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/TodoCommentCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class TodoCommentCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("TodoComment.slang", new TodoCommentCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/BadClassNameCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class BadClassNameCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("BadClassName.slang", new BadClassNameCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/FixMeCommentCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class FixMeCommentCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("FixMeComment.slang", new FixMeCommentCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/CodeAfterJumpCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class CodeAfterJumpCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("CodeAfterJump.slang", new CodeAfterJumpCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/SelfAssignmentCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class SelfAssignmentCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("SelfAssignment.slang", new SelfAssignmentCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/checks/api/InitContext.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks.api; 18 | 19 | import org.sonarsource.slang.api.Tree; 20 | import java.util.function.BiConsumer; 21 | 22 | public interface InitContext { 23 | 24 | void register(Class cls, BiConsumer visitor); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/AllBranchesIdenticalCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class AllBranchesIdenticalCheckTest { 22 | 23 | @Test 24 | void test() { Verifier.verify("AllBranchesIdentical.slang", new AllBranchesIdenticalCheck()); } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/BooleanInversionCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class BooleanInversionCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("BooleanInversion.slang", new BooleanInversionCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/CollapsibleIfStatementsCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class CollapsibleIfStatementsCheckTest { 22 | @Test 23 | void test() { Verifier.verify("CollapsibleIfStatements.slang", new CollapsibleIfStatementsCheck()); } 24 | } 25 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/MatchWithoutElseCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class MatchWithoutElseCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("MatchWithoutElse.slang", new MatchWithoutElseCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/OneStatementPerLineCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class OneStatementPerLineCheckTest { 22 | @Test 23 | void test() { 24 | Verifier.verify("OneStatementPerLine.slang", new OneStatementPerLineCheck()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /.github/workflows/RequestReview.yml: -------------------------------------------------------------------------------- 1 | name: Request review 2 | 3 | on: 4 | pull_request: 5 | types: ["review_requested"] 6 | 7 | jobs: 8 | RequestReview_job: 9 | name: Request review 10 | runs-on: sonar-runner 11 | permissions: 12 | id-token: write 13 | # For external PR, ticket should be moved manually 14 | if: | 15 | github.event.pull_request.head.repo.full_name == github.repository 16 | steps: 17 | - id: secrets 18 | uses: SonarSource/vault-action-wrapper@v3 19 | with: 20 | secrets: | 21 | development/github/token/{REPO_OWNER_NAME_DASH}-jira token | GITHUB_TOKEN; 22 | development/kv/data/jira user | JIRA_USER; 23 | development/kv/data/jira token | JIRA_TOKEN; 24 | - uses: sonarsource/gh-action-lt-backlog/RequestReview@v2 25 | with: 26 | github-token: ${{ fromJSON(steps.secrets.outputs.vault).GITHUB_TOKEN }} 27 | jira-user: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_USER }} 28 | jira-token: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_TOKEN }} 29 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/exception_handling.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::3", "text": "try", "type": "KEYWORD"}, 6 | {"textRange": "1:10::11", "text": "x"}, 7 | {"textRange": "1:20::25", "text": "catch", "type": "KEYWORD"}, 8 | {"textRange": "1:30::31", "text": "y"}, 9 | {"textRange": "1:40::47", "text": "finally", "type": "KEYWORD"}, 10 | {"textRange": "1:50::51", "text": "z"} 11 | ] 12 | }, 13 | "tree": { 14 | "@type": "ExceptionHandling", 15 | "metaData": "1:0::51", 16 | "tryBlock": {"@type": "Identifier", "metaData": "1:10::11", "name": "x"}, 17 | "tryKeyword": "1:0::3", 18 | "catchBlocks": [ 19 | {"@type": "Catch", 20 | "metaData": "1:20::31", 21 | "catchParameter": null, 22 | "catchBlock": {"@type": "Identifier", "metaData": "1:30::31", "name": "y"}, 23 | "keyword": "1:20::25" 24 | } 25 | ], 26 | "finallyBlock": {"@type": "Identifier", "metaData": "1:50::51", "name": "z"} 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/MatchTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import java.util.List; 20 | import javax.annotation.CheckForNull; 21 | 22 | public interface MatchTree extends Tree { 23 | 24 | @CheckForNull 25 | Tree expression(); 26 | 27 | List cases(); 28 | 29 | Token keyword(); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/IdenticalConditionsCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class IdenticalConditionsCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("IdenticalConditions.slang", new IdenticalConditionsCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/UnusedLocalVariableCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class UnusedLocalVariableCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("UnusedLocalVariable.slang", new UnusedLocalVariableCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/UnusedPrivateMethodCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class UnusedPrivateMethodCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("UnusedPrivateMethod.slang", new UnusedPrivateMethodCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/Annotation.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import java.util.List; 20 | 21 | public interface Annotation extends HasTextRange { 22 | 23 | /** 24 | * Short name of the annotation, without qualified name. 25 | */ 26 | String shortName(); 27 | 28 | List argumentsText(); 29 | 30 | } 31 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/HardcodedCredentialsCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class HardcodedCredentialsCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("HardcodedCredentials.slang", new HardcodedCredentialsCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/RedundantParenthesesCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class RedundantParenthesesCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("RedundantParentheses.slang", new RedundantParenthesesCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/UnaryExpressionTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface UnaryExpressionTree extends Tree { 20 | 21 | public enum Operator { 22 | NEGATE, 23 | PLUS, 24 | MINUS, 25 | INCREMENT, 26 | DECREMENT 27 | } 28 | 29 | Operator operator(); 30 | 31 | Tree operand(); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/WrongAssignmentOperatorCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class WrongAssignmentOperatorCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("WrongAssignmentOperator.slang", new WrongAssignmentOperatorCheck()); 26 | } 27 | 28 | } -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/IdenticalBinaryOperandCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class IdenticalBinaryOperandCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("IdenticalBinaryOperand.slang", new IdenticalBinaryOperandCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-testing/src/test/java/org/sonarsource/test/TestCheck.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.test; 18 | 19 | import org.sonarsource.slang.checks.api.InitContext; 20 | import org.sonarsource.slang.checks.api.SlangCheck; 21 | 22 | // Used in the test for PackageScanner 23 | class TestCheck implements SlangCheck { 24 | @Override 25 | public void initialize(InitContext init) { } 26 | } 27 | -------------------------------------------------------------------------------- /.github/workflows/SubmitReview.yml: -------------------------------------------------------------------------------- 1 | name: Submit Review 2 | 3 | on: 4 | pull_request_review: 5 | types: [submitted] 6 | 7 | jobs: 8 | SubmitReview_job: 9 | name: Submit Review 10 | runs-on: sonar-runner 11 | permissions: 12 | id-token: write 13 | pull-requests: read 14 | # For external PR, ticket should be moved manually 15 | if: | 16 | github.event.pull_request.head.repo.full_name == github.repository 17 | && (github.event.review.state == 'changes_requested' 18 | || github.event.review.state == 'approved') 19 | steps: 20 | - id: secrets 21 | uses: SonarSource/vault-action-wrapper@v3 22 | with: 23 | secrets: | 24 | development/kv/data/jira user | JIRA_USER; 25 | development/kv/data/jira token | JIRA_TOKEN; 26 | - uses: sonarsource/gh-action-lt-backlog/SubmitReview@v2 27 | with: 28 | github-token: ${{secrets.GITHUB_TOKEN}} 29 | jira-user: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_USER }} 30 | jira-token: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_TOKEN }} 31 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/TextRange.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface TextRange { 20 | 21 | TextPointer start(); 22 | 23 | TextPointer end(); 24 | 25 | default boolean isInside(TextRange other) { 26 | return this.start().compareTo(other.start()) >= 0 && this.end().compareTo(other.end()) <= 0; 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/TopLevelTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import java.util.List; 20 | import javax.annotation.CheckForNull; 21 | 22 | public interface TopLevelTree extends Tree { 23 | 24 | List declarations(); 25 | 26 | List allComments(); 27 | 28 | @CheckForNull 29 | Token firstCpdToken(); 30 | 31 | } 32 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/UnusedFunctionParameterCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class UnusedFunctionParameterCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("UnusedFunctionParameter.slang", new UnusedFunctionParameterCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/VariableAndParameterNameCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class VariableAndParameterNameCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("VariableAndParameterName.slang", new VariableAndParameterNameCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/JumpTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import javax.annotation.CheckForNull; 20 | 21 | public interface JumpTree extends Tree, HasKeyword { 22 | enum JumpKind { 23 | BREAK, 24 | CONTINUE 25 | } 26 | @CheckForNull 27 | IdentifierTree label(); 28 | 29 | Token keyword(); 30 | 31 | JumpKind kind(); 32 | } 33 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/VariableDeclarationTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import javax.annotation.CheckForNull; 20 | 21 | public interface VariableDeclarationTree extends Tree { 22 | 23 | IdentifierTree identifier(); 24 | 25 | @CheckForNull 26 | Tree type(); 27 | 28 | @CheckForNull 29 | Tree initializer(); 30 | 31 | boolean isVal(); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/IfConditionalAlwaysTrueOrFalseCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class IfConditionalAlwaysTrueOrFalseCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("IfConditionalAlwaysTrueOrFalse.slang", new IfConditionalAlwaysTrueOrFalseCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/MatchCaseTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import javax.annotation.CheckForNull; 20 | 21 | public interface MatchCaseTree extends Tree { 22 | 23 | // expression is null in case of default clause 24 | @CheckForNull 25 | Tree expression(); 26 | 27 | @CheckForNull 28 | Tree body(); 29 | 30 | TextRange rangeToHighlight(); 31 | 32 | } 33 | -------------------------------------------------------------------------------- /.github/workflows/PullRequestCreated.yml: -------------------------------------------------------------------------------- 1 | name: Pull Request Created 2 | 3 | on: 4 | pull_request: 5 | types: ["opened"] 6 | 7 | jobs: 8 | PullRequestCreated_job: 9 | name: Pull Request Created 10 | runs-on: sonar-runner 11 | permissions: 12 | id-token: write 13 | # For external PR, ticket should be created manually 14 | if: | 15 | github.event.pull_request.head.repo.full_name == github.repository 16 | steps: 17 | - id: secrets 18 | uses: SonarSource/vault-action-wrapper@v3 19 | with: 20 | secrets: | 21 | development/github/token/{REPO_OWNER_NAME_DASH}-jira token | GITHUB_TOKEN; 22 | development/kv/data/jira user | JIRA_USER; 23 | development/kv/data/jira token | JIRA_TOKEN; 24 | - uses: sonarsource/gh-action-lt-backlog/PullRequestCreated@v2 25 | with: 26 | github-token: ${{ fromJSON(steps.secrets.outputs.vault).GITHUB_TOKEN }} 27 | jira-user: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_USER }} 28 | jira-token: ${{ fromJSON(steps.secrets.outputs.vault).JIRA_TOKEN }} 29 | jira-project: SONARSLANG 30 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/TreeMetaData.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import java.util.List; 20 | import java.util.Set; 21 | 22 | public interface TreeMetaData { 23 | 24 | TextRange textRange(); 25 | 26 | List commentsInside(); 27 | 28 | List annotations(); 29 | 30 | List tokens(); 31 | 32 | Set linesOfCode(); 33 | 34 | } 35 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/DuplicatedFunctionImplementationCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class DuplicatedFunctionImplementationCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("DuplicatedFunctionImplementation.slang", new DuplicatedFunctionImplementationCheck()); 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/ExceptionHandlingTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import javax.annotation.CheckForNull; 20 | import java.util.List; 21 | 22 | public interface ExceptionHandlingTree extends Tree { 23 | 24 | Tree tryBlock(); 25 | 26 | List catchBlocks(); 27 | 28 | Token tryKeyword(); 29 | 30 | @CheckForNull 31 | Tree finallyBlock(); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/CommentedCodeCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | import org.sonarsource.slang.parser.SlangCodeVerifier; 21 | 22 | class CommentedCodeCheckTest { 23 | 24 | @Test 25 | void test() { 26 | Verifier.verify("CommentedCode.slang", new CommentedCodeCheck(new SlangCodeVerifier())); 27 | } 28 | 29 | } 30 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/LoopTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import javax.annotation.CheckForNull; 20 | 21 | public interface LoopTree extends Tree { 22 | 23 | public enum LoopKind { 24 | FOR, 25 | WHILE, 26 | DOWHILE 27 | } 28 | 29 | @CheckForNull 30 | Tree condition(); 31 | 32 | Tree body(); 33 | 34 | LoopKind kind(); 35 | 36 | Token keyword(); 37 | } 38 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/ParameterTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import java.util.List; 20 | import javax.annotation.CheckForNull; 21 | 22 | public interface ParameterTree extends Tree { 23 | 24 | @CheckForNull 25 | IdentifierTree identifier(); 26 | 27 | @CheckForNull 28 | Tree type(); 29 | 30 | @CheckForNull 31 | Tree defaultValue(); 32 | 33 | List modifiers(); 34 | 35 | } 36 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/AssignmentExpressionTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface AssignmentExpressionTree extends Tree { 20 | 21 | public enum Operator { 22 | EQUAL, 23 | PLUS_EQUAL, 24 | // for other compound assignments a native tree should be created 25 | } 26 | 27 | Operator operator(); 28 | 29 | Tree leftHandSide(); 30 | 31 | Tree statementOrExpression(); 32 | 33 | } 34 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/TabsCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class TabsCheckTest { 22 | 23 | @Test 24 | void test_without_tabs() { 25 | Verifier.verifyNoIssue("Tabs_compliant.slang", new TabsCheck()); 26 | } 27 | 28 | @Test 29 | void test_with_tabs() { 30 | Verifier.verify("Tabs_noncompliant.slang", new TabsCheck()); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /SECURITY.md: -------------------------------------------------------------------------------- 1 | # Reporting Security Issues 2 | 3 | A mature software vulnerability treatment process is a cornerstone of a robust information security management system. Contributions from the community play an important role in the evolution and security of our products, and in safeguarding the security and privacy of our users. 4 | 5 | If you believe you have discovered a security vulnerability in Sonar's products, we encourage you to report it immediately. 6 | 7 | To responsibly report a security issue, please email us at [security@sonarsource.com](mailto:security@sonarsource.com). Sonar’s security team will acknowledge your report, guide you through the next steps, or request additional information if necessary. Customers with a support contract can also report the vulnerability directly through the support channel. 8 | 9 | For security vulnerabilities found in third-party libraries, please also contact the library's owner or maintainer directly. 10 | 11 | ## Responsible Disclosure Policy 12 | 13 | For more information about disclosing a security vulnerability to Sonar, please refer to our community post: [Responsible Vulnerability Disclosure](https://community.sonarsource.com/t/responsible-vulnerability-disclosure/9317). 14 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/FunctionCognitiveComplexityCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class FunctionCognitiveComplexityCheckTest { 22 | 23 | @Test 24 | void test() { 25 | FunctionCognitiveComplexityCheck check = new FunctionCognitiveComplexityCheck(); 26 | check.threshold = 4; 27 | Verifier.verify("FunctionCognitiveComplexity.slang", check); 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /slang-checks/src/main/java/org/sonarsource/slang/checks/utils/PropertyDefaultValues.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks.utils; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Retention; 21 | import java.lang.annotation.RetentionPolicy; 22 | import java.lang.annotation.Target; 23 | 24 | @Retention(RetentionPolicy.RUNTIME) 25 | @Target({ElementType.FIELD}) 26 | public @interface PropertyDefaultValues { 27 | PropertyDefaultValue[] value(); 28 | } 29 | -------------------------------------------------------------------------------- /slang-checks/src/main/java/org/sonarsource/slang/checks/ParsingErrorCheck.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.sonar.check.Rule; 20 | import org.sonarsource.slang.checks.api.InitContext; 21 | import org.sonarsource.slang.checks.api.SlangCheck; 22 | 23 | @Rule(key = "ParsingError") 24 | public class ParsingErrorCheck implements SlangCheck { 25 | @Override 26 | public void initialize(InitContext init) { 27 | // errors are reported in InputFileContext#reportParseError 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/impl/BaseTreeImpl.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.impl; 18 | 19 | import org.sonarsource.slang.api.Tree; 20 | import org.sonarsource.slang.api.TreeMetaData; 21 | 22 | public abstract class BaseTreeImpl implements Tree { 23 | 24 | private final TreeMetaData metaData; 25 | 26 | protected BaseTreeImpl(TreeMetaData metaData) { 27 | this.metaData = metaData; 28 | } 29 | 30 | @Override 31 | public TreeMetaData metaData() { 32 | return metaData; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/CodeAfterJump.slang: -------------------------------------------------------------------------------- 1 | fun testReturn() { 2 | return 42; // Noncompliant {{Refactor this piece of code to not have any dead code after this "return".}} 3 | //^^^^^^^^^ 4 | 42; 5 | } 6 | 7 | fun lastReturn() { 8 | 42; 9 | return 42; 10 | } 11 | 12 | fun testBreak() { 13 | while (cond) { 14 | break; // Noncompliant {{Refactor this piece of code to not have any dead code after this "break".}} 15 | // ^^^^^ 16 | 42; 17 | 42; 18 | } 19 | } 20 | 21 | fun testContinue() { 22 | while (cond) { 23 | continue; // Noncompliant {{Refactor this piece of code to not have any dead code after this "continue".}} 24 | // ^^^^^^^^ 25 | 42; 26 | } 27 | } 28 | 29 | fun testContinueWithLabel() { 30 | while (cond) { 31 | continue myLabel; // Noncompliant {{Refactor this piece of code to not have any dead code after this "continue".}} 32 | // ^^^^^^^^^^^^^^^^ 33 | 42; 34 | } 35 | } 36 | 37 | fun empty() { 38 | } 39 | 40 | fun fnRequiresCfg() { 41 | if (cond) { 42 | return; 43 | } else { 44 | return; 45 | }; 46 | 47 | 42; 48 | } 49 | 50 | fun testThrow() { 51 | throw 42; // Noncompliant {{Refactor this piece of code to not have any dead code after this "throw".}} 52 | 42; 53 | } 54 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/TooLongFunctionCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class TooLongFunctionCheckTest { 22 | 23 | TooLongFunctionCheck check = new TooLongFunctionCheck(); 24 | 25 | @Test 26 | void max_3() { 27 | check.max = 3; 28 | Verifier.verify("TooLongFunction_3.slang", check); 29 | } 30 | 31 | @Test 32 | void max_4() { 33 | check.max = 4; 34 | Verifier.verify("TooLongFunction_4.slang", check); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/TooManyCasesCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class TooManyCasesCheckTest { 22 | 23 | private TooManyCasesCheck check = new TooManyCasesCheck(); 24 | 25 | @Test 26 | void test_3() { 27 | check.maximum = 3; 28 | Verifier.verify("TooManyCases_3.slang", check); 29 | } 30 | 31 | @Test 32 | void test_4() { 33 | check.maximum = 4; 34 | Verifier.verify("TooManyCases_4.slang", check); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/MatchCaseTooBigCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class MatchCaseTooBigCheckTest { 22 | 23 | private MatchCaseTooBigCheck check = new MatchCaseTooBigCheck(); 24 | 25 | @Test 26 | void max_5() { 27 | check.max = 5; 28 | Verifier.verify("MatchCaseTooBig_5.slang", check); 29 | } 30 | 31 | @Test 32 | void max_3() { 33 | check.max = 3; 34 | Verifier.verify("MatchCaseTooBig_3.slang", check); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/MatchWithoutElse.slang: -------------------------------------------------------------------------------- 1 | match (x) { }; // Noncompliant {{Add a default clause to this "match" statement.}} 2 | //^^^^^ 3 | match (x) { 1 -> 1; }; // Noncompliant {{Add a default clause to this "match" statement.}} 4 | match (x) { 1 -> 1; else -> 2; }; 5 | match (x) { else -> 2; 1 -> 1; }; 6 | 7 | int fun foo() { 8 | match (x) { 1 -> 1; }; // Noncompliant 9 | match (x) { 1 -> 1; else -> 2; }; 10 | 11 | int val value = match (x) { 1 -> 1; }; // Noncompliant 12 | value = if (y) { match (x) { 1 -> 1; }; } else 2; // Noncompliant 13 | 14 | while (y) { 15 | match (x) { else -> 2; }; 16 | match (x) { 1 -> 1; }; // Noncompliant 17 | }; 18 | 19 | native[] { [ 20 | match (x) { // Noncompliant 21 | 1 -> { match (y) { // Noncompliant 22 | 1 -> 1; 23 | 2 -> { 24 | var c; 25 | match (z) { // Noncompliant 26 | 1 -> { c = 2; }; 27 | }; 28 | }; 29 | 3 -> { 30 | var variable; 31 | match (c) { 32 | 1 -> variable = 1; 33 | else -> variable = 2; 34 | }; 35 | variable; 36 | }; 37 | }; 38 | }; 39 | } 40 | ] } 41 | } 42 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/NestedMatch.slang: -------------------------------------------------------------------------------- 1 | match (x) { 1 -> a; else -> b; }; // OK 2 | 3 | match (x) { 4 | 1 -> a; 5 | 2 -> match (y) { // Noncompliant {{Refactor the code to eliminate this nested "match".}} 6 | // ^^^^^ 7 | 3 -> c; 8 | else -> d; 9 | }; 10 | else -> b; 11 | }; 12 | 13 | match (x) { 14 | 1 -> a; 15 | 2 -> { 16 | match (y) { // Noncompliant {{Refactor the code to eliminate this nested "match".}} 17 | 3 -> c; 18 | else -> d; 19 | }; 20 | match (z) { // Noncompliant {{Refactor the code to eliminate this nested "match".}} 21 | 3 -> c; 22 | else -> d; 23 | }; 24 | }; 25 | else -> b; 26 | }; 27 | 28 | match (x) { 29 | 1 -> a; 30 | 2 -> match (y) { // Noncompliant {{Refactor the code to eliminate this nested "match".}} 31 | 3 -> c; 32 | else -> match (z) { // Noncompliant {{Refactor the code to eliminate this nested "match".}} 33 | 4 -> d; 34 | else -> e; 35 | }; 36 | }; 37 | else -> b; 38 | }; 39 | 40 | match (x) { 41 | 1 -> a; 42 | 2 -> b; 43 | else -> match (y) { // Noncompliant {{Refactor the code to eliminate this nested "match".}} 44 | 3 -> c; 45 | else -> d; 46 | }; 47 | }; -------------------------------------------------------------------------------- /slang-testing/src/test/java/org/sonarsource/slang/testing/PackageScannerTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.testing; 18 | 19 | import java.util.List; 20 | import org.junit.jupiter.api.Test; 21 | 22 | import static org.assertj.core.api.Assertions.assertThat; 23 | 24 | class PackageScannerTest { 25 | 26 | @Test 27 | void finds_classes_that_implement_slangcheck() { 28 | List result = PackageScanner.findSlangChecksInPackage("org.sonarsource.test"); 29 | assertThat(result).containsExactly("org.sonarsource.test.TestCheck"); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/BadFunctionNameCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class BadFunctionNameCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("BadFunctionName.slang", new BadFunctionNameCheck()); 26 | } 27 | 28 | @Test 29 | void test_upper_case() { 30 | BadFunctionNameCheck check = new BadFunctionNameCheck(); 31 | check.format = "^[A-Z]*$"; 32 | Verifier.verify("BadFunctionName.uppercase.slang", check); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/TooLongLineCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class TooLongLineCheckTest { 22 | 23 | private TooLongLineCheck check = new TooLongLineCheck(); 24 | 25 | @Test 26 | void max_120() { 27 | check.maximumLineLength = 120; 28 | Verifier.verify("TooLongLine_120.slang", check); 29 | } 30 | 31 | @Test 32 | void max_40() { 33 | check.maximumLineLength = 40; 34 | Verifier.verify("TooLongLine_40.slang", check); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/Tree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import java.util.List; 20 | import java.util.stream.Stream; 21 | 22 | public interface Tree extends HasTextRange { 23 | 24 | List children(); 25 | 26 | TreeMetaData metaData(); 27 | 28 | @Override 29 | default TextRange textRange() { 30 | return metaData().textRange(); 31 | } 32 | 33 | default Stream descendants() { 34 | return children().stream() 35 | .flatMap(tree -> Stream.concat(Stream.of(tree), tree.descendants())); 36 | } 37 | 38 | } 39 | -------------------------------------------------------------------------------- /slang-api/src/test/resources/org/sonarsource/slang/persistence/function_declaration.json: -------------------------------------------------------------------------------- 1 | { 2 | "treeMetaData": { 3 | "comments": [], 4 | "tokens": [ 5 | {"textRange": "1:0::6", "text": "public", "type": "KEYWORD"}, 6 | {"textRange": "1:7::10", "text": "int"}, 7 | {"textRange": "1:11::14", "text": "foo"}, 8 | {"textRange": "1:15::20", "text": "param"}, 9 | {"textRange": "1:20::21", "text": "{"}, 10 | {"textRange": "1:22::23", "text": "}"}, 11 | {"textRange": "1:24::26", "text": "->", "type": "KEYWORD"} 12 | ] 13 | }, 14 | "tree": { 15 | "@type": "FunctionDeclaration", 16 | "metaData": "1:0::26", 17 | "modifiers": [ 18 | {"@type": "Native", "metaData": "1:0::6", "nativeKind": "modifier", "children": []} 19 | ], 20 | "isConstructor": true, 21 | "returnType": {"@type": "Identifier", "metaData": "1:7::10", "name": "int"}, 22 | "name": {"@type": "Identifier", "metaData": "1:11::14", "name": "foo"}, 23 | "formalParameters": [ 24 | {"@type": "Identifier", "metaData": "1:15::20", "name": "param"} 25 | ], 26 | "body": {"@type": "Block", "metaData": "1:20::23", "statementOrExpressions": []}, 27 | "nativeChildren": [ 28 | {"@type": "Native", "metaData": "1:24::26", "nativeKind": "arrow", "children": []} 29 | ] 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/TooManyParametersCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class TooManyParametersCheckTest { 22 | 23 | @Test 24 | void default_threshold() { 25 | Verifier.verify("TooManyParameters.slang", new TooManyParametersCheck()); 26 | } 27 | 28 | @Test 29 | void threshold_3() { 30 | TooManyParametersCheck check = new TooManyParametersCheck(); 31 | check.max = 3; 32 | Verifier.verify("TooManyParameters.threshold.3.slang", check); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/TooComplexExpressionCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class TooComplexExpressionCheckTest { 22 | 23 | @Test 24 | void test_max_3() { 25 | Verifier.verify("TooComplexExpression_3.slang", new TooComplexExpressionCheck()); 26 | } 27 | 28 | @Test 29 | void test_max_2() { 30 | TooComplexExpressionCheck check = new TooComplexExpressionCheck(); 31 | check.max = 2; 32 | Verifier.verify("TooComplexExpression_2.slang", check); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /slang-checks/src/main/java/org/sonarsource/slang/checks/utils/PropertyDefaultValue.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks.utils; 18 | 19 | import java.lang.annotation.ElementType; 20 | import java.lang.annotation.Repeatable; 21 | import java.lang.annotation.Retention; 22 | import java.lang.annotation.RetentionPolicy; 23 | import java.lang.annotation.Target; 24 | 25 | @Retention(RetentionPolicy.RUNTIME) 26 | @Target({ElementType.FIELD}) 27 | @Repeatable(PropertyDefaultValues.class) 28 | public @interface PropertyDefaultValue { 29 | 30 | Language language(); 31 | 32 | String defaultValue(); 33 | } 34 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/TooManyLinesOfCodeFileCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class TooManyLinesOfCodeFileCheckTest { 22 | 23 | TooManyLinesOfCodeFileCheck check = new TooManyLinesOfCodeFileCheck(); 24 | 25 | @Test 26 | void max_4() { 27 | check.max = 4; 28 | Verifier.verify("TooManyLinesOfCodeFile.max_4.slang", check); 29 | } 30 | 31 | @Test 32 | void max_5() { 33 | check.max = 5; 34 | Verifier.verifyNoIssue("TooManyLinesOfCodeFile.max_5.slang", check); 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/IntegerLiteralTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import java.math.BigInteger; 20 | 21 | public interface IntegerLiteralTree extends LiteralTree { 22 | 23 | enum Base { 24 | BINARY(2), 25 | OCTAL(8), 26 | DECIMAL(10), 27 | HEXADECIMAL(16); 28 | 29 | private int radix; 30 | 31 | Base(int i) { 32 | radix = i; 33 | } 34 | 35 | public int getRadix() { 36 | return radix; 37 | } 38 | } 39 | 40 | Base getBase(); 41 | 42 | BigInteger getIntegerValue(); 43 | 44 | String getNumericPart(); 45 | 46 | } 47 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/TooDeeplyNestedStatementsCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class TooDeeplyNestedStatementsCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("TooDeeplyNestedStatements.slang", new TooDeeplyNestedStatementsCheck()); 26 | } 27 | 28 | @Test 29 | void test_max_2() { 30 | TooDeeplyNestedStatementsCheck check = new TooDeeplyNestedStatementsCheck(); 31 | check.max = 2; 32 | Verifier.verify("TooDeeplyNestedStatements.max_2.slang", check); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /slang-checks/src/test/resources/org/sonarsource/slang/checks/ElseIfWithoutElse.slang: -------------------------------------------------------------------------------- 1 | if (x == 0) { 2 | x = 42; 3 | }; 4 | 5 | if (x == 0) { 6 | x = 42; 7 | } else { 8 | x = 43; 9 | }; 10 | 11 | if (x == 0) { 12 | doSomething(); 13 | } else if (x == 1) { // Noncompliant {{Add the missing "else" clause.}} 14 | //^^^^^^^ 15 | doSomethingElse(); 16 | }; 17 | 18 | if (x == 0) { 19 | doSomething(); 20 | } else if (x == 1) { 21 | doSomethingElse(); 22 | } else { 23 | print("Something"); 24 | }; 25 | 26 | if (x == 0) { 27 | doSomething(); 28 | } else if (x == 1) { 29 | doSomethingElse(); 30 | } else if (x == 2) { // Noncompliant {{Add the missing "else" clause.}} 31 | print("Something"); 32 | }; 33 | 34 | if (x == 0) { 35 | break; 36 | } else if (x == 1) { 37 | return; 38 | } else if (x == 3) { 39 | throw(1); 40 | }; 41 | 42 | if (x == 0) { 43 | break; 44 | } else if (x == 1) { // Noncompliant {{Add the missing "else" clause.}} 45 | //^^^^^^^ 46 | doSomething(); 47 | }; 48 | 49 | if (x == 0) { 50 | } else if (x == 1) { // Noncompliant {{Add the missing "else" clause.}} 51 | return; 52 | }; 53 | 54 | if (x >= 0) 55 | if (x > 1) 56 | return 0 57 | else if (x == 1) 58 | doSomething() 59 | else if (x == 0) { // Noncompliant {{Add the missing "else" clause.}} 60 | doSomethingElse() 61 | }; 62 | 63 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/FunctionDeclarationTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | import java.util.List; 20 | import javax.annotation.CheckForNull; 21 | 22 | public interface FunctionDeclarationTree extends Tree { 23 | 24 | List modifiers(); 25 | 26 | boolean isConstructor(); 27 | 28 | @CheckForNull 29 | Tree returnType(); 30 | 31 | @CheckForNull 32 | IdentifierTree name(); 33 | 34 | List formalParameters(); 35 | 36 | @CheckForNull 37 | BlockTree body(); 38 | 39 | List nativeChildren(); 40 | 41 | TextRange rangeToHighlight(); 42 | 43 | } 44 | -------------------------------------------------------------------------------- /slang-checks/src/test/java/org/sonarsource/slang/checks/StringLiteralDuplicatedCheckTest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.checks; 18 | 19 | import org.junit.jupiter.api.Test; 20 | 21 | class StringLiteralDuplicatedCheckTest { 22 | 23 | @Test 24 | void test() { 25 | Verifier.verify("StringLiteralDuplicated.slang", new StringLiteralDuplicatedCheck()); 26 | } 27 | 28 | @Test 29 | void test_threshold_4() { 30 | StringLiteralDuplicatedCheck check = new StringLiteralDuplicatedCheck(); 31 | check.threshold = 4; 32 | Verifier.verify("StringLiteralDuplicated.threshold_4.slang", check); 33 | } 34 | 35 | } 36 | -------------------------------------------------------------------------------- /slang-api/src/main/java/org/sonarsource/slang/api/BinaryExpressionTree.java: -------------------------------------------------------------------------------- 1 | /* 2 | * SonarSource SLang 3 | * Copyright (C) 2018-2025 SonarSource SA 4 | * mailto:info AT sonarsource DOT com 5 | * 6 | * This program is free software; you can redistribute it and/or 7 | * modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA. 8 | * 9 | * This program is distributed in the hope that it will be useful, 10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12 | * See the Sonar Source-Available License for more details. 13 | * 14 | * You should have received a copy of the Sonar Source-Available License 15 | * along with this program; if not, see https://sonarsource.com/license/ssal/ 16 | */ 17 | package org.sonarsource.slang.api; 18 | 19 | public interface BinaryExpressionTree extends Tree { 20 | 21 | public enum Operator { 22 | PLUS, 23 | MINUS, 24 | TIMES, 25 | DIVIDED_BY, 26 | 27 | EQUAL_TO, 28 | NOT_EQUAL_TO, 29 | GREATER_THAN, 30 | GREATER_THAN_OR_EQUAL_TO, 31 | LESS_THAN, 32 | LESS_THAN_OR_EQUAL_TO, 33 | 34 | CONDITIONAL_AND, 35 | CONDITIONAL_OR, 36 | } 37 | 38 | Operator operator(); 39 | 40 | Token operatorToken(); 41 | 42 | Tree leftOperand(); 43 | 44 | Tree rightOperand(); 45 | 46 | } 47 | --------------------------------------------------------------------------------