1 package org.codehaus.plexus.compiler;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 import javax.inject.Inject;
27
28 import java.io.File;
29 import java.util.ArrayList;
30 import java.util.Collection;
31 import java.util.Collections;
32 import java.util.Iterator;
33 import java.util.List;
34 import java.util.Map;
35 import java.util.stream.Collectors;
36
37 import org.apache.maven.RepositoryUtils;
38 import org.apache.maven.artifact.Artifact;
39 import org.apache.maven.artifact.DefaultArtifact;
40 import org.apache.maven.artifact.handler.DefaultArtifactHandler;
41 import org.apache.maven.artifact.versioning.VersionRange;
42 import org.codehaus.plexus.testing.PlexusTest;
43 import org.codehaus.plexus.util.FileUtils;
44 import org.codehaus.plexus.util.StringUtils;
45 import org.eclipse.aether.DefaultRepositorySystemSession;
46 import org.eclipse.aether.RepositorySystemSession;
47 import org.eclipse.aether.impl.LocalRepositoryProvider;
48 import org.eclipse.aether.repository.LocalRepository;
49 import org.eclipse.aether.repository.LocalRepositoryManager;
50 import org.hamcrest.io.FileMatchers;
51 import org.junit.jupiter.api.BeforeEach;
52 import org.junit.jupiter.api.Test;
53
54 import static org.hamcrest.MatcherAssert.assertThat;
55 import static org.hamcrest.Matchers.containsInAnyOrder;
56 import static org.hamcrest.Matchers.is;
57 import static org.hamcrest.Matchers.notNullValue;
58
59
60
61
62 @PlexusTest
63 public abstract class AbstractCompilerTest {
64 private boolean compilerDebug = false;
65
66 private boolean compilerDeprecationWarnings = false;
67
68 private boolean forceJavacCompilerUse = false;
69
70 @Inject
71 private Map<String, Compiler> compilers;
72
73 @Inject
74 private LocalRepositoryProvider localRepositoryProvider;
75
76 private LocalRepositoryManager localRepositoryManager;
77
78 protected abstract String getRoleHint();
79
80 @BeforeEach
81 final void setUpLocalRepo() throws Exception {
82 String localRepo = System.getProperty("maven.repo.local");
83 assertThat("system property maven.repo.local", localRepo, notNullValue());
84
85 LocalRepository localRepository = new LocalRepository(localRepo);
86 assertThat(
87 "test prerequisite: local repository path: " + localRepository.getBasedir(),
88 localRepository.getBasedir(),
89 FileMatchers.aReadableFile());
90
91 RepositorySystemSession session = new DefaultRepositorySystemSession();
92 localRepositoryManager = localRepositoryProvider.newLocalRepositoryManager(session, localRepository);
93 }
94
95 protected void setCompilerDebug(boolean flag) {
96 compilerDebug = flag;
97 }
98
99 protected void setCompilerDeprecationWarnings(boolean flag) {
100 compilerDeprecationWarnings = flag;
101 }
102
103 public void setForceJavacCompilerUse(boolean forceJavacCompilerUse) {
104 this.forceJavacCompilerUse = forceJavacCompilerUse;
105 }
106
107 protected final Compiler getCompiler() {
108 return compilers.get(getRoleHint());
109 }
110
111 protected List<String> getClasspath() throws Exception {
112 List<String> cp = new ArrayList<>();
113
114 File file = getLocalArtifactPath("commons-lang", "commons-lang", "2.0", "jar");
115
116 assertThat(
117 "test prerequisite: commons-lang library must be available in local repository at " + file,
118 file,
119 FileMatchers.aReadableFile());
120
121 cp.add(file.getAbsolutePath());
122
123 return cp;
124 }
125
126 protected void configureCompilerConfig(CompilerConfiguration compilerConfig) {}
127
128 @Test
129 public void testCompilingSources() throws Exception {
130 List<CompilerMessage> messages = new ArrayList<>();
131 Collection<String> files = new ArrayList<>();
132
133 for (CompilerConfiguration compilerConfig : getCompilerConfigurations()) {
134 File outputDir = new File(compilerConfig.getOutputLocation());
135
136 messages.addAll(getCompiler().performCompile(compilerConfig).getCompilerMessages());
137
138 if (outputDir.isDirectory()) {
139 files.addAll(normalizePaths(FileUtils.getFileNames(outputDir, null, null, false)));
140 }
141 }
142
143 int numCompilerErrors = compilerErrorCount(messages);
144
145 int numCompilerWarnings = messages.size() - numCompilerErrors;
146
147 int expectedErrors = expectedErrors();
148
149 if (expectedErrors != numCompilerErrors) {
150 System.out.println(numCompilerErrors + " error(s) found:");
151 List<String> errors = new ArrayList<>();
152 for (CompilerMessage error : messages) {
153 if (!error.isError()) {
154 continue;
155 }
156
157 System.out.println("----");
158 System.out.println(error.getFile());
159 System.out.println(error.getMessage());
160 System.out.println("----");
161 errors.add(error.getMessage());
162 }
163
164 assertThat(
165 "Wrong number of compilation errors (" + numCompilerErrors + "/" + expectedErrors
166 + ") : " + displayLines(errors),
167 numCompilerErrors,
168 is(expectedErrors));
169 }
170
171 int expectedWarnings = expectedWarnings();
172 if (expectedWarnings != numCompilerWarnings) {
173 List<String> warnings = new ArrayList<>();
174 System.out.println(numCompilerWarnings + " warning(s) found:");
175 for (CompilerMessage error : messages) {
176 if (error.isError()) {
177 continue;
178 }
179
180 System.out.println("----");
181 System.out.println(error.getFile());
182 System.out.println(error.getMessage());
183 System.out.println("----");
184 warnings.add(error.getMessage());
185 }
186
187 assertThat(
188 "Wrong number ("
189 + numCompilerWarnings + "/" + expectedWarnings + ") of compilation warnings: "
190 + displayLines(warnings),
191 numCompilerWarnings,
192 is(expectedWarnings));
193 }
194
195 assertThat(
196 files, containsInAnyOrder(normalizePaths(expectedOutputFiles()).toArray(new String[0])));
197 }
198
199 protected String displayLines(List<String> warnings) {
200
201 StringBuilder sb = new StringBuilder(System.lineSeparator());
202 for (String warning : warnings) {
203 sb.append('-').append(warning).append(System.lineSeparator());
204 }
205 return sb.toString();
206 }
207
208 private List<CompilerConfiguration> getCompilerConfigurations() throws Exception {
209 String sourceDir = "src/test-input/src/main";
210
211 List<String> filenames = FileUtils.getFileNames(new File(sourceDir), "**/*.java", null, false, true);
212 Collections.sort(filenames);
213
214 List<CompilerConfiguration> compilerConfigurations = new ArrayList<>();
215
216 int index = 0;
217 for (Iterator<String> it = filenames.iterator(); it.hasNext(); index++) {
218 String filename = it.next();
219
220 CompilerConfiguration compilerConfig = new CompilerConfiguration();
221
222 compilerConfig.setDebug(compilerDebug);
223
224 compilerConfig.setShowDeprecation(compilerDeprecationWarnings);
225
226 compilerConfig.setClasspathEntries(getClasspath());
227
228 compilerConfig.addSourceLocation(sourceDir);
229
230 compilerConfig.setOutputLocation("target/" + getRoleHint() + "/classes-" + index);
231
232 FileUtils.deleteDirectory(compilerConfig.getOutputLocation());
233
234 compilerConfig.addInclude(filename);
235
236 compilerConfig.setForceJavacCompilerUse(this.forceJavacCompilerUse);
237
238 configureCompilerConfig(compilerConfig);
239
240 String target = getTargetVersion();
241 if (StringUtils.isNotEmpty(target)) {
242 compilerConfig.setTargetVersion(target);
243 }
244
245 String source = getSourceVersion();
246 if (StringUtils.isNotEmpty(source)) {
247 compilerConfig.setSourceVersion(source);
248 }
249
250 compilerConfigurations.add(compilerConfig);
251 }
252
253 return compilerConfigurations;
254 }
255
256 public String getTargetVersion() {
257 return null;
258 }
259
260 public String getSourceVersion() {
261 return null;
262 }
263
264 private List<String> normalizePaths(Collection<String> relativePaths) {
265 return relativePaths.stream()
266 .map(s -> s.replace(File.separatorChar, '/'))
267 .collect(Collectors.toList());
268 }
269
270 protected int compilerErrorCount(List<CompilerMessage> messages) {
271 int count = 0;
272
273 for (CompilerMessage message : messages) {
274 count += message.isError() ? 1 : 0;
275 }
276
277 return count;
278 }
279
280 protected int expectedErrors() {
281 return 1;
282 }
283
284 protected int expectedWarnings() {
285 return 0;
286 }
287
288 protected Collection<String> expectedOutputFiles() {
289 return Collections.emptyList();
290 }
291
292 protected File getLocalArtifactPath(String groupId, String artifactId, String version, String type) {
293 VersionRange versionRange = VersionRange.createFromVersion(version);
294
295 Artifact artifact = new DefaultArtifact(
296 groupId,
297 artifactId,
298 versionRange,
299 Artifact.SCOPE_COMPILE,
300 type,
301 null,
302 new DefaultArtifactHandler(type));
303
304 return getLocalArtifactPath(artifact);
305 }
306
307 protected String getJavaVersion() {
308
309 String javaVersion = System.getProperty("java.version");
310 String realJavaVersion = javaVersion;
311
312 int dotIdx = javaVersion.indexOf(".");
313 if (dotIdx > -1) {
314 int lastDot = dotIdx;
315
316
317 dotIdx = javaVersion.indexOf(".", lastDot + 1);
318 if (dotIdx > lastDot) {
319 javaVersion = javaVersion.substring(0, dotIdx);
320 }
321 }
322
323 System.out.println("java.version is: " + realJavaVersion + "\ntrimmed java version is: " + javaVersion
324 + "\ncomparison: \"1.5\".compareTo( \"" + javaVersion + "\" ) == " + ("1.5".compareTo(javaVersion))
325 + "\n");
326
327 return javaVersion;
328 }
329
330 protected File getLocalArtifactPath(Artifact artifact) {
331 return new File(
332 localRepositoryManager.getRepository().getBasedir(),
333 localRepositoryManager.getPathForLocalArtifact(RepositoryUtils.toArtifact(artifact)));
334 }
335 }