From f1553ab1d39b11e7cce8845371470fe519157c8b Mon Sep 17 00:00:00 2001 From: Ashley Scopes <73482956+ascopes@users.noreply.github.com> Date: Sat, 21 Jan 2023 12:35:22 +0000 Subject: [PATCH 1/2] Add ability to only run annotation processing/only run compilation --- .../jct/compilers/AbstractJctCompiler.java | 13 +++++ .../jct/compilers/CompilationMode.java | 53 +++++++++++++++++++ .../ascopes/jct/compilers/JctCompiler.java | 27 ++++++++++ .../ascopes/jct/compilers/JctFlagBuilder.java | 8 +++ .../javac/JavacJctFlagBuilderImpl.java | 20 +++++++ .../compilers/AbstractJctCompilerTest.java | 46 ++++++++++++++++ .../javac/JavacJctFlagBuilderImplTest.java | 47 ++++++++++++++++ 7 files changed, 214 insertions(+) create mode 100644 java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/CompilationMode.java diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/AbstractJctCompiler.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/AbstractJctCompiler.java index d6e0f100d..347937de8 100644 --- a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/AbstractJctCompiler.java +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/AbstractJctCompiler.java @@ -66,6 +66,7 @@ public abstract class AbstractJctCompiler> private boolean showWarnings; private boolean showDeprecationWarnings; private boolean failOnWarnings; + private CompilationMode compilationMode; private Locale locale; private Charset logCharset; private boolean verbose; @@ -104,6 +105,7 @@ protected AbstractJctCompiler( showWarnings = JctCompiler.DEFAULT_SHOW_WARNINGS; showDeprecationWarnings = JctCompiler.DEFAULT_SHOW_DEPRECATION_WARNINGS; failOnWarnings = JctCompiler.DEFAULT_FAIL_ON_WARNINGS; + compilationMode = JctCompiler.DEFAULT_COMPILATION_MODE; locale = JctCompiler.DEFAULT_LOCALE; logCharset = JctCompiler.DEFAULT_LOG_CHARSET; previewFeatures = JctCompiler.DEFAULT_PREVIEW_FEATURES; @@ -215,6 +217,17 @@ public A failOnWarnings(boolean enabled) { return myself(); } + @Override + public CompilationMode getCompilationMode() { + return compilationMode; + } + + @Override + public A compilationMode(CompilationMode compilationMode) { + this.compilationMode = compilationMode; + return myself(); + } + @Override public List getAnnotationProcessorOptions() { return List.copyOf(annotationProcessorOptions); diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/CompilationMode.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/CompilationMode.java new file mode 100644 index 000000000..82bdf1299 --- /dev/null +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/CompilationMode.java @@ -0,0 +1,53 @@ +/* + * Copyright (C) 2022 - 2023, the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package io.github.ascopes.jct.compilers; + +import org.apiguardian.api.API; +import org.apiguardian.api.API.Status; + +/** + * An enum representing the various types of compilation mode that a compiler can + * run under. + * + *

This corresponds to the {@code -proc} flag in the OpenJDK Javac implementation. + * + * @author Ashley Scopes + * @since 0.0.1 (0.0.1-M6) + */ +@API(since = "0.0.1", status = Status.STABLE) +public enum CompilationMode { + + /** + * Run compilation and run the annotation processors, if configured. + * + *

This is usually the default mode. + */ + COMPILATION_AND_ANNOTATION_PROCESSING, + + /** + * Run compilation, but skip any annotation processing that may run. + * + *

This corresponds to providing {@code -proc:none} in the OpenJDK Javac implementation. + */ + COMPILATION_ONLY, + + /** + * Skip compilation, but run any annotation processing that may be enabled. + * + *

This corresponds to providing {@code -proc:only} in the OpenJDK Javac implementation. + */ + ANNOTATION_PROCESSING_ONLY, +} diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/JctCompiler.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/JctCompiler.java index 83738cb4c..fb9c418a9 100644 --- a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/JctCompiler.java +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/JctCompiler.java @@ -111,6 +111,12 @@ public interface JctCompiler, R extends JctCompilati */ LoggingMode DEFAULT_DIAGNOSTIC_LOGGING_MODE = LoggingMode.ENABLED; + /** + * Default setting for the compilation mode to use + * ({@link CompilationMode#COMPILATION_AND_ANNOTATION_PROCESSING}). + */ + CompilationMode DEFAULT_COMPILATION_MODE = CompilationMode.COMPILATION_AND_ANNOTATION_PROCESSING; + /** * Default setting for how to apply annotation processor discovery when no processors are * explicitly defined ({@link AnnotationProcessorDiscovery#INCLUDE_DEPENDENCIES}). @@ -358,6 +364,27 @@ default C addCompilerOptions(String compilerOption, String... compilerOptions) { */ C failOnWarnings(boolean enabled); + /** + * Get the compilation mode that is in use. + * + *

Unless otherwise changed or specified, implementations should default to + * {@link #DEFAULT_COMPILATION_MODE}. + * + * @return the compilation mode. + */ + CompilationMode getCompilationMode(); + + /** + * Set the compilation mode to use for this compiler. + * + *

Unless otherwise changed or specified, implementations should default to + * {@link #DEFAULT_COMPILATION_MODE}. + * + * @param compilationMode the compilation mode to use. + * @return this compiler object for further call chaining. + */ + C compilationMode(CompilationMode compilationMode); + /** * Get the default release to use if no release or target version is specified. * diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/JctFlagBuilder.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/JctFlagBuilder.java index 5d4e489e7..75660361d 100644 --- a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/JctFlagBuilder.java +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/JctFlagBuilder.java @@ -62,6 +62,14 @@ public interface JctFlagBuilder { */ JctFlagBuilder failOnWarnings(boolean enabled); + /** + * Set the compilation mode to run under. + * + * @param compilationMode the compilation mode to run under. + * @return this builder. + */ + JctFlagBuilder compilationMode(CompilationMode compilationMode); + /** * Add deprecation warning preferences. * diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/javac/JavacJctFlagBuilderImpl.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/javac/JavacJctFlagBuilderImpl.java index 46aa1daff..66a5a37cd 100644 --- a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/javac/JavacJctFlagBuilderImpl.java +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/javac/JavacJctFlagBuilderImpl.java @@ -15,6 +15,7 @@ */ package io.github.ascopes.jct.compilers.javac; +import io.github.ascopes.jct.compilers.CompilationMode; import io.github.ascopes.jct.compilers.JctFlagBuilder; import java.util.ArrayList; import java.util.List; @@ -72,6 +73,25 @@ public JavacJctFlagBuilderImpl failOnWarnings(boolean enabled) { return addFlagIfTrue(enabled, WERROR); } + @Override + public JctFlagBuilder compilationMode(CompilationMode compilationMode) { + switch (compilationMode) { + case COMPILATION_ONLY: + craftedFlags.add("-proc:none"); + break; + + case ANNOTATION_PROCESSING_ONLY: + craftedFlags.add("-proc:only"); + break; + + default: + // Do nothing. The default behaviour is to allow this. + break; + } + + return this; + } + @Override public JavacJctFlagBuilderImpl showDeprecationWarnings(boolean enabled) { return addFlagIfTrue(enabled, DEPRECATION); diff --git a/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/compilers/AbstractJctCompilerTest.java b/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/compilers/AbstractJctCompilerTest.java index 7c4ce914d..4198ed177 100644 --- a/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/compilers/AbstractJctCompilerTest.java +++ b/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/compilers/AbstractJctCompilerTest.java @@ -29,6 +29,7 @@ import static org.mockito.Mockito.verifyNoMoreInteractions; import io.github.ascopes.jct.compilers.AbstractJctCompiler; +import io.github.ascopes.jct.compilers.CompilationMode; import io.github.ascopes.jct.compilers.JctCompiler; import io.github.ascopes.jct.compilers.JctCompilerConfigurer; import io.github.ascopes.jct.compilers.JctFlagBuilder; @@ -202,6 +203,14 @@ void constructorInitialisesFailOnWarningsToDefaultValue() { .isEqualTo(JctCompiler.DEFAULT_FAIL_ON_WARNINGS); } + @DisplayName("constructor initialises compilationMode to default value") + @Test + void constructorInitialisesCompilationModeToDefaultValue() { + // Then + assertThatCompilerField("compilationMode") + .isEqualTo(JctCompiler.DEFAULT_COMPILATION_MODE); + } + @DisplayName("constructor initialises locale to default value") @Test void constructorInitialisesLocaleToDefaultValue() { @@ -626,6 +635,43 @@ void failOnWarningsReturnsTheCompiler() { } } + @DisplayName(".isCompilationMode() returns the expected values") + @EnumSource(CompilationMode.class) + @ParameterizedTest(name = "for compilationMode = {0}") + void isCompilationModeReturnsExpectedValue(CompilationMode expected) { + // Given + setFieldOnCompiler("compilationMode", expected); + + // Then + assertThat(compiler.getCompilationMode()).isEqualTo(expected); + } + + @DisplayName("AbstractJctCompiler#compilationMode tests") + @Nested + class CompilationModeTests { + + @DisplayName(".compilationMode(...) sets the expected values") + @EnumSource(CompilationMode.class) + @ParameterizedTest(name = "for compilationMode = {0}") + void compilationModeSetsExpectedValue(CompilationMode expected) { + // When + compiler.compilationMode(expected); + + // Then + assertThatCompilerField("compilationMode").isEqualTo(expected); + } + + @DisplayName(".compilationMode(...) returns the compiler") + @Test + void compilationModeReturnsTheCompiler() { + // When + var result = compiler.compilationMode(CompilationMode.COMPILATION_AND_ANNOTATION_PROCESSING); + + // Then + assertThat(result).isSameAs(compiler); + } + } + @DisplayName(".getAnnotationProcessorOptions returns a copy of the expected value") @Test void getAnnotationProcessorOptionsReturnsCopyOfTheExpectedValue() { diff --git a/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/compilers/javac/JavacJctFlagBuilderImplTest.java b/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/compilers/javac/JavacJctFlagBuilderImplTest.java index 7b4f9ffc6..70e0f44e3 100644 --- a/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/compilers/javac/JavacJctFlagBuilderImplTest.java +++ b/java-compiler-testing/src/test/java/io/github/ascopes/jct/tests/unit/compilers/javac/JavacJctFlagBuilderImplTest.java @@ -20,6 +20,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +import io.github.ascopes.jct.compilers.CompilationMode; import io.github.ascopes.jct.compilers.javac.JavacJctFlagBuilderImpl; import io.github.ascopes.jct.tests.helpers.Fixtures; import java.util.List; @@ -33,6 +34,8 @@ import org.junit.jupiter.api.Test; import org.junit.jupiter.api.TestMethodOrder; import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; +import org.junit.jupiter.params.provider.EnumSource; import org.junit.jupiter.params.provider.ValueSource; /** @@ -183,6 +186,50 @@ void returnsFlagBuilder() { } } + @DisplayName(".compilationMode(CompilationMode) tests") + @Nested + class CompilationModeFlagTest { + + @DisplayName(".compilationMode(COMPILATION_AND_ANNOTATION_PROCESSING) adds no flags") + @Test + void compilationAndAnnotationProcessingAddsNoFlags() { + // When + flagBuilder.compilationMode(CompilationMode.COMPILATION_AND_ANNOTATION_PROCESSING); + + // Then + assertThat(flagBuilder.build()).isEmpty(); + } + + @DisplayName(".compilationMode(COMPILATION_ONLY) adds -proc:none") + @Test + void compilationOnlyAddsProcNone() { + // When + flagBuilder.compilationMode(CompilationMode.COMPILATION_ONLY); + + // Then + assertThat(flagBuilder.build()).containsExactly("-proc:none"); + } + + @DisplayName(".compilationMode(ANNOTATION_PROCESSING_ONLY) adds -proc:only") + @Test + void annotationProcessingOnlyAddsProcOnly() { + // When + flagBuilder.compilationMode(CompilationMode.ANNOTATION_PROCESSING_ONLY); + + // Then + assertThat(flagBuilder.build()).containsExactly("-proc:only"); + } + + @DisplayName(".compilationMode(...) returns the flag builder") + @EnumSource(CompilationMode.class) + @ParameterizedTest(name = "for compilationMode = {0}") + void returnsFlagBuilder(CompilationMode mode) { + // Then + assertThat(flagBuilder.compilationMode(mode)) + .isSameAs(flagBuilder); + } + } + @DisplayName(".showDeprecationWarnings(boolean) tests") @Nested class ShowDeprecationWarningsFlagTest { From 12a6bf2350760269af19cf066e7de4e1de2803c1 Mon Sep 17 00:00:00 2001 From: Ashley Scopes <73482956+ascopes@users.noreply.github.com> Date: Sat, 21 Jan 2023 12:37:35 +0000 Subject: [PATCH 2/2] Add immutability flags to CompilationMode enum --- .../java/io/github/ascopes/jct/compilers/CompilationMode.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/CompilationMode.java b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/CompilationMode.java index 82bdf1299..2cca057b7 100644 --- a/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/CompilationMode.java +++ b/java-compiler-testing/src/main/java/io/github/ascopes/jct/compilers/CompilationMode.java @@ -15,6 +15,8 @@ */ package io.github.ascopes.jct.compilers; +import javax.annotation.concurrent.Immutable; +import javax.annotation.concurrent.ThreadSafe; import org.apiguardian.api.API; import org.apiguardian.api.API.Status; @@ -28,6 +30,8 @@ * @since 0.0.1 (0.0.1-M6) */ @API(since = "0.0.1", status = Status.STABLE) +@Immutable +@ThreadSafe public enum CompilationMode { /**