in src/com/facebook/buck/jvm/kotlin/KotlincToJarStepFactory.java [138:369]
public void createCompileStep(
BuildContext buildContext,
ProjectFilesystem projectFilesystem,
BuildTarget invokingRule,
CompilerParameters parameters,
/* output params */
Builder<Step> steps,
BuildableContext buildableContext) {
ImmutableSortedSet<Path> declaredClasspathEntries = parameters.getClasspathEntries();
ImmutableSortedSet<Path> sourceFilePaths = parameters.getSourceFilePaths();
Path outputDirectory = parameters.getOutputPaths().getClassesDir();
Path pathToSrcsList = parameters.getOutputPaths().getPathToSourcesList();
boolean generatingCode = !javacOptions.getJavaAnnotationProcessorParams().isEmpty();
boolean hasKotlinSources =
sourceFilePaths.stream().anyMatch(KOTLIN_PATH_MATCHER::matches)
|| sourceFilePaths.stream().anyMatch(SRC_ZIP_MATCHER::matches);
ImmutableSortedSet.Builder<Path> sourceBuilder =
ImmutableSortedSet.<Path>naturalOrder().addAll(sourceFilePaths);
// Only invoke kotlinc if we have kotlin or src zip files.
if (hasKotlinSources) {
Path stubsOutput =
BuildTargetPaths.getAnnotationPath(projectFilesystem, invokingRule, "__%s_stubs__");
Path sourcesOutput =
BuildTargetPaths.getAnnotationPath(projectFilesystem, invokingRule, "__%s_sources__");
Path classesOutput =
BuildTargetPaths.getAnnotationPath(projectFilesystem, invokingRule, "__%s_classes__");
Path kaptGeneratedOutput =
BuildTargetPaths.getAnnotationPath(
projectFilesystem, invokingRule, "__%s_kapt_generated__");
Path annotationGenFolder = getKaptAnnotationGenPath(projectFilesystem, invokingRule);
Path genOutputFolder =
BuildTargetPaths.getGenPath(projectFilesystem, invokingRule, "__%s_gen_sources__");
Path genOutput =
BuildTargetPaths.getGenPath(
projectFilesystem, invokingRule, "__%s_gen_sources__/generated" + SRC_ZIP);
// Javac requires that the root directory for generated sources already exist.
addCreateFolderStep(steps, projectFilesystem, buildContext, stubsOutput);
addCreateFolderStep(steps, projectFilesystem, buildContext, classesOutput);
addCreateFolderStep(steps, projectFilesystem, buildContext, kaptGeneratedOutput);
addCreateFolderStep(steps, projectFilesystem, buildContext, sourcesOutput);
addCreateFolderStep(steps, projectFilesystem, buildContext, annotationGenFolder);
addCreateFolderStep(steps, projectFilesystem, buildContext, genOutputFolder);
ImmutableSortedSet<Path> allClasspaths =
ImmutableSortedSet.<Path>naturalOrder()
.addAll(
Optional.ofNullable(extraClassPath.getExtraClasspath())
.orElse(ImmutableList.of()))
.addAll(declaredClasspathEntries)
.addAll(kotlinHomeLibraries)
.build();
SourcePathResolverAdapter resolver = buildContext.getSourcePathResolver();
String friendPathsArg = getFriendsPath(resolver, friendPaths);
String moduleName = getModuleName(invokingRule);
ImmutableList.Builder<String> annotationProcessingOptionsBuilder = ImmutableList.builder();
Builder<Step> postKotlinCompilationSteps = ImmutableList.builder();
if (generatingCode && annotationProcessingTool.equals(AnnotationProcessingTool.KAPT)) {
ImmutableList<String> annotationProcessors =
ImmutableList.copyOf(
javacOptions.getJavaAnnotationProcessorParams().getPluginProperties().stream()
.map(ResolvedJavacPluginProperties::getProcessorNames)
.flatMap(Set::stream)
.map(name -> AP_PROCESSORS_ARG + name)
.collect(Collectors.toList()));
ImmutableList<String> apClassPaths =
ImmutableList.copyOf(
javacOptions.getJavaAnnotationProcessorParams().getPluginProperties().stream()
.map(
resolvedJavacPluginProperties ->
resolvedJavacPluginProperties.getJavacPluginJsr199Fields(
buildContext.getSourcePathResolver(), projectFilesystem))
.map(JavacPluginJsr199Fields::getClasspath)
.flatMap(List::stream)
.map(url -> AP_CLASSPATH_ARG + urlToFile(url))
.collect(Collectors.toList()));
ImmutableList<String> kaptPluginOptions =
ImmutableList.<String>builder()
.add(
AP_CLASSPATH_ARG
+ kotlinc.getAnnotationProcessorPath(buildContext.getSourcePathResolver()))
.add(AP_CLASSPATH_ARG + kotlinc.getStdlibPath(buildContext.getSourcePathResolver()))
.addAll(apClassPaths)
.addAll(annotationProcessors)
.add(SOURCES_ARG + projectFilesystem.resolve(sourcesOutput))
.add(CLASSES_ARG + projectFilesystem.resolve(classesOutput))
.add(STUBS_ARG + projectFilesystem.resolve(stubsOutput))
.add(
AP_OPTIONS
+ encodeKaptApOptions(
kaptApOptions,
projectFilesystem.resolve(kaptGeneratedOutput).toString()))
.add(JAVAC_ARG + encodeOptions(Collections.emptyMap()))
.add(LIGHT_ANALYSIS + "true") // TODO: Provide value as argument
.add(CORRECT_ERROR_TYPES + "false") // TODO: Provide value as argument
.build();
annotationProcessingOptionsBuilder
.add(
X_PLUGIN_ARG
+ kotlinc.getAnnotationProcessorPath(buildContext.getSourcePathResolver()))
.add(PLUGIN)
.add(KAPT3_PLUGIN + APT_MODE + "compile," + Joiner.on(",").join(kaptPluginOptions));
postKotlinCompilationSteps.add(
CopyStep.forDirectory(
projectFilesystem,
sourcesOutput,
annotationGenFolder,
DirectoryMode.CONTENTS_ONLY));
postKotlinCompilationSteps.add(
CopyStep.forDirectory(
projectFilesystem,
classesOutput,
annotationGenFolder,
DirectoryMode.CONTENTS_ONLY));
postKotlinCompilationSteps.add(
CopyStep.forDirectory(
projectFilesystem,
kaptGeneratedOutput,
annotationGenFolder,
DirectoryMode.CONTENTS_ONLY));
postKotlinCompilationSteps.add(
new ZipStep(
projectFilesystem,
genOutput,
ImmutableSet.of(),
false,
ZipCompressionLevel.DEFAULT,
annotationGenFolder));
// Generated classes should be part of the output. This way generated files
// such as META-INF dirs will also be added to the final jar.
postKotlinCompilationSteps.add(
CopyStep.forDirectory(
projectFilesystem, classesOutput, outputDirectory, DirectoryMode.CONTENTS_ONLY));
sourceBuilder.add(genOutput);
}
ImmutableList.Builder<String> extraArguments =
ImmutableList.<String>builder()
.addAll(extraKotlincArguments)
.add(friendPathsArg)
.addAll(getKotlincPluginsArgs(resolver))
.addAll(annotationProcessingOptionsBuilder.build())
.add(MODULE_NAME)
.add(moduleName);
if (abiGenerationPlugin != null) {
Path tmpSourceAbiFolder = JavaAbis.getTmpGenPathForSourceAbi(projectFilesystem, invokingRule);
addCreateFolderStep(steps, projectFilesystem, buildContext, tmpSourceAbiFolder);
extraArguments.add("-Xplugin=" + abiGenerationPlugin);
extraArguments.add(
"-P", "plugin:org.jetbrains.kotlin.jvm.abi:outputDir=" + tmpSourceAbiFolder);
}
steps.add(
new KotlincStep(
invokingRule,
outputDirectory,
sourceFilePaths,
pathToSrcsList,
allClasspaths,
kotlinc,
extraArguments.build(),
projectFilesystem,
Optional.of(parameters.getOutputPaths().getWorkingDirectory())));
steps.addAll(postKotlinCompilationSteps.build());
}
final JavacOptions finalJavacOptions;
switch (annotationProcessingTool) {
case KAPT:
// If kapt was never invoked then do annotation processing with javac.
finalJavacOptions =
hasKotlinSources
? javacOptions.withJavaAnnotationProcessorParams(JavacPluginParams.EMPTY)
: javacOptions;
break;
case JAVAC:
finalJavacOptions = javacOptions;
break;
default:
throw new IllegalStateException(
"Unexpected annotationProcessingTool " + annotationProcessingTool);
}
// Note that this filters out only .kt files, so this keeps both .java and .src.zip files.
ImmutableSortedSet<Path> javaSourceFiles =
ImmutableSortedSet.copyOf(
sourceBuilder.build().stream()
.filter(input -> !KOTLIN_PATH_MATCHER.matches(input))
.collect(Collectors.toSet()));
CompilerParameters javacParameters =
CompilerParameters.builder()
.from(parameters)
.setClasspathEntries(
ImmutableSortedSet.<Path>naturalOrder()
.add(projectFilesystem.resolve(outputDirectory))
.addAll(
Optional.ofNullable(extraClassPath.getExtraClasspath())
.orElse(ImmutableList.of()))
.addAll(declaredClasspathEntries)
.build())
.setSourceFilePaths(javaSourceFiles)
.build();
new JavacToJarStepFactory(javac, finalJavacOptions, extraClassPath)
.createCompileStep(
buildContext,
projectFilesystem,
invokingRule,
javacParameters,
steps,
buildableContext);
}