Skip to content
Merged
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
Expand Up @@ -25,6 +25,7 @@
import io.github.ascopes.jct.workspaces.Workspace;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -123,7 +124,12 @@ protected AbstractJctCompiler(

@Override
public JctCompilationImpl compile(Workspace workspace) {
return JctJsr199Interop.compile(workspace, myself(), jsr199Compiler, flagBuilder);
return JctJsr199Interop.compile(workspace, myself(), jsr199Compiler, flagBuilder, null);
}

@Override
public JctCompilationImpl compile(Workspace workspace, Collection<String> classNames) {
return JctJsr199Interop.compile(workspace, myself(), jsr199Compiler, flagBuilder, classNames);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.io.UncheckedIOException;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import javax.annotation.Nullable;
Expand Down Expand Up @@ -126,15 +127,65 @@ public interface JctCompiler<C extends JctCompiler<C, R>, R extends JctCompilati
/**
* Invoke the compilation and return the compilation result.
*
* <p>The actual classes to compile will be dynamically discovered. If you wish to
* specify the specific classes to compile, see {@link #compile(Workspace, String, String...)} or
* {@link #compile(Workspace, Collection)}.
*
* @param workspace the workspace to compile.
* @return the compilation result.
* @throws JctCompilerException if the compiler threw an unhandled exception. This should not
* occur for compilation failures generally.
* @throws IllegalStateException if no compilation units were found.
* @throws UncheckedIOException if an IO error occurs.
* @see #compile(Workspace, String, String...)
* @see #compile(Workspace, Collection)
*/
R compile(Workspace workspace);

/**
* Invoke the compilation and return the compilation result.
*
* <p>Only classes matching the given class names will be compiled.
*
* <p>If you wish to let JCT determine which classes to compile dynamically, see
* {@link #compile(Workspace)} instead.
*
* @param workspace the workspace to compile.
* @param firstClassName the first class name to compile.
* @param additionalClassNames any additional class names to compile.
* @return the compilation result.
* @throws JctCompilerException if the compiler threw an unhandled exception. This should not
* occur for compilation failures generally.
* @throws IllegalStateException if no compilation units were found.
* @throws UncheckedIOException if an IO error occurs.
* @see #compile(Workspace)
* @see #compile(Workspace, Collection)
*/
default R compile(Workspace workspace, String firstClassName, String... additionalClassNames) {
return compile(workspace, IterableUtils.combineOneOrMore(firstClassName, additionalClassNames));
}

/**
* Invoke the compilation and return the compilation result.
*
* <p>Only classes matching the given class names will be compiled.
*
* <p>If you wish to let JCT determine which classes to compile dynamically, see
* {@link #compile(Workspace)} instead.
*
* @param workspace the workspace to compile.
* @param classNames the class names to compile.
* @return the compilation result.
* @throws JctCompilerException if the compiler threw an unhandled exception. This should not
* occur for compilation failures generally.
* @throws IllegalArgumentException if the collection is empty.
* @throws IllegalStateException if no compilation units were found.
* @throws UncheckedIOException if an IO error occurs.
* @see #compile(Workspace)
* @see #compile(Workspace, String, String...)
*/
R compile(Workspace workspace, Collection<String> classNames);

/**
* Apply a given configurer to this compiler that can throw a checked exception.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@
import java.lang.module.ModuleFinder;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
import javax.annotation.concurrent.ThreadSafe;
import javax.tools.JavaCompiler;
Expand Down Expand Up @@ -119,13 +121,17 @@ private JctJsr199Interop() {
* @param compiler the compiler to use.
* @param jsr199Compiler the JSR-199 compiler to use.
* @param flagBuilder the flag builder to use.
* @param classNames the class names to compile, or {@code null} to automatically detect
* all classes.
* @return the compilation factory.
*/
@SuppressWarnings("NullableProblems") // https://youtrack.jetbrains.com/issue/IDEA-311124
public static JctCompilationImpl compile(
Workspace workspace,
JctCompiler<?, ?> compiler,
JavaCompiler jsr199Compiler,
JctFlagBuilder flagBuilder
JctFlagBuilder flagBuilder,
@Nullable Collection<String> classNames
) {
// This method sucks, I hate it. If there is a nicer way of doing this without a load of
// additional overhead, additional code, or additional complexity either in this class or the
Expand All @@ -149,7 +155,8 @@ public static JctCompilationImpl compile(
flags,
fileManager,
diagnosticListener,
compilationUnits
compilationUnits,
classNames
);

var outputLines = writer.toString().lines().collect(Collectors.toList());
Expand Down Expand Up @@ -506,7 +513,8 @@ public static boolean performCompilerPass(
List<String> flags,
JctFileManager fileManager,
TracingDiagnosticListener<JavaFileObject> diagnosticListener,
List<JavaFileObject> compilationUnits
List<JavaFileObject> compilationUnits,
@Nullable Collection<String> classNames
) {
var name = compiler.toString();

Expand All @@ -515,9 +523,7 @@ public static boolean performCompilerPass(
fileManager,
diagnosticListener,
flags,
// TODO(ascopes): in the future, consider adding something here to allow customising
// the classes that get compiled, if desired.
null,
classNames,
compilationUnits
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@
import java.util.Arrays;
import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.stream.Stream;
import javax.annotation.processing.Processor;
import javax.tools.JavaCompiler;
Expand Down Expand Up @@ -320,13 +321,13 @@ void constructorInitialisesAnnotationProcessorDiscoveryToDefaultValue() {
}
}

@DisplayName(".compile(...) builds the expected compilation object")
@DisplayName(".compile(Workspace) builds the expected compilation object")
@Test
void compileReturnsTheExpectedObject() {
void compileWorkspaceBuildsTheExpectedCompilationObject() {
try (var factoryCls = mockStatic(JctJsr199Interop.class)) {
// Given
var expectedCompilation = mock(JctCompilationImpl.class);
factoryCls.when(() -> JctJsr199Interop.compile(any(), any(), any(), any()))
factoryCls.when(() -> JctJsr199Interop.compile(any(), any(), any(), any(), any()))
.thenReturn(expectedCompilation);
var expectedWorkspace = mock(Workspace.class);

Expand All @@ -335,7 +336,29 @@ void compileReturnsTheExpectedObject() {

// Then
factoryCls.verify(() -> JctJsr199Interop
.compile(expectedWorkspace, compiler, jsr199Compiler, flagBuilder));
.compile(expectedWorkspace, compiler, jsr199Compiler, flagBuilder, null));

assertThat(actualCompilation).isSameAs(expectedCompilation);
}
}

@DisplayName(".compile(Workspace, Collection) builds the expected compilation object")
@Test
void compileWorkspaceCollectionBuildsTheExpectedCompilationObject() {
try (var factoryCls = mockStatic(JctJsr199Interop.class)) {
// Given
var expectedCompilation = mock(JctCompilationImpl.class);
factoryCls.when(() -> JctJsr199Interop.compile(any(), any(), any(), any(), any()))
.thenReturn(expectedCompilation);
var expectedWorkspace = mock(Workspace.class);
var classes = Set.of("foo.bar", "baz.bork", "qux.quxx");

// When
var actualCompilation = compiler.compile(expectedWorkspace, classes);

// Then
factoryCls.verify(() -> JctJsr199Interop
.compile(expectedWorkspace, compiler, jsr199Compiler, flagBuilder, classes));

assertThat(actualCompilation).isSameAs(expectedCompilation);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@
import static org.mockito.Mockito.mock;

import io.github.ascopes.jct.compilers.JctCompiler;
import io.github.ascopes.jct.workspaces.Workspace;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
import javax.annotation.processing.Processor;
import javax.lang.model.SourceVersion;
Expand Down Expand Up @@ -260,6 +263,26 @@ void targetVersionSourceVersionCallsReleaseVersionString(
assertThat(result).isSameAs(compiler);
}

@DisplayName(".compile(Workspace, String, String...) calls .compile(Workspace, Collection)")
@Test
void compileStringVarargsCallsCompileCollection() {
// Given
var workspace = mock(Workspace.class);

given(compiler.compile(any(), any(), any(), any()))
.willCallRealMethod();

var firstClass = "org.example.Foo";
var secondClass = "org.example.Bar";
var thirdClass = "com.organisation.FooBar";

// When
var result = compiler.compile(workspace, firstClass, secondClass, thirdClass);

// Then
then(compiler).should().compile(workspace, List.of(firstClass, secondClass, thirdClass));
}

static Stream<Arguments> sourceVersions() {
return Stream
.of(SourceVersion.values())
Expand Down
Loading