diff --git a/its/ruling/src/test/resources/expected/eclipse-jetty-similar-to-main/java-S9358.json b/its/ruling/src/test/resources/expected/eclipse-jetty-similar-to-main/java-S9358.json deleted file mode 100644 index 95dedef2f79..00000000000 --- a/its/ruling/src/test/resources/expected/eclipse-jetty-similar-to-main/java-S9358.json +++ /dev/null @@ -1,9 +0,0 @@ -{ -"eclipse-jetty:jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java": [ -129 -], -"eclipse-jetty:jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java": [ -362, -373 -] -} diff --git a/its/ruling/src/test/resources/expected/eclipse-jetty/java-S9358.json b/its/ruling/src/test/resources/expected/eclipse-jetty/java-S9358.json index c0d8f9793cf..ebfe745e721 100644 --- a/its/ruling/src/test/resources/expected/eclipse-jetty/java-S9358.json +++ b/its/ruling/src/test/resources/expected/eclipse-jetty/java-S9358.json @@ -1,15 +1,5 @@ { -"eclipse-jetty:jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java": [ -129 -], -"eclipse-jetty:jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java": [ -362, -373 -], "eclipse-jetty:jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java": [ 58 -], -"eclipse-jetty:jetty-util/src/test/java/org/eclipse/jetty/util/statistic/CounterStatisticTest.java": [ -91 ] } diff --git a/its/ruling/src/test/resources/expected/guava/java-S9358.json b/its/ruling/src/test/resources/expected/guava/java-S9358.json deleted file mode 100644 index 49cc1861a22..00000000000 --- a/its/ruling/src/test/resources/expected/guava/java-S9358.json +++ /dev/null @@ -1,12 +0,0 @@ -{ -"guava:src/com/google/common/collect/RegularImmutableTable.java": [ -151, -155 -], -"guava:src/com/google/common/collect/TreeMultiset.java": [ -91 -], -"guava:src/com/google/common/hash/MessageDigestHashFunction.java": [ -156 -] -} diff --git a/its/ruling/src/test/resources/expected/sonarqube-6.5/java-S9358.json b/its/ruling/src/test/resources/expected/sonarqube-6.5/java-S9358.json index 02230c7e1b6..dbdbd0af966 100644 --- a/its/ruling/src/test/resources/expected/sonarqube-6.5/java-S9358.json +++ b/its/ruling/src/test/resources/expected/sonarqube-6.5/java-S9358.json @@ -1,14 +1,5 @@ { -"sonarqube-6.5:src/main/java/org/sonar/server/computation/task/projectanalysis/qualitygate/ConditionEvaluator.java": [ -113 -], "sonarqube-6.5:src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java": [ 175 -], -"sonarqube-6.5:src/main/java/org/sonar/server/qualityprofile/RuleActivator.java": [ -200 -], -"sonarqube-6.5:src/main/java/org/sonar/server/setting/ws/ValuesAction.java": [ -247 ] } diff --git a/java-checks-test-sources/default/src/main/java/checks/TernaryOperatorSameOperationCheckSample.java b/java-checks-test-sources/default/src/main/java/checks/TernaryOperatorSameOperationCheckSample.java index f0e3dc02894..a6585025cfc 100644 --- a/java-checks-test-sources/default/src/main/java/checks/TernaryOperatorSameOperationCheckSample.java +++ b/java-checks-test-sources/default/src/main/java/checks/TernaryOperatorSameOperationCheckSample.java @@ -177,7 +177,37 @@ void testNonIdentifierReceiver() { Object nir1 = condition ? getObj().foo(a) : getObj().foo(b); // Noncompliant } + void testComplexArguments(String value, StringBuilder buffer, int index) { + String c12 = condition ? foo(value.substring(1)) : foo(value); // Compliant - method invocation as differing argument + String c13 = condition ? foo(value.substring(1)) : foo(value.substring(2)); // Compliant - nested invocations + Object c14 = condition ? new Thread(() -> {}) : new Thread(this::run); // Compliant - lambda and method reference + Object c15 = condition ? new Foo((String) obj.toString()) : new Foo(value); // Compliant - cast + Object c16 = condition ? new Foo(value + "x") : new Foo(value); // Compliant - binary expression + String c17 = condition ? foo(new String("a")) : foo(value); // Compliant - object creation + String[] arr = {value}; + String c18 = condition ? arr[index + 1] : arr[index]; // Compliant - complex index + + String s1 = condition ? foo("abc") : foo("def"); // Noncompliant + String s2 = condition ? foo(this.field) : foo(value); // Noncompliant + String s3 = condition ? foo(obj.field) : foo(obj2.field); // Noncompliant + String s4 = condition ? foo((value)) : foo(field); // Noncompliant + Object s5 = condition ? overloaded(-1) : overloaded(index); // Noncompliant + String s6 = condition ? arr[0] : arr[index]; // Noncompliant + } + + void testDifferentArgumentTypes(int primitive, Integer boxed, long longValue, Object object, String string) { + Object t1 = condition ? takesLong(primitive) : takesLong(longValue); // Compliant - different argument types + Object t2 = condition ? takesObject(boxed) : takesObject(primitive); // Compliant - unboxing would occur + Object t3 = condition ? takesObject(string) : takesObject(object); // Compliant - different argument types + Object t4 = condition ? foo(string) : foo(null); // Compliant - null literal + Object t5 = condition ? takesLong(longValue) : takesLong(1L); // Noncompliant + } + // Private methods used in ternary + String field; + private void run() { } + private Object takesLong(long l) { return l; } + private Object takesObject(Object o) { return o; } private String foo(String s) { return s; } private String foo(String s, String t) { return s + t; } private String bar(String s) { return s; } diff --git a/java-checks/src/main/java/org/sonar/java/checks/TernaryOperatorSameOperationCheck.java b/java-checks/src/main/java/org/sonar/java/checks/TernaryOperatorSameOperationCheck.java index 0861e01ad11..5a2e18dd0b8 100644 --- a/java-checks/src/main/java/org/sonar/java/checks/TernaryOperatorSameOperationCheck.java +++ b/java-checks/src/main/java/org/sonar/java/checks/TernaryOperatorSameOperationCheck.java @@ -22,14 +22,17 @@ import org.sonar.java.model.SyntacticEquivalence; import org.sonar.plugins.java.api.IssuableSubscriptionVisitor; import org.sonar.plugins.java.api.semantic.Symbol; +import org.sonar.plugins.java.api.semantic.Type; import org.sonar.plugins.java.api.tree.ArrayAccessExpressionTree; import org.sonar.plugins.java.api.tree.ConditionalExpressionTree; import org.sonar.plugins.java.api.tree.ExpressionTree; import org.sonar.plugins.java.api.tree.IdentifierTree; +import org.sonar.plugins.java.api.tree.LiteralTree; import org.sonar.plugins.java.api.tree.MemberSelectExpressionTree; import org.sonar.plugins.java.api.tree.MethodInvocationTree; import org.sonar.plugins.java.api.tree.NewClassTree; import org.sonar.plugins.java.api.tree.Tree; +import org.sonar.plugins.java.api.tree.UnaryExpressionTree; @Rule(key = "S9358") public class TernaryOperatorSameOperationCheck extends IssuableSubscriptionVisitor { @@ -130,7 +133,12 @@ private static boolean hasExactlyOneArgumentDifference(List