Skip to content

Commit e8ee20b

Browse files
SONARJAVA-5659 Make inAndroidContext final (#5223)
In order to make code easier to understand we made two changes: * inAndroidContext is now final (in prod code) * VisitorsBridgeForTests is constructed using a builder
1 parent ae437c3 commit e8ee20b

File tree

11 files changed

+125
-56
lines changed

11 files changed

+125
-56
lines changed

java-checks-testkit/src/main/java/org/sonar/java/checks/verifier/internal/InternalCheckVerifier.java

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -282,17 +282,18 @@ private void verifyAll() {
282282
visitors.add(expectations.parser());
283283
}
284284
SonarComponents sonarComponents = CheckVerifierUtils.sonarComponents(isCacheEnabled, readCache, writeCache, null);
285-
VisitorsBridgeForTests visitorsBridge;
286285
JavaVersion actualVersion = javaVersion == null ? DEFAULT_JAVA_VERSION : javaVersion;
287-
if (withoutSemantic) {
288-
visitorsBridge = new VisitorsBridgeForTests(visitors, sonarComponents, actualVersion);
289-
} else {
286+
VisitorsBridgeForTests.Builder visitorsBridgeBuilder = new VisitorsBridgeForTests.Builder(visitors)
287+
.withJavaVersion(actualVersion)
288+
.withSonarComponents(sonarComponents)
289+
.withAndroidContext(inAndroidContext);
290+
if (!withoutSemantic) {
290291
List<File> actualClasspath = classpath == null ? TestClasspathUtils.DEFAULT_MODULE.getClassPath() : classpath;
291-
visitorsBridge = new VisitorsBridgeForTests(visitors, actualClasspath, sonarComponents, actualVersion);
292+
visitorsBridgeBuilder.enableSemanticWithProjectClasspath(actualClasspath);
292293
}
294+
VisitorsBridgeForTests visitorsBridge = visitorsBridgeBuilder.build();
293295

294296
JavaAstScanner astScanner = new JavaAstScanner(sonarComponents);
295-
visitorsBridge.setInAndroidContext(inAndroidContext);
296297
astScanner.setVisitorBridge(visitorsBridge);
297298

298299
List<InputFile> filesToParse = files;

java-checks-testkit/src/main/java/org/sonar/java/checks/verifier/internal/JavaCheckVerifier.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -99,16 +99,16 @@ private MultiFileVerifier createVerifier() {
9999
CommentLinesVisitor commentLinesVisitor = new CommentLinesVisitor();
100100
visitors.add(commentLinesVisitor);
101101
SonarComponents sonarComponents = CheckVerifierUtils.sonarComponents(isCacheEnabled, readCache, writeCache, rootDirectory);
102-
VisitorsBridgeForTests visitorsBridge;
103-
if (withoutSemantic) {
104-
visitorsBridge = new VisitorsBridgeForTests(visitors, sonarComponents, actualVersion);
105-
} else {
106-
visitorsBridge = new VisitorsBridgeForTests(visitors, actualClasspath, sonarComponents, actualVersion);
102+
VisitorsBridgeForTests.Builder visitorsBridgeBuilder = new VisitorsBridgeForTests.Builder(visitors)
103+
.withJavaVersion(actualVersion)
104+
.withSonarComponents(sonarComponents)
105+
.withAndroidContext(inAndroidContext);
106+
if(!withoutSemantic) {
107+
visitorsBridgeBuilder.enableSemanticWithProjectClasspath(actualClasspath);
107108
}
108109

109110
JavaAstScanner astScanner = new JavaAstScanner(sonarComponents);
110-
visitorsBridge.setInAndroidContext(inAndroidContext);
111-
111+
VisitorsBridgeForTests visitorsBridge = visitorsBridgeBuilder.build();
112112
astScanner.setVisitorBridge(visitorsBridge);
113113

114114
List<InputFile> filesToParse = files;

java-checks/src/test/java/org/sonar/java/checks/ParsingErrorCheckTest.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,9 @@ void test() {
3636
SonarComponents sonarComponents = mock(SonarComponents.class);
3737
when(sonarComponents.inputFileContents(any())).thenCallRealMethod();
3838

39-
VisitorsBridgeForTests visitorsBridge = new VisitorsBridgeForTests(new ParsingErrorCheck(), sonarComponents);
39+
VisitorsBridgeForTests visitorsBridge = new VisitorsBridgeForTests.Builder(new ParsingErrorCheck())
40+
.withSonarComponents(sonarComponents)
41+
.build();
4042
JavaAstScanner.scanSingleFileForTests(TestUtils.inputFile("src/test/files/checks/parsing/ParsingError.java"), visitorsBridge);
4143
Set<AnalyzerMessage> issues = visitorsBridge.lastCreatedTestContext().getIssues();
4244
assertThat(issues).hasSize(1);
@@ -54,7 +56,9 @@ void javacEmptyStatementsInImportsBug() {
5456
SonarComponents sonarComponents = mock(SonarComponents.class);
5557
when(sonarComponents.inputFileContents(any())).thenCallRealMethod();
5658

57-
VisitorsBridgeForTests visitorsBridge = new VisitorsBridgeForTests(new ParsingErrorCheck(), sonarComponents);
59+
VisitorsBridgeForTests visitorsBridge = new VisitorsBridgeForTests.Builder(new ParsingErrorCheck())
60+
.withSonarComponents(sonarComponents)
61+
.build();
5862
JavaAstScanner.scanSingleFileForTests(TestUtils.inputFile("src/test/files/checks/parsing/EmptyStatementsInImportsBug.java"), visitorsBridge);
5963
Set<AnalyzerMessage> issues = visitorsBridge.lastCreatedTestContext().getIssues();
6064
assertThat(issues).hasSize(1);

java-checks/src/test/java/org/sonar/java/filters/AnyRuleIssueFilterTest.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
import org.sonar.api.scan.issue.filter.FilterableIssue;
2727
import org.sonar.java.ast.JavaAstScanner;
2828
import org.sonar.java.checks.verifier.TestUtils;
29-
import org.sonar.java.model.JavaVersionImpl;
3029
import org.sonar.java.testing.VisitorsBridgeForTests;
3130
import org.sonar.plugins.java.api.location.Range;
3231
import org.sonar.plugins.java.api.tree.SyntaxToken;
@@ -132,7 +131,10 @@ private AbstractBooleanAssert<?> assertThatIssueWillBeAccepted(@Nullable Integer
132131
}
133132

134133
private static void scanFile(JavaIssueFilter filter) {
135-
VisitorsBridgeForTests visitorsBridge = new VisitorsBridgeForTests(Collections.singletonList(filter), Collections.emptyList(), null, new JavaVersionImpl());
134+
VisitorsBridgeForTests visitorsBridge =
135+
new VisitorsBridgeForTests.Builder(filter)
136+
.enableSemanticWithProjectClasspath(Collections.emptyList())
137+
.build();
136138
JavaAstScanner.scanSingleFileForTests(INPUT_FILE, visitorsBridge);
137139
}
138140

java-checks/src/test/java/org/sonar/java/filters/BaseTreeVisitorIssueFilterTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,7 @@ private static class FakeRuleWithoutKey implements JavaCheck {
176176
}
177177

178178
private static void scanFile(JavaIssueFilter filter) {
179-
VisitorsBridgeForTests visitorsBridge = new VisitorsBridgeForTests(Collections.singletonList(filter), Collections.emptyList(), null, new JavaVersionImpl());
179+
VisitorsBridgeForTests visitorsBridge = new VisitorsBridgeForTests.Builder(filter).build();
180180
JavaAstScanner.scanSingleFileForTests(INPUT_FILE, visitorsBridge);
181181
}
182182
}

java-checks/src/test/java/org/sonar/java/filters/FilterVerifier.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@
4141
import org.sonar.java.ast.visitors.SubscriptionVisitor;
4242
import org.sonar.java.checks.verifier.CheckVerifier;
4343
import org.sonar.java.checks.verifier.TestUtils;
44-
import org.sonar.java.model.JavaVersionImpl;
4544
import org.sonar.java.model.LineUtils;
4645
import org.sonar.java.reporting.AnalyzerMessage;
4746
import org.sonar.java.testing.JavaFileScannerContextForTests;
@@ -81,12 +80,12 @@ public void verify(String filename, JavaIssueFilter filter, JavaCheck... extraJa
8180
projectClasspath.add(new File("target/test-classes"));
8281

8382
InputFile inputFile = TestUtils.inputFile(filename);
84-
VisitorsBridgeForTests visitorsBridge;
85-
if (this.withoutSemantic) {
86-
visitorsBridge = new VisitorsBridgeForTests(visitors, sonarComponents(inputFile), new JavaVersionImpl());
87-
} else {
88-
visitorsBridge = new VisitorsBridgeForTests(visitors, projectClasspath, sonarComponents(inputFile), new JavaVersionImpl());
83+
VisitorsBridgeForTests.Builder visitorsBridgeBuilder = new VisitorsBridgeForTests.Builder(visitors)
84+
.withSonarComponents(sonarComponents(inputFile));
85+
if (!this.withoutSemantic) {
86+
visitorsBridgeBuilder.enableSemanticWithProjectClasspath(projectClasspath);
8987
}
88+
VisitorsBridgeForTests visitorsBridge = visitorsBridgeBuilder.build();
9089
JavaAstScanner.scanSingleFileForTests(inputFile, visitorsBridge);
9190
JavaFileScannerContextForTests testJavaFileScannerContext = visitorsBridge.lastCreatedTestContext();
9291

java-frontend/src/main/java/org/sonar/java/model/VisitorsBridge.java

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,7 @@ public class VisitorsBridge {
7575
protected InputFile currentFile;
7676
protected final JavaVersion javaVersion;
7777
private final List<File> classpath;
78-
// `inAndroidContext` should be made private final
79-
protected boolean inAndroidContext = false;
78+
protected final boolean inAndroidContext;
8079
private int fullyScannedFileCount = 0;
8180
private int skippedFileCount = 0;
8281
@VisibleForTesting
@@ -85,29 +84,28 @@ public class VisitorsBridge {
8584

8685
@VisibleForTesting
8786
public VisitorsBridge(JavaFileScanner visitor) {
88-
this(Collections.singletonList(visitor), new ArrayList<>(), null, new JavaVersionImpl());
87+
this(Collections.singletonList(visitor), new ArrayList<>(), null, new JavaVersionImpl(), false);
8988
}
9089

9190
@VisibleForTesting
9291
public VisitorsBridge(Iterable<? extends JavaCheck> visitors, List<File> projectClasspath, @Nullable SonarComponents sonarComponents) {
93-
this(visitors, projectClasspath, sonarComponents, new JavaVersionImpl());
92+
this(visitors, projectClasspath, sonarComponents, new JavaVersionImpl(), false);
9493
}
9594

96-
public VisitorsBridge(Iterable<? extends JavaCheck> visitors, List<File> projectClasspath, @Nullable SonarComponents sonarComponents, JavaVersion javaVersion,
97-
boolean inAndroidContext) {
98-
this(visitors, projectClasspath, sonarComponents, javaVersion);
99-
setInAndroidContext(inAndroidContext);
95+
public VisitorsBridge(Iterable<? extends JavaCheck> visitors, List<File> projectClasspath, @Nullable SonarComponents sonarComponents, JavaVersion javaVersion) {
96+
this(visitors, projectClasspath, sonarComponents, javaVersion, false);
10097
}
10198

102-
public VisitorsBridge(Iterable<? extends JavaCheck> visitors, List<File> projectClasspath, @Nullable SonarComponents sonarComponents, JavaVersion javaVersion) {
99+
public VisitorsBridge(Iterable<? extends JavaCheck> visitors, List<File> projectClasspath, @Nullable SonarComponents sonarComponents, JavaVersion javaVersion,
100+
boolean inAndroidContext) {
103101
this.visitors = visitors;
104102
this.allScanners = new ArrayList<>();
105103
this.scannersThatCannotBeSkipped = new ArrayList<>();
106104
this.classpath = projectClasspath;
107105
this.sonarComponents = sonarComponents;
108106
this.cacheContext = CacheContextImpl.of(sonarComponents);
109-
110107
this.javaVersion = javaVersion;
108+
this.inAndroidContext = inAndroidContext;
111109
dependencyService = new DependencyVersionInference();
112110
updateScanners();
113111
}
@@ -180,10 +178,6 @@ public List<File> getClasspath() {
180178
return classpath;
181179
}
182180

183-
public void setInAndroidContext(boolean inAndroidContext) {
184-
this.inAndroidContext = inAndroidContext;
185-
}
186-
187181
public void setCacheContext(CacheContext cacheContext) {
188182
this.cacheContext = cacheContext;
189183
}

java-frontend/src/main/java/org/sonar/java/testing/VisitorsBridgeForTests.java

Lines changed: 53 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@
2424
import org.sonar.java.SonarComponents;
2525
import org.sonar.java.annotations.VisibleForTesting;
2626
import org.sonar.java.model.JavaVersionImpl;
27-
import org.sonar.plugins.java.api.semantic.Sema;
2827
import org.sonar.java.model.VisitorsBridge;
2928
import org.sonar.plugins.java.api.InputFileScannerContext;
3029
import org.sonar.plugins.java.api.JavaCheck;
@@ -33,27 +32,70 @@
3332
import org.sonar.plugins.java.api.JavaVersion;
3433
import org.sonar.plugins.java.api.ModuleScannerContext;
3534
import org.sonar.plugins.java.api.caching.CacheContext;
35+
import org.sonar.plugins.java.api.semantic.Sema;
3636
import org.sonar.plugins.java.api.tree.CompilationUnitTree;
3737

3838
public class VisitorsBridgeForTests extends VisitorsBridge {
3939

4040
private JavaFileScannerContextForTests testContext;
4141
private JavaFileScannerContextForTests moduleContext;
42-
private boolean enableSemantic = true;
43-
42+
private final boolean enableSemantic;
4443

45-
@VisibleForTesting
46-
public VisitorsBridgeForTests(JavaFileScanner visitor, SonarComponents sonarComponents) {
47-
this(Collections.singletonList(visitor), Collections.emptyList(), sonarComponents, new JavaVersionImpl());
44+
private VisitorsBridgeForTests(Builder builder) {
45+
super(builder.visitors, builder.projectClasspath, builder.sonarComponents, builder.javaVersion, builder.inAndroidContext);
46+
this.enableSemantic = builder.enableSemantic;
4847
}
4948

50-
public VisitorsBridgeForTests(Iterable<? extends JavaCheck> visitors, @Nullable SonarComponents sonarComponents, JavaVersion javaVersion) {
51-
super(visitors, Collections.emptyList(), sonarComponents, javaVersion);
52-
enableSemantic = false;
49+
public static class Builder {
50+
Iterable<? extends JavaCheck> visitors;
51+
SonarComponents sonarComponents;
52+
JavaVersion javaVersion;
53+
List<File> projectClasspath;
54+
boolean enableSemantic;
55+
boolean inAndroidContext;
56+
57+
public Builder(JavaFileScanner visitor) {
58+
this(Collections.singletonList(visitor));
59+
}
60+
61+
public Builder(Iterable<? extends JavaCheck> visitors) {
62+
this.visitors = visitors;
63+
this.sonarComponents = null;
64+
this.javaVersion = new JavaVersionImpl();
65+
this.projectClasspath = Collections.emptyList();
66+
this.enableSemantic = false;
67+
this.inAndroidContext = false;
68+
}
69+
70+
public Builder withJavaVersion(JavaVersion javaVersion) {
71+
this.javaVersion = javaVersion;
72+
return this;
73+
}
74+
75+
public Builder withSonarComponents(SonarComponents sonarComponents) {
76+
this.sonarComponents = sonarComponents;
77+
return this;
78+
}
79+
80+
public Builder enableSemanticWithProjectClasspath(List<File> projectClasspath) {
81+
this.projectClasspath = projectClasspath;
82+
this.enableSemantic = true;
83+
return this;
84+
}
85+
86+
public Builder withAndroidContext(boolean inAndroidContext) {
87+
this.inAndroidContext = inAndroidContext;
88+
return this;
89+
}
90+
91+
public VisitorsBridgeForTests build() {
92+
return new VisitorsBridgeForTests(this);
93+
}
5394
}
5495

55-
public VisitorsBridgeForTests(Iterable<? extends JavaCheck> visitors, List<File> projectClasspath, @Nullable SonarComponents sonarComponents, JavaVersion javaVersion) {
56-
super(visitors, projectClasspath, sonarComponents, javaVersion);
96+
@VisibleForTesting
97+
boolean inAndroidContext() {
98+
return inAndroidContext;
5799
}
58100

59101
@Override

java-frontend/src/test/java/org/sonar/java/testing/VisitorsBridgeForTestsTest.java

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.sonar.java.testing;
1818

1919
import java.io.File;
20+
import java.util.ArrayList;
2021
import java.util.Collections;
2122
import org.junit.jupiter.api.Test;
2223
import org.sonar.api.batch.fs.InputFile;
@@ -46,13 +47,18 @@ void test_semantic_disabled() {
4647
sonarComponents.setSensorContext(context);
4748

4849
Tree parse = JParserTestUtils.parse("class A{}");
49-
VisitorsBridgeForTests visitorsBridgeForTests = new VisitorsBridgeForTests(Collections.singletonList(new DummyVisitor()), sonarComponents, new JavaVersionImpl());
50+
VisitorsBridgeForTests visitorsBridgeForTests = new VisitorsBridgeForTests.Builder(new DummyVisitor())
51+
.withSonarComponents(sonarComponents)
52+
.build();
5053
visitorsBridgeForTests.setCurrentFile(TestUtils.emptyInputFile("dummy.java"));
5154
visitorsBridgeForTests.visitFile(parse, false);
5255
assertThat(visitorsBridgeForTests.lastCreatedTestContext().getSemanticModel()).isNull();
5356

5457
parse = JParserTestUtils.parse("class A{}");
55-
visitorsBridgeForTests = new VisitorsBridgeForTests(new DummyVisitor(), sonarComponents);
58+
visitorsBridgeForTests = new VisitorsBridgeForTests.Builder(new DummyVisitor())
59+
.withSonarComponents(sonarComponents)
60+
.enableSemanticWithProjectClasspath(new ArrayList<>())
61+
.build();
5662
visitorsBridgeForTests.setCurrentFile(TestUtils.emptyInputFile("dummy.java"));
5763
visitorsBridgeForTests.visitFile(parse, false);
5864
assertThat(visitorsBridgeForTests.lastCreatedTestContext().getSemanticModel()).isNotNull();
@@ -66,7 +72,9 @@ void test_report_with_analysis_message() {
6672

6773
Tree parse = JParserTestUtils.parse("class A{}");
6874
DummyVisitor javaCheck = new DummyVisitor();
69-
VisitorsBridgeForTests visitorsBridgeForTests = new VisitorsBridgeForTests(Collections.singletonList(javaCheck), sonarComponents, new JavaVersionImpl());
75+
VisitorsBridgeForTests visitorsBridgeForTests = new VisitorsBridgeForTests.Builder(javaCheck)
76+
.withSonarComponents(sonarComponents)
77+
.build();
7078
visitorsBridgeForTests.setCurrentFile(TestUtils.emptyInputFile("dummy.java"));
7179
visitorsBridgeForTests.visitFile(parse, false);
7280
JavaFileScannerContextForTests lastContext = visitorsBridgeForTests.lastCreatedTestContext();
@@ -88,7 +96,9 @@ void create_InputFileScannerContext_also_sets_testContext_field() {
8896
SonarComponents sonarComponents = new SonarComponents(null, context.fileSystem(), null, null, null, null);
8997
sonarComponents.setSensorContext(context);
9098
DummyVisitor javaCheck = new DummyVisitor();
91-
VisitorsBridgeForTests visitorsBridgeForTests = new VisitorsBridgeForTests(Collections.singletonList(javaCheck), sonarComponents, new JavaVersionImpl());
99+
VisitorsBridgeForTests visitorsBridgeForTests = new VisitorsBridgeForTests.Builder(javaCheck)
100+
.withSonarComponents(sonarComponents)
101+
.build();
92102
var inputFile = mock(InputFile.class);
93103

94104
var expectedTestContext =
@@ -99,7 +109,9 @@ void create_InputFileScannerContext_also_sets_testContext_field() {
99109

100110
@Test
101111
void lastCreatedModuleContext_returns_last_created_module_context() {
102-
var bridge = new VisitorsBridgeForTests(Collections.emptyList(), mock(SonarComponents.class), new JavaVersionImpl());
112+
var bridge = new VisitorsBridgeForTests.Builder(Collections.emptyList())
113+
.withSonarComponents(mock(SonarComponents.class))
114+
.build();
103115
var firstModuleContext = bridge.createScannerContext(null, new JavaVersionImpl(), false, null);
104116
var secondAndExpectedModuleContext = bridge.createScannerContext(null, new JavaVersionImpl(), false, null);
105117
var firstTestContext = bridge.createScannerContext((CompilationUnitTree) null, null, null, false);
@@ -112,6 +124,17 @@ void lastCreatedModuleContext_returns_last_created_module_context() {
112124
.isNotSameAs(secondTestContext);
113125
}
114126

127+
@Test
128+
void test_builder() {
129+
VisitorsBridgeForTests visitorsBridge =
130+
new VisitorsBridgeForTests.Builder(Collections.emptyList())
131+
.withJavaVersion(JavaVersionImpl.fromString("17"))
132+
.withAndroidContext(true)
133+
.build();
134+
assertThat(visitorsBridge.getJavaVersion().asInt()).isEqualTo(17);
135+
assertThat(visitorsBridge.inAndroidContext()).isTrue();
136+
}
137+
115138
private static class DummyVisitor implements JavaFileScanner {
116139
@Override
117140
public void scanFile(JavaFileScannerContext context) {

java-frontend/src/test/java/org/sonar/plugins/java/api/IssuableSubscriptionVisitorTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class IssuableSubscriptionVisitorTest {
3838

3939
@Test
4040
void test_custom_rules_report_issues() {
41-
VisitorsBridgeForTests visitorsBridge = new VisitorsBridgeForTests(Collections.singletonList(new CustomRule()), new ArrayList<>(), null, new JavaVersionImpl());
41+
VisitorsBridgeForTests visitorsBridge = new VisitorsBridgeForTests.Builder(new CustomRule()).build();
4242
JavaAstScanner.scanSingleFileForTests(TestUtils.inputFile("src/test/resources/IssuableSubscriptionClass.java"), visitorsBridge);
4343
Set<AnalyzerMessage> issues = visitorsBridge.lastCreatedTestContext().getIssues();
4444
assertThat(issues).hasSize(8);

0 commit comments

Comments
 (0)