Skip to content

Commit 041cf7e

Browse files
SONARJAVA-5830 Implement internal classpath resolution API
1 parent bc26dd9 commit 041cf7e

File tree

4 files changed

+117
-3
lines changed

4 files changed

+117
-3
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
/*
2+
* SonarQube Java
3+
* Copyright (C) 2012-2025 SonarSource SA
4+
* mailto:info AT sonarsource DOT com
5+
*
6+
* This program is free software; you can redistribute it and/or
7+
* modify it under the terms of the Sonar Source-Available License Version 1, as published by SonarSource SA.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12+
* See the Sonar Source-Available License for more details.
13+
*
14+
* You should have received a copy of the Sonar Source-Available License
15+
* along with this program; if not, see https://sonarsource.com/license/ssal/
16+
*/
17+
package org.sonar.java;
18+
19+
import java.io.File;
20+
import java.nio.file.Path;
21+
import java.util.HashSet;
22+
import java.util.List;
23+
import java.util.stream.Stream;
24+
import org.sonar.plugins.java.api.internal.ClasspathResolver;
25+
import org.sonar.plugins.java.api.internal.ResolvedClasspath;
26+
27+
public class DefaultClassPathResolver implements ClasspathResolver {
28+
private SonarComponents sonarComponents;
29+
30+
public DefaultClassPathResolver(SonarComponents sonarComponents) {
31+
this.sonarComponents = sonarComponents;
32+
}
33+
34+
@Override
35+
public ResolvedClasspath mainClasspath() {
36+
return new ResolvedClasspathImpl(SonarComponentsAdapter.forMainSources(sonarComponents));
37+
}
38+
39+
@Override
40+
public ResolvedClasspath testClasspath() {
41+
return new ResolvedClasspathImpl(SonarComponentsAdapter.forTestSources(sonarComponents));
42+
}
43+
44+
private interface SonarComponentsAdapter {
45+
List<File> binaries();
46+
47+
List<File> classpath();
48+
49+
static SonarComponentsAdapter forMainSources(SonarComponents sonarComponents) {
50+
return new SonarComponentsAdapter() {
51+
@Override
52+
public List<File> binaries() {
53+
return sonarComponents.getCompilationOutput();
54+
}
55+
56+
@Override
57+
public List<File> classpath() {
58+
return sonarComponents.getJavaClasspath();
59+
}
60+
};
61+
}
62+
63+
static SonarComponentsAdapter forTestSources(SonarComponents sonarComponents) {
64+
return new SonarComponentsAdapter() {
65+
@Override
66+
public List<File> binaries() {
67+
return sonarComponents.getTestCompilationOutput();
68+
}
69+
70+
@Override
71+
public List<File> classpath() {
72+
return sonarComponents.getJavaTestClasspath();
73+
}
74+
};
75+
}
76+
}
77+
78+
static class ResolvedClasspathImpl implements ResolvedClasspath {
79+
private final List<Path> binaries;
80+
private final List<Path> libraries;
81+
82+
ResolvedClasspathImpl(SonarComponentsAdapter sonarComponentsAdapter) {
83+
binaries = toPaths(sonarComponentsAdapter.binaries()).toList();
84+
var binariesSet = new HashSet<>(binaries);
85+
86+
libraries = toPaths(sonarComponentsAdapter.classpath())
87+
.filter(classpathEntry -> !binariesSet.contains(classpathEntry))
88+
.toList();
89+
}
90+
91+
@Override
92+
public List<Path> sonarJavaBinaries() {
93+
return binaries;
94+
}
95+
96+
@Override
97+
public List<Path> sonarJavaLibraries() {
98+
return libraries;
99+
}
100+
101+
private static Stream<Path> toPaths(List<File> files) {
102+
return files.stream().map(File::toPath);
103+
}
104+
}
105+
}

java-frontend/src/main/java/org/sonar/java/SonarComponents.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -251,6 +251,10 @@ public NewHighlighting highlightableFor(InputFile inputFile) {
251251
return context.newHighlighting().onFile(inputFile);
252252
}
253253

254+
public List<File> getCompilationOutput() {
255+
return javaClasspath.getBinaryDirs();
256+
}
257+
254258
public List<File> getJavaClasspath() {
255259
if (javaClasspath == null) {
256260
return new ArrayList<>();
@@ -262,6 +266,10 @@ public boolean inAndroidContext() {
262266
return javaClasspath.inAndroidContext();
263267
}
264268

269+
public List<File> getTestCompilationOutput() {
270+
return javaTestClasspath.getBinaryDirs();
271+
}
272+
265273
public List<File> getJavaTestClasspath() {
266274
return javaTestClasspath.getElements();
267275
}

sonar-java-plugin/src/main/java/org/sonar/plugins/java/JavaPlugin.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
import org.sonar.api.SonarProduct;
2828
import org.sonar.api.config.PropertyDefinition;
2929
import org.sonar.java.AnalysisWarningsWrapper;
30+
import org.sonar.java.DefaultClassPathResolver;
3031
import org.sonar.java.DefaultJavaResourceLocator;
3132
import org.sonar.java.JavaConstants;
3233
import org.sonar.java.SonarComponents;
@@ -62,6 +63,7 @@ public void define(Context context) {
6263
list.add(DroppedPropertiesSensor.class);
6364
list.add(JavaSonarWayProfile.class);
6465
list.add(ClasspathForMain.class);
66+
list.add(DefaultClassPathResolver.class);
6567

6668
ExternalReportExtensions.define(context);
6769
}

sonar-java-plugin/src/test/java/org/sonar/plugins/java/JavaPluginTest.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,14 +44,13 @@ void sonarLint_9_9_extensions() {
4444
.contains(SonarLintCache.class);
4545
}
4646

47-
4847
@Test
4948
void sonarqube_9_9_extensions() {
5049
SonarRuntime sqCommunity = SonarRuntimeImpl.forSonarQube(VERSION_9_9, SonarQubeSide.SCANNER, SonarEdition.COMMUNITY);
5150
Plugin.Context context = new Plugin.Context(sqCommunity);
5251
javaPlugin.define(context);
5352
assertThat(context.getExtensions())
54-
.hasSize(35)
53+
.hasSize(36)
5554
.doesNotContain(Jasper.class);
5655
}
5756

@@ -61,7 +60,7 @@ void sonarqube_9_9_commercial_extensions() {
6160
Plugin.Context context = new Plugin.Context(sqEnterprise);
6261
javaPlugin.define(context);
6362
assertThat(context.getExtensions())
64-
.hasSize(36)
63+
.hasSize(37)
6564
.contains(Jasper.class);
6665
}
6766

0 commit comments

Comments
 (0)