Repository: apple/pkl
File: pkl-gradle/src/main/java/org/pkl/gradle/task/EvalTask.java (Java)

Code before:

  // not tracked because it might contain placeholders
  @Internal
  public abstract RegularFileProperty getOutputFile();

  // not tracked because it might contain placeholders
  @Internal
  public abstract DirectoryProperty getMultipleFileOutputDir();

  @Input
  @Optional
  public abstract Property<String> getOutputFormat();

  @Input
  @Optional
  public abstract Property<String> getModuleOutputSeparator();

  @Input
  @Optional
  public abstract Property<String> getExpression();

  @Inject
  public abstract ObjectFactory getObjectFactory();

  private CliEvaluator getCliEvaluator() {
    return new CliEvaluator(
        new CliEvaluatorOptions(
            getCliBaseOptions(),
            getOutputFile().get().getAsFile().getAbsolutePath(),
            getOutputFormat().get(),
            getModuleOutputSeparator().get(),
            mapAndGetOrNull(getMultipleFileOutputDir(), (it) -> it.getAsFile().getAbsolutePath()),
            getExpression().get()));
  }

  @OutputFiles
  @Optional
  public SetProperty<File> getOutputPaths() {
    var ret = getObjectFactory().setProperty(File.class);
    ret.value(getCliEvaluator().getOutputFiles()).disallowChanges();
    return ret;
  }

  @OutputDirectories
  @Optional
  public SetProperty<File> getMultipleFileOutputPaths() {
    var ret = getObjectFactory().setProperty(File.class);
    ret.value(getCliEvaluator().getOutputDirectories()).disallowChanges();
    return ret;
  }


Review comment (suggestion):
Note that this results in multiple `CliEvaluator` instances, each of which recomputes `CliEvaluator.outputFiles` and `CliEvaluator.outputDirectories`.

Code after:

public abstract class EvalTask extends ModulesTask {

  // not tracked because it might contain placeholders
  // required
  @Internal
  public abstract RegularFileProperty getOutputFile();

  // not tracked because it might contain placeholders
  // optional
  @Internal
  public abstract DirectoryProperty getMultipleFileOutputDir();

  @Input
  public abstract Property<String> getOutputFormat();

  @Input
  public abstract Property<String> getModuleOutputSeparator();

  @Input
  public abstract Property<String> getExpression();

  private final Provider<CliEvaluator> cliEvaluator =
      getProviders()
          .provider(
              () ->
                  new CliEvaluator(
                      new CliEvaluatorOptions(
                          getCliBaseOptions(),
                          getOutputFile().get().getAsFile().getAbsolutePath(),
                          getOutputFormat().get(),
                          getModuleOutputSeparator().get(),
                          mapAndGetOrNull(
                              getMultipleFileOutputDir(), it -> it.getAsFile().getAbsolutePath()),
                          getExpression().get())));

  @SuppressWarnings("unused")
  @OutputFiles
  @Optional
  public FileCollection getEffectiveOutputFiles() {
    return getObjects()
        .fileCollection()
        .from(cliEvaluator.map(e -> nullToEmpty(e.getOutputFiles())));
  }

  @OutputDirectories
  @Optional
  public FileCollection getEffectiveOutputDirs() {
    return getObjects()
        .fileCollection()
        .from(cliEvaluator.map(e -> nullToEmpty(e.getOutputDirectories())));