From 4777e6723e787d0aff1b6d2f50bf2f0229253fe4 Mon Sep 17 00:00:00 2001 From: Ignat Beresnev Date: Thu, 15 Dec 2022 04:57:08 +0100 Subject: Update Qodana GitHub action (#2747) --- .github/workflows/qodana.yml | 20 +- qodana.sarif.json | 25786 ++++++++++++----------------------------- 2 files changed, 7304 insertions(+), 18502 deletions(-) diff --git a/.github/workflows/qodana.yml b/.github/workflows/qodana.yml index 2c1f87f4..b77719ea 100644 --- a/.github/workflows/qodana.yml +++ b/.github/workflows/qodana.yml @@ -6,22 +6,20 @@ on: push: branches: - master + jobs: inspection: runs-on: ubuntu-latest steps: - - name: Checkout - uses: actions/checkout@v3 - - name: Qodana - Code Inspection - id: qodana - uses: JetBrains/qodana-action@v2022.2.1 + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + - name: 'Qodana Scan' + uses: JetBrains/qodana-action@v2022.2.3 with: args: --baseline,qodana.sarif.json,--fail-threshold,0,--linter,jetbrains/qodana-jvm env: QODANA_TOKEN: ${{ secrets.QODANA_TOKEN }} - clone-finder: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Qodana - Clone Finder - uses: JetBrains/qodana-clone-finder-action@v2.0-eap + - uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: ${{ runner.temp }}/qodana/results/qodana.sarif.json diff --git a/qodana.sarif.json b/qodana.sarif.json index 0a919343..0abbf5c9 100644 --- a/qodana.sarif.json +++ b/qodana.sarif.json @@ -7,7 +7,7 @@ "driver": { "name": "QDJVM", "fullName": "Qodana for JVM", - "version": "213.7162.133", + "version": "222.4502.199", "rules": [], "taxa": [ { @@ -211,13 +211,13 @@ ] }, { - "id": "Java/Probable bugs", - "name": "Probable bugs", + "id": "Kotlin/Migration", + "name": "Migration", "relationships": [ { "target": { - "id": "Java", - "index": 5, + "id": "Kotlin", + "index": 2, "toolComponent": { "name": "QDJVM" } @@ -229,13 +229,13 @@ ] }, { - "id": "Spring/Spring Cloud", - "name": "Spring Cloud", + "id": "Java/Probable bugs", + "name": "Probable bugs", "relationships": [ { "target": { - "id": "Spring", - "index": 7, + "id": "Java", + "index": 5, "toolComponent": { "name": "QDJVM" } @@ -247,8 +247,8 @@ ] }, { - "id": "Java/Serialization issues", - "name": "Serialization issues", + "id": "Java/Class structure", + "name": "Class structure", "relationships": [ { "target": { @@ -265,8 +265,8 @@ ] }, { - "id": "Java/Class structure", - "name": "Class structure", + "id": "Java/Serialization issues", + "name": "Serialization issues", "relationships": [ { "target": { @@ -367,8 +367,8 @@ ] }, { - "id": "Java/Control flow issues", - "name": "Control flow issues", + "id": "Java/Numeric issues", + "name": "Numeric issues", "relationships": [ { "target": { @@ -385,8 +385,8 @@ ] }, { - "id": "Java/Numeric issues", - "name": "Numeric issues", + "id": "Java/Control flow issues", + "name": "Control flow issues", "relationships": [ { "target": { @@ -522,6 +522,24 @@ } ] }, + { + "id": "Java/Verbose or redundant code constructs", + "name": "Verbose or redundant code constructs", + "relationships": [ + { + "target": { + "id": "Java", + "index": 5, + "toolComponent": { + "name": "QDJVM" + } + }, + "kinds": [ + "superset" + ] + } + ] + }, { "id": "General", "name": "General" @@ -647,7 +665,7 @@ { "target": { "id": "CSS", - "index": 48, + "index": 49, "toolComponent": { "name": "QDJVM" } @@ -773,7 +791,7 @@ { "target": { "id": "Java/Naming conventions", - "index": 55, + "index": 56, "toolComponent": { "name": "QDJVM" } @@ -817,7 +835,7 @@ { "target": { "id": "Plugin DevKit", - "index": 59, + "index": 60, "toolComponent": { "name": "QDJVM" } @@ -936,50 +954,10 @@ } ] }, - { - "id": "Plugin DevKit/Code", - "name": "Code", - "relationships": [ - { - "target": { - "id": "Plugin DevKit", - "index": 59, - "toolComponent": { - "name": "QDJVM" - } - }, - "kinds": [ - "superset" - ] - } - ] - }, - { - "id": "Java/Verbose or redundant code constructs", - "name": "Verbose or redundant code constructs", - "relationships": [ - { - "target": { - "id": "Java", - "index": 5, - "toolComponent": { - "name": "QDJVM" - } - }, - "kinds": [ - "superset" - ] - } - ] - }, { "id": "XSLT", "name": "XSLT" }, - { - "id": "JUnit", - "name": "JUnit" - }, { "id": "Groovy/Style", "name": "Style", @@ -1038,6 +1016,24 @@ } ] }, + { + "id": "Plugin DevKit/Code", + "name": "Code", + "relationships": [ + { + "target": { + "id": "Plugin DevKit", + "index": 60, + "toolComponent": { + "name": "QDJVM" + } + }, + "kinds": [ + "superset" + ] + } + ] + }, { "id": "JSP", "name": "JSP" @@ -1085,7 +1081,7 @@ { "target": { "id": "CSS", - "index": 48, + "index": 49, "toolComponent": { "name": "QDJVM" } @@ -1121,7 +1117,7 @@ { "target": { "id": "Java/Lombok", - "index": 79, + "index": 78, "toolComponent": { "name": "QDJVM" } @@ -1147,7 +1143,7 @@ { "target": { "id": "Java/Naming conventions", - "index": 55, + "index": 56, "toolComponent": { "name": "QDJVM" } @@ -1455,7 +1451,7 @@ { "target": { "id": "Java/Numeric issues", - "index": 27, + "index": 26, "toolComponent": { "name": "QDJVM" } @@ -1473,7 +1469,7 @@ { "target": { "id": "Plugin DevKit", - "index": 59, + "index": 60, "toolComponent": { "name": "QDJVM" } @@ -1616,24 +1612,6 @@ "id": "Oracle", "name": "Oracle" }, - { - "id": "Kotlin/Migration", - "name": "Migration", - "relationships": [ - { - "target": { - "id": "Kotlin", - "index": 2, - "toolComponent": { - "name": "QDJVM" - } - }, - "kinds": [ - "superset" - ] - } - ] - }, { "id": "Kotlin/Migration/Maven", "name": "Maven", @@ -1641,7 +1619,7 @@ { "target": { "id": "Kotlin/Migration", - "index": 118, + "index": 15, "toolComponent": { "name": "QDJVM" } @@ -1743,7 +1721,7 @@ { "target": { "id": "Kotlin/Migration", - "index": 118, + "index": 15, "toolComponent": { "name": "QDJVM" } @@ -1841,7 +1819,7 @@ { "target": { "id": "Java/Probable bugs", - "index": 15, + "index": 16, "toolComponent": { "name": "QDJVM" } @@ -1856,10 +1834,6 @@ "id": "RELAX NG", "name": "RELAX NG" }, - { - "id": "Application servers", - "name": "Application servers" - }, { "id": "CSS/Code quality tools", "name": "Code quality tools", @@ -1867,7 +1841,7 @@ { "target": { "id": "CSS", - "index": 48, + "index": 49, "toolComponent": { "name": "QDJVM" } @@ -1907,7 +1881,7 @@ { "target": { "id": "Gradle", - "index": 139, + "index": 136, "toolComponent": { "name": "QDJVM" } @@ -1919,8 +1893,8 @@ ] }, { - "id": "Spring/Spring Cloud Stream", - "name": "Spring Cloud Stream", + "id": "Spring/Spring Boot", + "name": "Spring Boot", "relationships": [ { "target": { @@ -1937,8 +1911,8 @@ ] }, { - "id": "Spring/Spring Boot", - "name": "Spring Boot", + "id": "Spring/Spring Shell", + "name": "Spring Shell", "relationships": [ { "target": { @@ -1972,6 +1946,24 @@ } ] }, + { + "id": "JVM languages/Test frameworks", + "name": "Test frameworks", + "relationships": [ + { + "target": { + "id": "JVM languages", + "index": 1, + "toolComponent": { + "name": "QDJVM" + } + }, + "kinds": [ + "superset" + ] + } + ] + }, { "id": "PostgreSQL", "name": "PostgreSQL" @@ -2017,22 +2009,8 @@ ] }, { - "id": "Kotlin/Other problems", - "name": "Other problems", - "relationships": [ - { - "target": { - "id": "Kotlin", - "index": 2, - "toolComponent": { - "name": "QDJVM" - } - }, - "kinds": [ - "superset" - ] - } - ] + "id": "Dependency analysis", + "name": "Dependency analysis" }, { "id": "EL", @@ -2049,7 +2027,7 @@ { "target": { "id": "Java/Lombok", - "index": 79, + "index": 78, "toolComponent": { "name": "QDJVM" } @@ -2085,7 +2063,7 @@ { "target": { "id": "CSS", - "index": 48, + "index": 49, "toolComponent": { "name": "QDJVM" } @@ -2097,13 +2075,31 @@ ] }, { - "id": "Spring/Spring Batch", - "name": "Spring Batch", + "id": "Kotlin/Other problems", + "name": "Other problems", "relationships": [ { "target": { - "id": "Spring", - "index": 7, + "id": "Kotlin", + "index": 2, + "toolComponent": { + "name": "QDJVM" + } + }, + "kinds": [ + "superset" + ] + } + ] + }, + { + "id": "Plugin DevKit/Workspace model", + "name": "Workspace model", + "relationships": [ + { + "target": { + "id": "Plugin DevKit", + "index": 60, "toolComponent": { "name": "QDJVM" } @@ -2233,7 +2229,7 @@ "extensions": [ { "name": "org.intellij.intelliLang", - "version": "213.7162", + "version": "222.4502", "rules": [ { "id": "InjectionNotApplicable", @@ -2292,7 +2288,7 @@ { "target": { "id": "Pattern validation", - "index": 107, + "index": 106, "toolComponent": { "name": "QDJVM" } @@ -2326,7 +2322,7 @@ { "target": { "id": "General", - "index": 37, + "index": 38, "toolComponent": { "name": "QDJVM" } @@ -2360,7 +2356,7 @@ { "target": { "id": "Pattern validation", - "index": 107, + "index": 106, "toolComponent": { "name": "QDJVM" } @@ -2428,7 +2424,7 @@ { "target": { "id": "Pattern validation", - "index": 107, + "index": 106, "toolComponent": { "name": "QDJVM" } @@ -2483,7 +2479,7 @@ }, { "name": "com.intellij.java", - "version": "213.7162", + "version": "222.4502", "rules": [ { "id": "OverrideOnly", @@ -2522,7 +2518,7 @@ { "id": "CallToSuspiciousStringMethod", "shortDescription": { - "text": "Call to suspicious String method" + "text": "Call to suspicious 'String' method" }, "fullDescription": { "text": "Reports calls of: 'equals()' 'equalsIgnoreCase()' 'compareTo()' 'compareToIgnoreCase()' and 'trim()' on 'String' objects. Comparison of internationalized strings should probably use a 'java.text.Collator' instead. 'String.trim()' only removes control characters between 0x00 and 0x20. The 'String.strip()' method introduced in Java 11 is more Unicode aware and can be used as a replacement.", @@ -2624,7 +2620,7 @@ { "id": "UnusedReturnValue", "shortDescription": { - "text": "Method can be void" + "text": "Method can be made 'void'" }, "fullDescription": { "text": "Reports methods whose return values are never used when called. The return type of such methods can be made 'void'. Methods annotated with Error Prone's or AssertJ's '@CanIgnoreReturnValue' annotation will not be reported. The quick-fix updates the method signature and removes 'return' statements from inside the method. Example: '// reported if visibility setting is Protected or Public\n protected String myToUpperCase(String s) {\n return s.toUpperCase();\n }\n\n // simple setter, reporting depends on setting\n public String setStr(String str) {\n myStr = str;\n return myStr;\n }\n\n void test() {\n setStr(\"value\"); // return value is unused\n myToUpperCase(\"result\"); // return value is unused\n }' After the quick-fix is applied to both methods: 'protected void myToUpperCase(String s) {\n // 'return' removed completely\n // as 's.toUpperCase()' has no side effect\n }\n\n public void setStr(String str) {\n myStr = str;\n // 'return' removed\n }\n ...' NOTE: Some methods might not be reported during in-editor highlighting due to performance reasons. To see all results, run the inspection using Code | Inspect Code or Code | Analyze Code | Run Inspection by Name> Use the Ignore simple setters option to ignore unused return values from simple setter calls. Use the Maximal reported method visibility option to control the maximum visibility of methods to be reported.", @@ -2658,7 +2654,7 @@ { "id": "UncheckedExceptionClass", "shortDescription": { - "text": "Unchecked exception class" + "text": "Unchecked 'Exception' class" }, "fullDescription": { "text": "Reports subclasses of 'java.lang.RuntimeException'. Some coding standards require that all user-defined exception classes are checked. Example: 'class EnigmaException extends RuntimeException {} // warning: Unchecked exception class 'EnigmaException''", @@ -2746,7 +2742,7 @@ { "target": { "id": "Java/Probable bugs", - "index": 15, + "index": 16, "toolComponent": { "name": "QDJVM" } @@ -2758,13 +2754,13 @@ ] }, { - "id": "ComparatorNotSerializable", + "id": "ClassWithOnlyPrivateConstructors", "shortDescription": { - "text": "Comparator class not declared Serializable" + "text": "Class with only 'private' constructors should be declared 'final'" }, "fullDescription": { - "text": "Reports classes that implement 'java.lang.Comparator', but do not implement 'java.io.Serializable'. If a non-serializable comparator is used to construct an ordered collection such as a 'java.util.TreeMap' or 'java.util.TreeSet', then the collection will also be non-serializable. This can result in unexpected and difficult-to-diagnose bugs. Since subclasses of 'java.lang.Comparator' are often stateless, simply marking them serializable is a small cost to avoid such issues. Example: 'class Foo implements Comparator { // warning\n @Override\n public int compare(Object o1, Object o2) {\n /* ... */\n }\n }' After the quick-fix is applied: 'class Foo implements Comparator, Serializable { // no warning here\n @Override\n public int compare(Object o1, Object o2) {\n /* ... */\n }\n }'", - "markdown": "Reports classes that implement `java.lang.Comparator`, but do not implement `java.io.Serializable`.\n\n\nIf a non-serializable comparator is used to construct an ordered collection such\nas a `java.util.TreeMap` or `java.util.TreeSet`, then the\ncollection will also be non-serializable. This can result in unexpected and\ndifficult-to-diagnose bugs.\n\n\nSince subclasses of `java.lang.Comparator` are often stateless,\nsimply marking them serializable is a small cost to avoid such issues.\n\n**Example:**\n\n\n class Foo implements Comparator { // warning\n @Override\n public int compare(Object o1, Object o2) {\n /* ... */\n }\n }\n\nAfter the quick-fix is applied:\n\n\n class Foo implements Comparator, Serializable { // no warning here\n @Override\n public int compare(Object o1, Object o2) {\n /* ... */\n }\n }\n" + "text": "Reports classes with only 'private' constructors. A class that only has 'private' constructors cannot be extended outside a file and should be declared as 'final'.", + "markdown": "Reports classes with only `private` constructors.\n\nA class that only has `private` constructors cannot be extended outside a file and should be declared as `final`." }, "defaultConfiguration": { "enabled": false, @@ -2779,7 +2775,7 @@ "relationships": [ { "target": { - "id": "Java/Serialization issues", + "id": "Java/Class structure", "index": 17, "toolComponent": { "name": "QDJVM" @@ -2792,13 +2788,13 @@ ] }, { - "id": "ClassWithOnlyPrivateConstructors", + "id": "ComparatorNotSerializable", "shortDescription": { - "text": "Class with only 'private' constructors should be declared 'final'" + "text": "'Comparator' class not declared 'Serializable'" }, "fullDescription": { - "text": "Reports classes with only 'private' constructors. A class that only has 'private' constructors cannot be extended outside a file and should be declared as 'final'.", - "markdown": "Reports classes with only `private` constructors.\n\nA class that only has `private` constructors cannot be extended outside a file and should be declared as `final`." + "text": "Reports classes that implement 'java.lang.Comparator', but do not implement 'java.io.Serializable'. If a non-serializable comparator is used to construct an ordered collection such as a 'java.util.TreeMap' or 'java.util.TreeSet', then the collection will also be non-serializable. This can result in unexpected and difficult-to-diagnose bugs. Since subclasses of 'java.lang.Comparator' are often stateless, simply marking them serializable is a small cost to avoid such issues. Example: 'class Foo implements Comparator { // warning\n @Override\n public int compare(Object o1, Object o2) {\n /* ... */\n }\n }' After the quick-fix is applied: 'class Foo implements Comparator, Serializable { // no warning here\n @Override\n public int compare(Object o1, Object o2) {\n /* ... */\n }\n }'", + "markdown": "Reports classes that implement `java.lang.Comparator`, but do not implement `java.io.Serializable`.\n\n\nIf a non-serializable comparator is used to construct an ordered collection such\nas a `java.util.TreeMap` or `java.util.TreeSet`, then the\ncollection will also be non-serializable. This can result in unexpected and\ndifficult-to-diagnose bugs.\n\n\nSince subclasses of `java.lang.Comparator` are often stateless,\nsimply marking them serializable is a small cost to avoid such issues.\n\n**Example:**\n\n\n class Foo implements Comparator { // warning\n @Override\n public int compare(Object o1, Object o2) {\n /* ... */\n }\n }\n\nAfter the quick-fix is applied:\n\n\n class Foo implements Comparator, Serializable { // no warning here\n @Override\n public int compare(Object o1, Object o2) {\n /* ... */\n }\n }\n" }, "defaultConfiguration": { "enabled": false, @@ -2813,7 +2809,7 @@ "relationships": [ { "target": { - "id": "Java/Class structure", + "id": "Java/Serialization issues", "index": 18, "toolComponent": { "name": "QDJVM" @@ -2862,7 +2858,7 @@ { "id": "FieldAccessedSynchronizedAndUnsynchronized", "shortDescription": { - "text": "Field accessed in both synchronized and unsynchronized contexts" + "text": "Field accessed in both 'synchronized' and unsynchronized contexts" }, "fullDescription": { "text": "Reports non-final fields that are accessed in both 'synchronized' and non-'synchronized' contexts. 'volatile' fields as well as accesses in constructors and initializers are ignored by this inspection. Such \"partially synchronized\" access is often the result of a coding oversight and may lead to unexpectedly inconsistent data structures. Example: 'public class Program {\n Console console; // warning: Field 'console' is accessed in both synchronized and unsynchronized contexts\n\n public synchronized void execute() {\n console.print(\"running\");\n }\n\n public void check() {\n console.check();\n }\n }'\n Use the option to specify if simple getters and setters are counted as accesses too.", @@ -2894,19 +2890,19 @@ ] }, { - "id": "NegatedEqualityExpression", + "id": "RemoveLiteralUnderscores", "shortDescription": { - "text": "Negated equality expression" + "text": "Underscores in numeric literal" }, "fullDescription": { - "text": "Reports equality expressions which are negated by a prefix expression. Such expressions can be simplified using the '!=' operator. Example: '!(i == 1)' After the quick-fix is applied: 'i != 1'", - "markdown": "Reports equality expressions which are negated by a prefix expression.\n\nSuch expressions can be simplified using the `!=` operator.\n\nExample:\n\n\n !(i == 1)\n\nAfter the quick-fix is applied:\n\n\n i != 1\n" + "text": "Reports numeric literals with underscores and suggests removing them with a quick-fix. This may be useful if you need to lower the language level. The quick-fix removes underscores from numeric literals. For example '1_000_000' will be converted to '1000000'. Numeric literals with underscores appeared in Java 7. This inspection can help to downgrade for backward compatibility with earlier Java versions. New in 2020.2", + "markdown": "Reports numeric literals with underscores and suggests removing them with a quick-fix. This may be useful if you need to lower the language level.\n\nThe quick-fix removes underscores from numeric literals. For example `1_000_000` will be converted to `1000000`.\n\n\n*Numeric literals with underscores* appeared in Java 7.\nThis inspection can help to downgrade for backward compatibility with earlier Java versions.\n\nNew in 2020.2" }, "defaultConfiguration": { "enabled": false, - "level": "warning", + "level": "note", "parameters": { - "ideaSeverity": "WARNING", + "ideaSeverity": "INFORMATION", "tags": [ "ideaSeverity" ] @@ -2915,7 +2911,7 @@ "relationships": [ { "target": { - "id": "Java/Control flow issues", + "id": "Java/Numeric issues", "index": 26, "toolComponent": { "name": "QDJVM" @@ -2928,19 +2924,19 @@ ] }, { - "id": "RemoveLiteralUnderscores", + "id": "NegatedEqualityExpression", "shortDescription": { - "text": "Underscores in numeric literal" + "text": "Negated equality expression" }, "fullDescription": { - "text": "Reports numeric literals with underscores and suggests removing them with a quick-fix. This may be useful if you need to lower the language level. The quick-fix removes underscores from numeric literals. For example '1_000_000' will be converted to '1000000'. This inspection only reports if the language level of the project or module is 7 or higher. New in 2020.2", - "markdown": "Reports numeric literals with underscores and suggests removing them with a quick-fix. This may be useful if you need to lower the language level.\n\nThe quick-fix removes underscores from numeric literals. For example `1_000_000` will be converted to `1000000`.\n\nThis inspection only reports if the language level of the project or module is 7 or higher.\n\nNew in 2020.2" + "text": "Reports equality expressions which are negated by a prefix expression. Such expressions can be simplified using the '!=' operator. Example: '!(i == 1)' After the quick-fix is applied: 'i != 1'", + "markdown": "Reports equality expressions which are negated by a prefix expression.\n\nSuch expressions can be simplified using the `!=` operator.\n\nExample:\n\n\n !(i == 1)\n\nAfter the quick-fix is applied:\n\n\n i != 1\n" }, "defaultConfiguration": { "enabled": false, - "level": "note", + "level": "warning", "parameters": { - "ideaSeverity": "INFORMATION", + "ideaSeverity": "WARNING", "tags": [ "ideaSeverity" ] @@ -2949,7 +2945,7 @@ "relationships": [ { "target": { - "id": "Java/Numeric issues", + "id": "Java/Control flow issues", "index": 27, "toolComponent": { "name": "QDJVM" @@ -2984,7 +2980,7 @@ { "target": { "id": "Java/Probable bugs", - "index": 15, + "index": 16, "toolComponent": { "name": "QDJVM" } @@ -3132,19 +3128,19 @@ ] }, { - "id": "AssertionCanBeIf", + "id": "DoubleNegation", "shortDescription": { - "text": "Assertion can be replaced with 'if' statement" + "text": "Double negation" }, "fullDescription": { - "text": "Reports 'assert' statements and suggests replacing them with 'if' statements that throw 'java.lang.AssertionError'. Example: 'assert param != null;' After the quick-fix is applied: 'if (param == null) throw new AssertionError();'", - "markdown": "Reports `assert` statements and suggests replacing them with `if` statements that throw `java.lang.AssertionError`.\n\nExample:\n\n\n assert param != null;\n\nAfter the quick-fix is applied:\n\n\n if (param == null) throw new AssertionError();\n" + "text": "Reports double negations that can be simplified. Example: 'if (!!functionCall()) {}' After the quick-fix is applied: 'if (functionCall()) {}' Example: 'if (!(a != b)) {}' After the quick-fix is applied: 'if (a == b) {}'", + "markdown": "Reports double negations that can be simplified.\n\nExample:\n\n\n if (!!functionCall()) {}\n\nAfter the quick-fix is applied:\n\n\n if (functionCall()) {}\n\nExample:\n\n\n if (!(a != b)) {}\n\nAfter the quick-fix is applied:\n\n\n if (a == b) {}\n" }, "defaultConfiguration": { - "enabled": false, - "level": "note", + "enabled": true, + "level": "warning", "parameters": { - "ideaSeverity": "INFORMATION", + "ideaSeverity": "WARNING", "tags": [ "ideaSeverity" ] @@ -3154,7 +3150,7 @@ { "target": { "id": "Java/Control flow issues", - "index": 26, + "index": 27, "toolComponent": { "name": "QDJVM" } @@ -3166,19 +3162,19 @@ ] }, { - "id": "DoubleNegation", + "id": "AssertionCanBeIf", "shortDescription": { - "text": "Double negation" + "text": "Assertion can be replaced with 'if' statement" }, "fullDescription": { - "text": "Reports double negations that can be simplified. Example: 'if (!!functionCall()) {}' After the quick-fix is applied: 'if (functionCall()) {}' Example: 'if (!(a != b)) {}' After the quick-fix is applied: 'if (a == b) {}'", - "markdown": "Reports double negations that can be simplified.\n\nExample:\n\n\n if (!!functionCall()) {}\n\nAfter the quick-fix is applied:\n\n\n if (functionCall()) {}\n\nExample:\n\n\n if (!(a != b)) {}\n\nAfter the quick-fix is applied:\n\n\n if (a == b) {}\n" + "text": "Reports 'assert' statements and suggests replacing them with 'if' statements that throw 'java.lang.AssertionError'. Example: 'assert param != null;' After the quick-fix is applied: 'if (param == null) throw new AssertionError();'", + "markdown": "Reports `assert` statements and suggests replacing them with `if` statements that throw `java.lang.AssertionError`.\n\nExample:\n\n\n assert param != null;\n\nAfter the quick-fix is applied:\n\n\n if (param == null) throw new AssertionError();\n" }, "defaultConfiguration": { - "enabled": true, - "level": "warning", + "enabled": false, + "level": "note", "parameters": { - "ideaSeverity": "WARNING", + "ideaSeverity": "INFORMATION", "tags": [ "ideaSeverity" ] @@ -3188,7 +3184,7 @@ { "target": { "id": "Java/Control flow issues", - "index": 26, + "index": 27, "toolComponent": { "name": "QDJVM" } @@ -3233,6 +3229,40 @@ } ] }, + { + "id": "ReplaceOnLiteralHasNoEffect", + "shortDescription": { + "text": "Replacement operation has no effect" + }, + "fullDescription": { + "text": "Reports calls to the 'String' methods 'replace()', 'replaceAll()' or 'replaceFirst()' that have no effect. Such calls can be guaranteed to have no effect when the qualifier and search string are compile-time constants and the search string is not found in the qualifier. This is redundant and may indicate an error. Example: '// replacement does nothing\n \"hello\".replace(\"$value$\", value);' New in 2022.1", + "markdown": "Reports calls to the `String` methods `replace()`, `replaceAll()` or `replaceFirst()` that have no effect. Such calls can be guaranteed to have no effect when the qualifier and search string are compile-time constants and the search string is not found in the qualifier. This is redundant and may indicate an error.\n\n**Example:**\n\n\n // replacement does nothing\n \"hello\".replace(\"$value$\", value);\n\nNew in 2022.1" + }, + "defaultConfiguration": { + "enabled": true, + "level": "warning", + "parameters": { + "ideaSeverity": "WARNING", + "tags": [ + "ideaSeverity" + ] + } + }, + "relationships": [ + { + "target": { + "id": "Java/Verbose or redundant code constructs", + "index": 37, + "toolComponent": { + "name": "QDJVM" + } + }, + "kinds": [ + "superset" + ] + } + ] + }, { "id": "SingleClassImport", "shortDescription": { @@ -3290,7 +3320,7 @@ { "target": { "id": "Java/Numeric issues", - "index": 27, + "index": 26, "toolComponent": { "name": "QDJVM" } @@ -3304,7 +3334,7 @@ { "id": "SystemOutErr", "shortDescription": { - "text": "Use of System.out or System.err" + "text": "Use of 'System.out' or 'System.err'" }, "fullDescription": { "text": "Reports usages of 'System.out' or 'System.err'. Such statements are often used for temporary debugging and should be either removed from the production code, or replaced by a more robust logging facility.", @@ -3324,7 +3354,7 @@ { "target": { "id": "Java/Code maturity", - "index": 40, + "index": 41, "toolComponent": { "name": "QDJVM" } @@ -3392,7 +3422,7 @@ { "target": { "id": "Java/Serialization issues", - "index": 17, + "index": 18, "toolComponent": { "name": "QDJVM" } @@ -3426,7 +3456,7 @@ { "target": { "id": "Java/Numeric issues", - "index": 27, + "index": 26, "toolComponent": { "name": "QDJVM" } @@ -3460,7 +3490,7 @@ { "target": { "id": "Java/Control flow issues", - "index": 26, + "index": 27, "toolComponent": { "name": "QDJVM" } @@ -3528,7 +3558,7 @@ { "target": { "id": "Java/Data flow", - "index": 43, + "index": 44, "toolComponent": { "name": "QDJVM" } @@ -3562,7 +3592,7 @@ { "target": { "id": "Java/Probable bugs", - "index": 15, + "index": 16, "toolComponent": { "name": "QDJVM" } @@ -3596,7 +3626,7 @@ { "target": { "id": "Java/Probable bugs", - "index": 15, + "index": 16, "toolComponent": { "name": "QDJVM" } @@ -3630,7 +3660,7 @@ { "target": { "id": "Java/Probable bugs", - "index": 15, + "index": 16, "toolComponent": { "name": "QDJVM" } @@ -3698,7 +3728,7 @@ { "target": { "id": "Java/Code maturity", - "index": 40, + "index": 41, "toolComponent": { "name": "QDJVM" } @@ -3712,7 +3742,7 @@ { "id": "TestCaseInProductCode", "shortDescription": { - "text": "JUnit TestCase in product source" + "text": "JUnit 'TestCase' in product source" }, "fullDescription": { "text": "Reports JUnit 3 test classes in product source trees. This most likely indicates a programmer's error and can result in test code being shipped into production.", @@ -3732,7 +3762,7 @@ { "target": { "id": "Java/JUnit", - "index": 46, + "index": 47, "toolComponent": { "name": "QDJVM" } @@ -3766,7 +3796,7 @@ { "target": { "id": "Java/Probable bugs", - "index": 15, + "index": 16, "toolComponent": { "name": "QDJVM" } @@ -3783,8 +3813,8 @@ "text": "'finalize()' should be protected, not public" }, "fullDescription": { - "text": "Reports any implementations of the 'Object.finalize()' method that are declared 'public'. According to the contract of the 'Object.finalize()', only the garbage collector calls this method. Making this method public may be confusing, because it means that the method can be used by users. The quick-fix makes the method protected to prevent it from being explicitly invoked by other classes. Example: 'class X {\n public void finalize() {\n /* ... */\n }\n }' After the quick-fix is applied: 'class X {\n protected void finalize() {\n /* ... */\n }\n }'", - "markdown": "Reports any implementations of the `Object.finalize()` method that are declared `public`.\n\n\nAccording to the contract of the `Object.finalize()`, only the garbage\ncollector calls this method. Making this method public may be confusing, because it\nmeans that the method can be used by users.\n\n\nThe quick-fix makes the method protected to prevent it from being explicitly invoked\nby other classes.\n\n**Example:**\n\n\n class X {\n public void finalize() {\n /* ... */\n }\n }\n\nAfter the quick-fix is applied:\n\n\n class X {\n protected void finalize() {\n /* ... */\n }\n }\n" + "text": "Reports any implementations of the 'Object.finalize()' method that are declared 'public'. According to the contract of the 'Object.finalize()', only the garbage collector calls this method. Making this method public may be confusing, because it means that the method can be used from other code. A quick-fix is provided to make the method 'protected', to prevent it from being invoked from other classes. Example: 'class X {\n public void finalize() {\n /* ... */\n }\n }' After the quick-fix is applied: 'class X {\n protected void finalize() {\n /* ... */\n }\n }'", + "markdown": "Reports any implementations of the `Object.finalize()` method that are declared `public`.\n\n\nAccording to the contract of the `Object.finalize()`, only the garbage\ncollector calls this method. Making this method public may be confusing, because it\nmeans that the method can be used from other code.\n\n\nA quick-fix is provided to make the method `protected`, to prevent it from being invoked\nfrom other classes.\n\n**Example:**\n\n\n class X {\n public void finalize() {\n /* ... */\n }\n }\n\nAfter the quick-fix is applied:\n\n\n class X {\n protected void finalize() {\n /* ... */\n }\n }\n" }, "defaultConfiguration": { "enabled": true, @@ -3800,7 +3830,7 @@ { "target": { "id": "Java/Finalization", - "index": 50, + "index": 51, "toolComponent": { "name": "QDJVM" } @@ -3834,7 +3864,7 @@ { "target": { "id": "Java/Logging", - "index": 51, + "index": 52, "toolComponent": { "name": "QDJVM" } @@ -3868,7 +3898,7 @@ { "target": { "id": "Java/Modularization issues", - "index": 52, + "index": 53, "toolComponent": { "name": "QDJVM" } @@ -3902,7 +3932,7 @@ { "target": { "id": "Java/Control flow issues", - "index": 26, + "index": 27, "toolComponent": { "name": "QDJVM" } @@ -3936,7 +3966,7 @@ { "target": { "id": "Java/Javadoc", - "index": 53, + "index": 54, "toolComponent": { "name": "QDJVM" } @@ -4004,7 +4034,7 @@ { "target": { "id": "Java/Naming conventions/Class", - "index": 56, + "index": 57, "toolComponent": { "name": "QDJVM" } @@ -4086,7 +4116,7 @@ { "id": "UnnecessaryTemporaryOnConversionFromString", "shortDescription": { - "text": "Unnecessary temporary object in conversion from String" + "text": "Unnecessary temporary object in conversion from 'String'" }, "fullDescription": { "text": "Reports unnecessary creation of temporary objects when converting from 'String' to primitive types. Example: 'new Integer(\"3\").intValue()' After the quick-fix is applied: 'Integer.valueOf(\"3\")'", @@ -4140,7 +4170,7 @@ { "target": { "id": "Java/Abstraction issues", - "index": 61, + "index": 62, "toolComponent": { "name": "QDJVM" } @@ -4185,6 +4215,40 @@ } ] }, + { + "id": "IOStreamConstructor", + "shortDescription": { + "text": "'InputStream' and 'OutputStream' can be constructed using 'Files' methods" + }, + "fullDescription": { + "text": "Reports 'FileInputStream' or 'FileOutputStream' constructors when it is possible to replace them with 'Files.newInputStream()' or 'Files.newOutputStream()' accordingly. The streams created using 'Files' methods are usually more efficient than those created by stream constructors. Example: 'InputStream is = new BufferedInputStream(new FileInputStream(file));' After the quick-fix is applied: 'InputStream is = new BufferedInputStream(Files.newInputStream(file.toPath()));' This inspection does not show warning if the language level 10 or higher, but the quick-fix is still available. This inspection only reports if the language level of the project or module is 7 or higher. New in 2022.1", + "markdown": "Reports `FileInputStream` or `FileOutputStream` constructors when it is possible to replace them with `Files.newInputStream()` or `Files.newOutputStream()` accordingly. \nThe streams created using `Files` methods are usually more efficient than those created by stream constructors.\n\nExample:\n\n\n InputStream is = new BufferedInputStream(new FileInputStream(file));\n\nAfter the quick-fix is applied:\n\n\n InputStream is = new BufferedInputStream(Files.newInputStream(file.toPath()));\n\nThis inspection does not show warning if the language level 10 or higher, but the quick-fix is still available.\n\nThis inspection only reports if the language level of the project or module is 7 or higher.\n\nNew in 2022.1" + }, + "defaultConfiguration": { + "enabled": false, + "level": "warning", + "parameters": { + "ideaSeverity": "WARNING", + "tags": [ + "ideaSeverity" + ] + } + }, + "relationships": [ + { + "target": { + "id": "Java/Performance", + "index": 10, + "toolComponent": { + "name": "QDJVM" + } + }, + "kinds": [ + "superset" + ] + } + ] + }, { "id": "AssignmentToForLoopParameter", "shortDescription": { @@ -4208,7 +4272,7 @@ { "target": { "id": "Java/Assignment issues", - "index": 62, + "index": 63, "toolComponent": { "name": "QDJVM" } @@ -4242,7 +4306,7 @@ { "target": { "id": "Java/Java language level migration aids/Java 9", - "index": 63, + "index": 64, "toolComponent": { "name": "QDJVM" } @@ -4276,7 +4340,7 @@ { "target": { "id": "Java/JUnit", - "index": 46, + "index": 47, "toolComponent": { "name": "QDJVM" } @@ -4310,7 +4374,7 @@ { "target": { "id": "Java/Verbose or redundant code constructs", - "index": 68, + "index": 37, "toolComponent": { "name": "QDJVM" } @@ -4378,7 +4442,7 @@ { "target": { "id": "Java/Portability", - "index": 73, + "index": 71, "toolComponent": { "name": "QDJVM" } @@ -4412,7 +4476,7 @@ { "target": { "id": "Java/Abstraction issues", - "index": 61, + "index": 62, "toolComponent": { "name": "QDJVM" } @@ -4460,7 +4524,7 @@ { "id": "SuspiciousInvocationHandlerImplementation", "shortDescription": { - "text": "Suspicious InvocationHandler implementation" + "text": "Suspicious 'InvocationHandler' implementation" }, "fullDescription": { "text": "Reports implementations of 'InvocationHandler' that do not proxy standard 'Object' methods like 'hashCode()', 'equals()', and 'toString()'. Failing to handle these methods might cause unexpected problems upon calling them on a proxy instance. Example: 'InvocationHandler myHandler = (proxy, method, params) -> {\n System.out.println(\"Hello World!\");\n return null;\n };\n Runnable myProxy = (Runnable) Proxy.newProxyInstance(\n Thread.currentThread().getContextClassLoader(),\n new Class[] {Runnable.class}, myHandler\n );' This code snippet is designed to only proxy the 'Runnable.run()' method. However, calls to any 'Object' methods, like 'hashCode()', are proxied as well. This can lead to problems like a 'NullPointerException', for example, when adding 'myProxy' to a 'HashSet'. New in 2020.2", @@ -4480,7 +4544,7 @@ { "target": { "id": "Java/Probable bugs", - "index": 15, + "index": 16, "toolComponent": { "name": "QDJVM" } @@ -4494,7 +4558,7 @@ { "id": "HtmlTagCanBeJavadocTag", "shortDescription": { - "text": "... can be replaced with {@code ...}" + "text": "'...' can be replaced with '{@code ...}'" }, "fullDescription": { "text": "Reports usages of '' tags in Javadoc comments. Since Java 5, these tags can be replaced with '{@code ...}' constructs. This allows using angle brackets '<' and '>' inside the comment instead of HTML character entities. Example: '/**\n * @return empty ArrayList<Integer>\n */\n List getList(){ ... }' After the quick-fix is applied: '/**\n * @return empty {@code ArrayList}\n */\n List getList(){ ... }'", @@ -4514,7 +4578,7 @@ { "target": { "id": "Java/Javadoc", - "index": 53, + "index": 54, "toolComponent": { "name": "QDJVM" } @@ -4528,7 +4592,7 @@ { "id": "ClassEscapesItsScope", "shortDescription": { - "text": "Non-accessible 'class' is exposed" + "text": "Non-accessible class is exposed" }, "fullDescription": { "text": "Reports usages of classes in a field or method signature when a class in a signature is less visible than the member itself. While legal Java, such members are useless outside of the visibility scope. Example: 'public' method which returns a 'private' inner 'class'. 'protected' field whose type is a package-local 'class'. In Java 9, a module may hide some of its classes by excluding their packages from export. So, if the signature of exported API contains a non-exported class, such an API is useless outside of the module. Configure the inspection: Use the Module's API exposes not exported classes (Java 9+) option to report about the module API that exposes unexported classes. Note that the option works if the language level of the project or module is 9 or higher. Use the Public API exposes non-accessible classes option to report about a public API that exposes non-accessible classes. Use the Package-local API exposes private classes option to report about package-local API that exposes 'private' classes.", @@ -4548,7 +4612,7 @@ { "target": { "id": "Java/Visibility", - "index": 76, + "index": 75, "toolComponent": { "name": "QDJVM" } @@ -4582,7 +4646,7 @@ { "target": { "id": "Java/Probable bugs", - "index": 15, + "index": 16, "toolComponent": { "name": "QDJVM" } @@ -4616,7 +4680,7 @@ { "target": { "id": "Java/Assignment issues", - "index": 62, + "index": 63, "toolComponent": { "name": "QDJVM" } @@ -4633,8 +4697,8 @@ "text": "Auto-unboxing" }, "fullDescription": { - "text": "Reports expressions that are affected by unboxing conversion (automatic unwrapping of objects into primitive values). Try not to use objects instead of primitives. It might significantly affect the performance. Example: 'int x = new Integer(42);' The quick-fix makes the conversion explicit: 'int x = new Integer(42).intValue();' Autoboxing conversion is not supported in Java 1.4 and earlier JVM.", - "markdown": "Reports expressions that are affected by unboxing conversion (automatic unwrapping of objects into primitive values). Try not to use objects instead of primitives. It might significantly affect the performance.\n\n**Example:**\n\n int x = new Integer(42);\n\nThe quick-fix makes the conversion explicit:\n\n int x = new Integer(42).intValue();\n\nAutoboxing conversion is not supported in Java 1.4 and earlier JVM." + "text": "Reports expressions that are affected by unboxing conversion (automatic unwrapping of objects into primitive values). Try not to use objects instead of primitives. It might significantly affect the performance. Example: 'int x = new Integer(42);' The quick-fix makes the conversion explicit: 'int x = new Integer(42).intValue();' AutoUnboxing appeared in Java 5. This inspection can help to downgrade for backward compatibility with earlier Java versions.", + "markdown": "Reports expressions that are affected by unboxing conversion (automatic unwrapping of objects into primitive values). Try not to use objects instead of primitives. It might significantly affect the performance.\n\n**Example:**\n\n int x = new Integer(42);\n\nThe quick-fix makes the conversion explicit:\n\n int x = new Integer(42).intValue();\n\n\n*AutoUnboxing* appeared in Java 5.\nThis inspection can help to downgrade for backward compatibility with earlier Java versions." }, "defaultConfiguration": { "enabled": false, @@ -4664,7 +4728,7 @@ { "id": "NonFinalFieldInImmutable", "shortDescription": { - "text": "Non-final field in @Immutable class" + "text": "Non-final field in '@Immutable' class" }, "fullDescription": { "text": "Reports any non-final field in a class with the '@Immutable' annotation. This violates the contract of the '@Immutable' annotation. Example: 'import javax.annotation.concurrent.Immutable;\n @Immutable\n class Foo {\n String bar = \"foo\";\n }' Supported '@GuardedBy' annotations are: 'net.jcip.annotations.GuardedBy' 'javax.annotation.concurrent.GuardedBy' 'org.apache.http.annotation.GuardedBy' 'com.android.annotations.concurrency.GuardedBy' 'androidx.annotation.GuardedBy' 'com.google.errorprone.annotations.concurrent.GuardedBy'", @@ -4684,7 +4748,7 @@ { "target": { "id": "Java/Concurrency annotation issues", - "index": 77, + "index": 76, "toolComponent": { "name": "QDJVM" } @@ -4718,7 +4782,7 @@ { "target": { "id": "Java/Probable bugs", - "index": 15, + "index": 16, "toolComponent": { "name": "QDJVM" } @@ -4786,7 +4850,7 @@ { "target": { "id": "Java/JUnit", - "index": 46, + "index": 47, "toolComponent": { "name": "QDJVM" } @@ -4820,7 +4884,7 @@ { "target": { "id": "Java/Portability", - "index": 73, + "index": 71, "toolComponent": { "name": "QDJVM" } @@ -4854,7 +4918,7 @@ { "target": { "id": "Java/Numeric issues", - "index": 27, + "index": 26, "toolComponent": { "name": "QDJVM" } @@ -4888,7 +4952,7 @@ { "target": { "id": "Java/Javadoc", - "index": 53, + "index": 54, "toolComponent": { "name": "QDJVM" } @@ -4922,7 +4986,7 @@ { "target": { "id": "Java/Probable bugs", - "index": 15, + "index": 16, "toolComponent": { "name": "QDJVM" } @@ -4956,7 +5020,7 @@ { "target": { "id": "Java/Data flow", - "index": 43, + "index": 44,