Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"org.eclipse.jetty:jetty-project:jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java": [
129
],
"org.eclipse.jetty:jetty-project:jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java": [
362,
373
]
}
15 changes: 15 additions & 0 deletions its/ruling/src/test/resources/eclipse-jetty/java-S9358.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
{
"org.eclipse.jetty:jetty-project:jetty-http/src/main/java/org/eclipse/jetty/http/QuotedQualityCSV.java": [
129
],
"org.eclipse.jetty:jetty-project:jetty-jmx/src/main/java/org/eclipse/jetty/jmx/MBeanContainer.java": [
362,
373
],
"org.eclipse.jetty:jetty-project:jetty-util/src/main/java/org/eclipse/jetty/util/JavaVersion.java": [
58
],
"org.eclipse.jetty:jetty-project:jetty-util/src/test/java/org/eclipse/jetty/util/statistic/CounterStatisticTest.java": [
91
]
}
12 changes: 12 additions & 0 deletions its/ruling/src/test/resources/guava/java-S9358.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{
"com.google.guava:guava:src/com/google/common/collect/RegularImmutableTable.java": [
151,
155
],
"com.google.guava:guava:src/com/google/common/collect/TreeMultiset.java": [
91
],
"com.google.guava:guava:src/com/google/common/hash/MessageDigestHashFunction.java": [
156
]
}
14 changes: 14 additions & 0 deletions its/ruling/src/test/resources/sonar-server/java-S9358.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"org.sonarsource.sonarqube:sonar-server:src/main/java/org/sonar/server/computation/task/projectanalysis/qualitygate/ConditionEvaluator.java": [
113
],
"org.sonarsource.sonarqube:sonar-server:src/main/java/org/sonar/server/qualitygate/QualityGateConditionsUpdater.java": [
175
],
"org.sonarsource.sonarqube:sonar-server:src/main/java/org/sonar/server/qualityprofile/RuleActivator.java": [
200
],
"org.sonarsource.sonarqube:sonar-server:src/main/java/org/sonar/server/setting/ws/ValuesAction.java": [
247
]
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package checks;

import java.util.function.Function;

