public void createCompileStep()

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);
  }