Skip to content
Open
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
@@ -1,6 +1,6 @@
{
"ruleKey": "S1481",
"hasTruePositives": true,
"falseNegatives": 10,
"falseNegatives": 8,
"falsePositives": 0
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package checks;


public class UnusedVariablesFPCheck {
public class DeobfuscatedUpdateManager {
// @formatter:off
// uncommenting the following code makes the issue disappear, as the semantic is fully resolved
// private interface DataContainer {
// Iterable<ItemElement> getItems();
// }
//
// private interface ModelObject {
// void performAction();
// }
//
// private interface ItemElement {
// ModelObject getDataModel();
// }
//
// private static class SystemConfig {
// static ConfigMode getMode() {
// return ConfigMode.ENABLED;
// }
// }
//
// private enum ConfigMode {
// ENABLED,
// DISABLED
// }
//
// static class A {
// interface GenericCallback<T> { }
// }
// @formatter:on

void processUpdates(
DataContainer container
// REMARK : the issue arises from the A.GenericCallback<ModelObject> callback that is not even used (indirect type resolution problem)
, A.GenericCallback<X> callback
) {
for (ItemElement element : container.getItems()) {
if (SystemConfig.getMode() == ConfigMode.ENABLED) {
ModelObject dataModel = element.getDataModel(); // Compliant - false positive was raised here, dataModel is used in the next line
dataModel.performAction();
}
}
}

}

static class StringConcatenation {
// @formatter:off
// uncommenting the following code makes the issue disappear, as the semantic is fully resolved
// private class AClass {
// private class BClass<T> {
// public T b;
// }
// }
// @formatter:on

public String doSomething(AClass.BClass<String> instance) {
String c = "Hi"; // Compliant - false positive was raised here, c is used in the next line
return instance.b + c;
}
}

/*
A user reported a FP on enhanced switch statements like the one below.
However I was not able to reproduce it in a minimal example.
https://community.sonarsource.com/t/false-positive-for-s1854-unused-assignments-should-be-removed/114110/12

static class EnhancedSwitch {
// private enum DocumentStatus {
// DOC01,
// DOC02
// }
//
// private interface Document {
// void setStatus(DocumentStatus status);
// }
//
// private interface Event {
// }
//
// private class SimpleStatusChangedEvent implements Event {
// }
//
// private class NeedClientRecheckEvent implements Event {
// }
// private interface DocumentRepository {
// void save(Document document);
// }

void ko(Event event, Document document, DocumentRepository documentRepository) {
final DocumentStatus status = switch (event) {
case SimpleStatusChangedEvent ignored -> DocumentStatus.DOC01;
case NeedClientRecheckEvent ignored -> DocumentStatus.DOC02;
};
document.setStatus(status);
// ...
documentRepository.save(document);
}

}*/
}
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,14 @@ void test_non_compiling() {
.verifyIssues();
}

@Test
void test_incomplete_semantic() {
CheckVerifier.newVerifier()
.onFile(TestUtils.nonCompilingTestSourcesPath("checks/UnusedVariablesFPCheck.java"))
.withCheck(new DeadStoreCheck())
.verifyNoIssues();
}

private static class EraseSymbols extends BaseTreeVisitor {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public final boolean isTypeSymbol() {
}

@Override
public final boolean isMethodSymbol() {
public boolean isMethodSymbol() {
return false;
}

Expand Down Expand Up @@ -340,6 +340,11 @@ public boolean isVarArgsMethod() {
public boolean isNativeMethod() {
return false;
}

@Override
public boolean isMethodSymbol() {
return true;
}
}

public static final class UnknownType implements Type {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1285,7 +1285,7 @@ private java.util.Collection<UnknownClass.Entry<E>> samples() {

assertThat(recovered.isTypeSymbol()).isFalse();
assertThat(recovered.isVariableSymbol()).isFalse();
assertThat(recovered.isMethodSymbol()).isFalse();
assertThat(recovered.isMethodSymbol()).isTrue();
assertThat(recovered.isPackageSymbol()).isFalse();

assertThat(recovered.isAbstract()).isFalse();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@
Symbol unknownSymbol = Symbol.UNKNOWN_SYMBOL;

assertCommonProperties(unknownSymbol);
assertThat(unknownSymbol.isMethodSymbol()).isEqualTo(false);

Check warning on line 128 in java-frontend/src/test/java/org/sonar/java/model/SymbolsTest.java

View check run for this annotation

SonarQube-Next / SonarQube Code Analysis

Use isFalse() instead.

[S5838] Chained AssertJ assertions should be simplified to the corresponding dedicated assertion See more on https://next.sonarqube.com/sonarqube/project/issues?id=org.sonarsource.java%3Ajava&pullRequest=5378&issues=62314da3-c893-4e96-9126-c91ce97f8111&open=62314da3-c893-4e96-9126-c91ce97f8111
assertThat(unknownSymbol.name()).isEqualTo("!unknown!");
assertThat(unknownSymbol.owner()).isEqualTo(Symbol.ROOT_PACKAGE);
SymbolMetadata metadata = unknownSymbol.metadata();
Expand All @@ -137,6 +138,7 @@
Symbol.TypeSymbol unknownTypeSymbol = Symbol.TypeSymbol.UNKNOWN_TYPE;

assertCommonProperties(unknownTypeSymbol);
assertThat(unknownTypeSymbol.isMethodSymbol()).isEqualTo(false);

Check warning on line 141 in java-frontend/src/test/java/org/sonar/java/model/SymbolsTest.java

View check run for this annotation

SonarQube-Next / SonarQube Code Analysis

Use isFalse() instead.

[S5838] Chained AssertJ assertions should be simplified to the corresponding dedicated assertion See more on https://next.sonarqube.com/sonarqube/project/issues?id=org.sonarsource.java%3Ajava&pullRequest=5378&issues=43cf43e8-24f7-4497-aac9-af28ef70f5b8&open=43cf43e8-24f7-4497-aac9-af28ef70f5b8
assertThat(unknownTypeSymbol.name()).isEqualTo("!unknown!");
assertThat(unknownTypeSymbol.owner()).isEqualTo(Symbol.ROOT_PACKAGE);

Expand All @@ -154,6 +156,7 @@
Symbol.MethodSymbol unknownMethodSymbol = Symbol.MethodSymbol.UNKNOWN_METHOD;

assertCommonProperties(unknownMethodSymbol);
assertThat(unknownMethodSymbol.isMethodSymbol()).isEqualTo(true);

Check warning on line 159 in java-frontend/src/test/java/org/sonar/java/model/SymbolsTest.java

View check run for this annotation

SonarQube-Next / SonarQube Code Analysis

Use isTrue() instead.

[S5838] Chained AssertJ assertions should be simplified to the corresponding dedicated assertion See more on https://next.sonarqube.com/sonarqube/project/issues?id=org.sonarsource.java%3Ajava&pullRequest=5378&issues=4da054a8-f1c8-4ec3-b36f-702c274c6d56&open=4da054a8-f1c8-4ec3-b36f-702c274c6d56
assertThat(unknownMethodSymbol.name()).isEqualTo("!unknownMethod!");
assertThat(unknownMethodSymbol.owner()).isEqualTo(Symbol.TypeSymbol.UNKNOWN_TYPE);

Expand All @@ -171,7 +174,6 @@
assertThat(unknownSymbol.isPackageSymbol()).isFalse();
assertThat(unknownSymbol.isTypeSymbol()).isFalse();
assertThat(unknownSymbol.isVariableSymbol()).isFalse();
assertThat(unknownSymbol.isMethodSymbol()).isFalse();

assertThat(unknownSymbol.isStatic()).isFalse();
assertThat(unknownSymbol.isFinal()).isFalse();
Expand Down
Loading