class TernaryOperatorSameOperationCheckNoSemanticSample {

boolean condition;
boolean other;
TernaryOperatorSameOperationCheckNoSemanticSample obj;
TernaryOperatorSameOperationCheckNoSemanticSample obj2;

void testMethodInvocations() {
String a = "a";
String b = "b";
String x = "x";
String y = "y";

// Method invocations - Noncompliant
String m1 = condition ? foo(a) : foo(b); // Noncompliant {{Move the conditional expression inside this operation.}}

String m2 = condition ? this.foo(a) : this.foo(b); // Noncompliant
String m3 = condition ? obj.foo(a) : obj.foo(b); // Noncompliant

// Method invocations with multiple args where some differ - Noncompliant
String m5 = condition ? foo(a, x) : foo(b, x); // Noncompliant

Comment thread
gitar-bot[bot] marked this conversation as resolved.
// Method invocations with multiple args where all differ - Compliant
String m6 = condition ? foo(a, x) : foo(b, y); // Compliant - more than one argument differs

// Method invocations - Compliant (different operations or same arguments)
String c1 = condition ? foo(a) : bar(b); // Compliant - different methods
String c2 = condition ? foo(a) : foo(a); // Compliant - same arguments
String c3 = condition ? foo(a) : foo(a, b); // Compliant - different number of arguments
}

void testNewClass() {
String a = "a";
String b = "b";

// New class - Noncompliant
Object n1 = condition ? new Foo(a) : new Foo(b); // Noncompliant {{Move the conditional expression inside this operation.}}

// New class - Compliant
Object c4 = condition ? new Foo(a) : new Bar(b); // Compliant - different classes
Object c5 = condition ? new Foo(a) : new Foo(a); // Compliant - same arguments
Object c6 = condition ? new Foo(a) : new Foo(a, b); // Compliant - different arguments count
}

void testArrayAccess() {
String[] arr = new String[10];
String[] otherArr = new String[10];
int i = 0;
int j = 1;

// Array access - Noncompliant
String a1 = condition ? arr[i] : arr[j]; // Noncompliant {{Move the conditional expression inside this operation.}}

// Array access - Compliant
String c7 = condition ? arr[i] : arr[i]; // Compliant - same index
String c8 = condition ? arr[i] : otherArr[j]; // Compliant - different arrays
}

void testNewClassWithClassBody() {
String a = "a";
String b = "b";

// Anonymous class body - Compliant even without semantics
Object ac1 = condition ? new Foo(a) { } : new Foo(b) { }; // Compliant - anonymous class bodies
Object ac2 = condition ? new Foo(a) { } : new Foo(b); // Compliant - one has class body
}

// Private methods used in ternary
private String foo(String s) { return s; }
private String foo(String s, String t) { return s + t; }
private String bar(String s) { return s; }
private String noArg() { return ""; }

private static class Foo {
Foo(String s) {}
Foo(String s, String t) {}
}

private static class Bar {
Bar(String s) {}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
package checks;

import java.util.function.Function;

class TernaryOperatorSameOperationCheckSample {

boolean condition;
boolean other;
TernaryOperatorSameOperationCheckSample obj;
TernaryOperatorSameOperationCheckSample obj2;

void testMethodInvocations() {
String a = "a";
String b = "b";
String x = "x";
String y = "y";
String z = "z";

// Method invocations - Noncompliant
String m1 = condition ? foo(a) : foo(b); // Noncompliant {{Move the conditional expression inside this operation.}}

String m2 = condition ? this.foo(a) : this.foo(b); // Noncompliant
String m3 = condition ? obj.foo(a) : obj.foo(b); // Noncompliant
String m4 = condition ? StaticClass.foo(a) : StaticClass.foo(b); // Noncompliant

// Method invocations with multiple args where some differ - Noncompliant
String m5 = condition ? foo(a, x) : foo(b, x); // Noncompliant

// Method invocations with multiple args where all differ - Compliant
String m6 = condition ? foo(a, x) : foo(b, y); // Compliant - more than one argument differs

// Method invocations - Compliant (different operations or same arguments)
String c1 = condition ? foo(a) : bar(b); // Compliant - different methods
String c2 = condition ? foo(a) : foo(a); // Compliant - same arguments
String c3 = condition ? foo(a) : foo(a, b); // Compliant - different number of arguments
}

void testMethodInvocationsEdgeCases() {
String a = "a";
String b = "b";

// No-arg methods - Compliant (no arguments to differ)
String e1 = condition ? noArg() : noArg(); // Compliant

// Different receivers - Compliant
String e2 = condition ? obj.foo(a) : obj2.foo(b); // Compliant - different receiver objects

// Different kinds in true/false - Compliant
Object e3 = condition ? foo(a) : new Foo(b); // Compliant - method vs constructor
Object e4 = condition ? a : b; // Compliant - simple identifiers, not method/new/array

// String literal - Compliant
String e5 = condition ? "hello" : "world"; // Compliant

// Numeric literal - Compliant
int e6 = condition ? 1 : 2; // Compliant
}

void testNewClass() {
String a = "a";
String b = "b";

// New class - Noncompliant
Object n1 = condition ? new Foo(a) : new Foo(b); // Noncompliant {{Move the conditional expression inside this operation.}}

// New class with multiple args where some differ - Noncompliant
Object n2 = condition ? new Foo(a, b) : new Foo(b, b); // Noncompliant

// New class with multiple args where all differ - Compliant
Object n3 = condition ? new Foo(a, a) : new Foo(b, b); // Compliant - more than one argument differs

// New class - Compliant
Object c4 = condition ? new Foo(a) : new Bar(b); // Compliant - different classes
Object c5 = condition ? new Foo(a) : new Foo(a); // Compliant - same arguments
Object c6 = condition ? new Foo(a) : new Foo(a, b); // Compliant - different arguments count
}

void testArrayAccess() {
String[] arr = new String[10];
String[] otherArr = new String[10];
int i = 0;
int j = 1;

// Array access - Noncompliant
String a1 = condition ? arr[i] : arr[j]; // Noncompliant {{Move the conditional expression inside this operation.}}

// Array access - Compliant
String c7 = condition ? arr[i] : arr[i]; // Compliant - same index
String c8 = condition ? arr[i] : otherArr[j]; // Compliant - different arrays
}

void testNestedTernary() {
String x = "x";
String y = "y";
String z = "z";

// Nested ternary - Noncompliant (outer ternary has same operation after parentheses skip)
String n3 = condition ? (other ? foo(x) : foo(y)) : foo(z); // Noncompliant {{Move the conditional expression inside this operation.}}

// Nested ternary - Compliant (inner ternary is not same operation)
String c9 = condition ? (other ? foo(x) : bar(x)) : foo(z); // Compliant
}

void testMemberSelectEdgeCases() {
String a = "a";
String b = "b";

// Same receiver, different method names - Compliant
String ms1 = condition ? obj.foo(a) : obj.bar(b); // Compliant - different method names

// Method invocation vs member select method invocation - Compliant
String ms2 = condition ? foo(a) : obj.foo(b); // Compliant - identifier vs member select
}

void testOther() {
String a = "a";
String b = "b";

// Method reference - Compliant
Function<String, String> f1 = condition ? this::foo : this::method; // Compliant

// Multiple different operations - Compliant
String c10 = condition ? foo(a) : bar(b); // Compliant
Object c11 = condition ? new Foo(a) : new Bar(b); // Compliant

// Array access vs method invocation - Compliant
String[] arr = {a, b};
Object o1 = condition ? arr[0] : foo(b); // Compliant - different expression kinds

// New class vs array access - Compliant
Object o2 = condition ? new Foo(a) : arr[0]; // Compliant - different expression kinds
}

void testOverloadedMethods() {
// Overloaded methods with different parameter types - Compliant (different method symbols)
Object ov1 = condition ? overloaded(1) : overloaded("x"); // Compliant - different overloads
Object ov2 = condition ? this.overloaded(1) : this.overloaded("x"); // Compliant - different overloads

// Same overload, different arguments - Noncompliant
Object ov3 = condition ? overloaded(1) : overloaded(2); // Noncompliant
Object ov4 = condition ? overloaded("a") : overloaded("b"); // Noncompliant
}

void testOverloadedConstructors() {
// Overloaded constructors with different parameter types - Compliant (different constructor symbols)
Object oc1 = condition ? new OverloadedCtor(1) : new OverloadedCtor("x"); // Compliant - different constructors
}

void testNewClassWithClassBody() {
String a = "a";
String b = "b";

// Anonymous class body - Compliant (class bodies make each instantiation unique)
Object ac1 = condition ? new Foo(a) { } : new Foo(b) { }; // Compliant - anonymous class bodies
Object ac2 = condition ? new Foo(a) { } : new Foo(b); // Compliant - one has class body
}

void testQualifiedInstantiations() {
String a = "a";
String b = "b";

// Qualified instantiation with same enclosing expression - Noncompliant
Object qi1 = condition ? obj.new Inner(a) : obj.new Inner(b); // Noncompliant

// Qualified instantiation with different enclosing expression - Compliant
Object qi2 = condition ? obj.new Inner(a) : obj2.new Inner(b); // Compliant - different enclosing expressions

// Mixed: unqualified vs qualified - Compliant
Object qi3 = condition ? new Inner(a) : obj.new Inner(b); // Compliant - one has enclosing, other doesn't
}

void testNonIdentifierReceiver() {
String a = "a";
String b = "b";

// Non-identifier receiver (method call as receiver) - Noncompliant
Object nir1 = condition ? getObj().foo(a) : getObj().foo(b); // Noncompliant
}

// Private methods used in ternary
private String foo(String s) { return s; }
private String foo(String s, String t) { return s + t; }
private String bar(String s) { return s; }
private String method(String s) { return s; }
private String noArg() { return ""; }
private Object overloaded(int i) { return i; }
private Object overloaded(String s) { return s; }
private TernaryOperatorSameOperationCheckSample getObj() { return this; }

private static class StaticClass {
static String foo(String s) { return s; }
}

private static class Foo {
Foo(String s) {}
Foo(String s, String t) {}
}

private static class Bar {
Bar(String s) {}
}

private static class OverloadedCtor {
OverloadedCtor(int i) {}
OverloadedCtor(String s) {}
}

class Inner {
Inner(String s) {}
}

}
Loading
Loading