pkl-gradle: Migrate nullness to jSpecify (#1530)

This commit is contained in:
odenix
2026-04-17 20:34:54 +01:00
committed by GitHub
parent b1a5d8c915
commit 2e49a319b3
9 changed files with 104 additions and 81 deletions
+24 -3
View File
@@ -16,10 +16,28 @@ com.github.ajalt.mordant:mordant-jvm:3.0.1=compileClasspath
com.github.ajalt.mordant:mordant:3.0.1=compileClasspath com.github.ajalt.mordant:mordant:3.0.1=compileClasspath
com.github.ajalt.mordant:mordant:3.0.2=compileOnlyDependenciesMetadata com.github.ajalt.mordant:mordant:3.0.2=compileOnlyDependenciesMetadata
com.github.ben-manes.caffeine:caffeine:2.9.3=swiftExportClasspathResolvable com.github.ben-manes.caffeine:caffeine:2.9.3=swiftExportClasspathResolvable
com.github.ben-manes.caffeine:caffeine:3.0.5=annotationProcessor,testAnnotationProcessor
com.github.kevinstern:software-and-algorithms:1.0=annotationProcessor,testAnnotationProcessor
com.google.auto.service:auto-service-annotations:1.0.1=annotationProcessor,testAnnotationProcessor
com.google.auto.value:auto-value-annotations:1.9=annotationProcessor,testAnnotationProcessor
com.google.auto:auto-common:1.2.2=annotationProcessor,testAnnotationProcessor
com.google.errorprone:error_prone_annotation:2.48.0=annotationProcessor,testAnnotationProcessor
com.google.errorprone:error_prone_annotations:2.28.0=swiftExportClasspathResolvable com.google.errorprone:error_prone_annotations:2.28.0=swiftExportClasspathResolvable
io.github.java-diff-utils:java-diff-utils:4.12=kotlinInternalAbiValidation com.google.errorprone:error_prone_annotations:2.48.0=annotationProcessor,testAnnotationProcessor
com.google.errorprone:error_prone_check_api:2.48.0=annotationProcessor,testAnnotationProcessor
com.google.errorprone:error_prone_core:2.48.0=annotationProcessor,testAnnotationProcessor
com.google.googlejavaformat:google-java-format:1.34.1=annotationProcessor,testAnnotationProcessor
com.google.guava:failureaccess:1.0.3=annotationProcessor,testAnnotationProcessor
com.google.guava:guava:33.5.0-jre=annotationProcessor,testAnnotationProcessor
com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava=annotationProcessor,testAnnotationProcessor
com.google.j2objc:j2objc-annotations:3.1=annotationProcessor,testAnnotationProcessor
com.google.protobuf:protobuf-java:4.33.2=annotationProcessor,testAnnotationProcessor
com.uber.nullaway:nullaway:0.13.1=annotationProcessor,testAnnotationProcessor
io.github.eisop:dataflow-errorprone:3.41.0-eisop1=annotationProcessor,testAnnotationProcessor
io.github.java-diff-utils:java-diff-utils:4.12=annotationProcessor,kotlinInternalAbiValidation,testAnnotationProcessor
io.opentelemetry:opentelemetry-api:1.41.0=swiftExportClasspathResolvable io.opentelemetry:opentelemetry-api:1.41.0=swiftExportClasspathResolvable
io.opentelemetry:opentelemetry-context:1.41.0=swiftExportClasspathResolvable io.opentelemetry:opentelemetry-context:1.41.0=swiftExportClasspathResolvable
javax.inject:javax.inject:1=annotationProcessor,testAnnotationProcessor
net.bytebuddy:byte-buddy:1.18.3=testCompileClasspath,testRuntimeClasspath net.bytebuddy:byte-buddy:1.18.3=testCompileClasspath,testRuntimeClasspath
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath
org.assertj:assertj-core:3.27.7=testCompileClasspath,testRuntimeClasspath org.assertj:assertj-core:3.27.7=testCompileClasspath,testRuntimeClasspath
@@ -28,6 +46,8 @@ org.bouncycastle:bcpkix-jdk18on:1.80=kotlinBouncyCastleConfiguration
org.bouncycastle:bcprov-jdk18on:1.80=kotlinBouncyCastleConfiguration org.bouncycastle:bcprov-jdk18on:1.80=kotlinBouncyCastleConfiguration
org.bouncycastle:bcutil-jdk18on:1.80=kotlinBouncyCastleConfiguration org.bouncycastle:bcutil-jdk18on:1.80=kotlinBouncyCastleConfiguration
org.checkerframework:checker-qual:3.43.0=swiftExportClasspathResolvable org.checkerframework:checker-qual:3.43.0=swiftExportClasspathResolvable
org.checkerframework:checker-qual:3.53.0=annotationProcessor,testAnnotationProcessor
org.checkerframework:dataflow-nullaway:3.53.0=annotationProcessor,testAnnotationProcessor
org.jetbrains.kotlin:abi-tools-api:2.3.20=kotlinInternalAbiValidation org.jetbrains.kotlin:abi-tools-api:2.3.20=kotlinInternalAbiValidation
org.jetbrains.kotlin:abi-tools:2.3.20=kotlinInternalAbiValidation org.jetbrains.kotlin:abi-tools:2.3.20=kotlinInternalAbiValidation
org.jetbrains.kotlin:kotlin-build-tools-api:2.3.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath org.jetbrains.kotlin:kotlin-build-tools-api:2.3.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
@@ -63,7 +83,7 @@ org.jetbrains.kotlinx:kotlinx-serialization-bom:1.7.3=swiftExportClasspathResolv
org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.7.3=swiftExportClasspathResolvable org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:1.7.3=swiftExportClasspathResolvable
org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3=swiftExportClasspathResolvable org.jetbrains.kotlinx:kotlinx-serialization-core:1.7.3=swiftExportClasspathResolvable
org.jetbrains:annotations:13.0=compileClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable,testCompileClasspath,testRuntimeClasspath org.jetbrains:annotations:13.0=compileClasspath,kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable,testCompileClasspath,testRuntimeClasspath
org.jspecify:jspecify:1.0.0=compileClasspath,testCompileClasspath org.jspecify:jspecify:1.0.0=annotationProcessor,compileClasspath,runtimeClasspath,testAnnotationProcessor,testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-api:6.0.3=testCompileClasspath,testRuntimeClasspath org.junit.jupiter:junit-jupiter-api:6.0.3=testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-engine:6.0.3=testCompileClasspath,testRuntimeClasspath org.junit.jupiter:junit-jupiter-engine:6.0.3=testCompileClasspath,testRuntimeClasspath
org.junit.jupiter:junit-jupiter-params:6.0.3=testCompileClasspath,testRuntimeClasspath org.junit.jupiter:junit-jupiter-params:6.0.3=testCompileClasspath,testRuntimeClasspath
@@ -73,4 +93,5 @@ org.junit.platform:junit-platform-launcher:6.0.3=testRuntimeClasspath
org.junit:junit-bom:6.0.3=testCompileClasspath,testRuntimeClasspath org.junit:junit-bom:6.0.3=testCompileClasspath,testRuntimeClasspath
org.msgpack:msgpack-core:0.9.11=testRuntimeClasspath org.msgpack:msgpack-core:0.9.11=testRuntimeClasspath
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath
empty=annotationProcessor,apiDependenciesMetadata,implementationDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,runtimeClasspath,signatures,sourcesJar,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions org.pcollections:pcollections:4.0.1=annotationProcessor,testAnnotationProcessor
empty=apiDependenciesMetadata,implementationDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,signatures,sourcesJar,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions
+1 -1
View File
@@ -17,7 +17,7 @@ plugins {
id("pklAllProjects") id("pklAllProjects")
id("pklJavaLibrary") id("pklJavaLibrary")
id("pklGradlePluginTest") id("pklGradlePluginTest")
id("pklJSpecify")
`java-gradle-plugin` `java-gradle-plugin`
`maven-publish` `maven-publish`
id("pklPublishLibrary") id("pklPublishLibrary")
@@ -1,5 +1,5 @@
/* /*
* Copyright © 2024-2025 Apple Inc. and the Pkl project authors. All rights reserved. * Copyright © 2024-2026 Apple Inc. and the Pkl project authors. All rights reserved.
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
@@ -36,12 +36,11 @@ import org.gradle.api.tasks.TaskProvider;
import org.gradle.language.base.plugins.LifecycleBasePlugin; import org.gradle.language.base.plugins.LifecycleBasePlugin;
import org.gradle.plugins.ide.idea.model.IdeaModel; import org.gradle.plugins.ide.idea.model.IdeaModel;
import org.gradle.util.GradleVersion; import org.gradle.util.GradleVersion;
import org.jspecify.annotations.Nullable;
import org.pkl.cli.CliEvaluatorOptions; import org.pkl.cli.CliEvaluatorOptions;
import org.pkl.core.ImportGraph; import org.pkl.core.ImportGraph;
import org.pkl.core.OutputFormat; import org.pkl.core.OutputFormat;
import org.pkl.core.util.IoUtils; import org.pkl.core.util.IoUtils;
import org.pkl.core.util.LateInit;
import org.pkl.core.util.Nullable;
import org.pkl.gradle.spec.AnalyzeImportsSpec; import org.pkl.gradle.spec.AnalyzeImportsSpec;
import org.pkl.gradle.spec.BasePklSpec; import org.pkl.gradle.spec.BasePklSpec;
import org.pkl.gradle.spec.CodeGenSpec; import org.pkl.gradle.spec.CodeGenSpec;
@@ -71,21 +70,26 @@ public class PklPlugin implements Plugin<Project> {
private static final String MIN_GRADLE_VERSION = "8.2"; private static final String MIN_GRADLE_VERSION = "8.2";
@LateInit private Project project; private @Nullable Project __project;
@Override @Override
public void apply(Project project) { public void apply(Project project) {
this.project = project; __project = project;
if (GradleVersion.current().compareTo(GradleVersion.version(MIN_GRADLE_VERSION)) < 0) { if (GradleVersion.current().compareTo(GradleVersion.version(MIN_GRADLE_VERSION)) < 0) {
throw new GradleException( throw new GradleException(
String.format("Plugin `org.pkl` requires Gradle %s or higher.", MIN_GRADLE_VERSION)); String.format("Plugin `org.pkl` requires Gradle %s or higher.", MIN_GRADLE_VERSION));
} }
var extension = project.getExtensions().create("pkl", PklExtension.class); var extension = project().getExtensions().create("pkl", PklExtension.class);
configureExtension(extension); configureExtension(extension);
} }
private Project project() {
assert __project != null;
return __project;
}
private void configureExtension(PklExtension extension) { private void configureExtension(PklExtension extension) {
configureEvalTasks(extension.getEvaluators()); configureEvalTasks(extension.getEvaluators());
configureJavaCodeGenTasks(extension.getJavaCodeGenerators()); configureJavaCodeGenTasks(extension.getJavaCodeGenerators());
@@ -102,7 +106,7 @@ public class PklPlugin implements Plugin<Project> {
spec -> { spec -> {
configureBaseSpec(spec); configureBaseSpec(spec);
spec.getOutputPath() spec.getOutputPath()
.convention(project.getLayout().getBuildDirectory().dir("generated/pkl/packages")); .convention(project().getLayout().getBuildDirectory().dir("generated/pkl/packages"));
spec.getOverwrite().convention(false); spec.getOverwrite().convention(false);
var packageTask = createTask(ProjectPackageTask.class, spec); var packageTask = createTask(ProjectPackageTask.class, spec);
packageTask.configure( packageTask.configure(
@@ -113,12 +117,12 @@ public class PklPlugin implements Plugin<Project> {
task.getJunitReportsDir().set(spec.getJunitReportsDir()); task.getJunitReportsDir().set(spec.getJunitReportsDir());
task.getOverwrite().set(spec.getOverwrite()); task.getOverwrite().set(spec.getOverwrite());
}); });
project project()
.getPluginManager() .getPluginManager()
.withPlugin( .withPlugin(
"base", "base",
appliedPlugin -> appliedPlugin ->
project project()
.getTasks() .getTasks()
.named( .named(
LifecycleBasePlugin.BUILD_TASK_NAME, LifecycleBasePlugin.BUILD_TASK_NAME,
@@ -157,7 +161,7 @@ public class PklPlugin implements Plugin<Project> {
configureBaseSpec(spec); configureBaseSpec(spec);
spec.getOutputFile() spec.getOutputFile()
.convention( .convention(
project project()
.getLayout() .getLayout()
.getProjectDirectory() .getProjectDirectory()
// %{moduleDir} is resolved relatively to the working directory, // %{moduleDir} is resolved relatively to the working directory,
@@ -194,11 +198,12 @@ public class PklPlugin implements Plugin<Project> {
// constructor parameters annotations by setting this property to `null`. // constructor parameters annotations by setting this property to `null`.
spec.getParamsAnnotation() spec.getParamsAnnotation()
.set( .set(
project.provider( project()
() -> .provider(
spec.getGenerateSpringBootConfig().get() () ->
? null spec.getGenerateSpringBootConfig().get()
: "org.pkl.config.java.mapper.Named")); ? null
: "org.pkl.config.java.mapper.Named"));
createModulesTask(JavaCodeGenTask.class, spec) createModulesTask(JavaCodeGenTask.class, spec)
.configure( .configure(
@@ -211,14 +216,15 @@ public class PklPlugin implements Plugin<Project> {
}); });
}); });
project.afterEvaluate( project()
prj -> .afterEvaluate(
specs.all( prj ->
spec -> { specs.all(
configureIdeaModule(spec); spec -> {
configureCodeGenSpecSourceDirectories( configureIdeaModule(spec);
spec, "java", s -> Optional.of(s.getJava())); configureCodeGenSpecSourceDirectories(
})); spec, "java", s -> Optional.of(s.getJava()));
}));
} }
private void configureKotlinCodeGenTasks(NamedDomainObjectContainer<KotlinCodeGenSpec> specs) { private void configureKotlinCodeGenTasks(NamedDomainObjectContainer<KotlinCodeGenSpec> specs) {
@@ -237,14 +243,15 @@ public class PklPlugin implements Plugin<Project> {
}); });
}); });
project.afterEvaluate( project()
prj -> .afterEvaluate(
specs.all( prj ->
spec -> { specs.all(
configureIdeaModule(spec); spec -> {
configureCodeGenSpecSourceDirectories( configureIdeaModule(spec);
spec, "kotlin", this::getKotlinSourceDirectorySet); configureCodeGenSpecSourceDirectories(
})); spec, "kotlin", this::getKotlinSourceDirectorySet);
}));
} }
private void configurePkldocTasks(NamedDomainObjectContainer<PkldocSpec> specs) { private void configurePkldocTasks(NamedDomainObjectContainer<PkldocSpec> specs) {
@@ -254,7 +261,7 @@ public class PklPlugin implements Plugin<Project> {
spec.getOutputDir() spec.getOutputDir()
.convention( .convention(
project project()
.getLayout() .getLayout()
.getBuildDirectory() .getBuildDirectory()
.map(it -> it.dir("pkldoc").dir(spec.getName()))); .map(it -> it.dir("pkldoc").dir(spec.getName())));
@@ -284,12 +291,12 @@ public class PklPlugin implements Plugin<Project> {
task.getOverwrite().set(spec.getOverwrite()); task.getOverwrite().set(spec.getOverwrite());
}); });
project project()
.getPluginManager() .getPluginManager()
.withPlugin( .withPlugin(
"base", "base",
appliedPlugin -> appliedPlugin ->
project project()
.getTasks() .getTasks()
.named( .named(
LifecycleBasePlugin.CHECK_TASK_NAME, LifecycleBasePlugin.CHECK_TASK_NAME,
@@ -306,7 +313,7 @@ public class PklPlugin implements Plugin<Project> {
spec.getAllowedResources() spec.getAllowedResources()
.convention(List.of("env:", "prop:", "file:", "modulepath:", "https:", "package:")); .convention(List.of("env:", "prop:", "file:", "modulepath:", "https:", "package:"));
spec.getEvalRootDir().convention(project.getRootProject().getLayout().getProjectDirectory()); spec.getEvalRootDir().convention(project().getRootProject().getLayout().getProjectDirectory());
// Defaulting to OS env vars is bad for reproducibility and cachability. // Defaulting to OS env vars is bad for reproducibility and cachability.
// Hence, this spec defaults to empty env vars, which is consistent with other Gradle tasks // Hence, this spec defaults to empty env vars, which is consistent with other Gradle tasks
@@ -326,18 +333,19 @@ public class PklPlugin implements Plugin<Project> {
private void configureCodeGenSpec(CodeGenSpec spec) { private void configureCodeGenSpec(CodeGenSpec spec) {
spec.getOutputDir() spec.getOutputDir()
.convention( .convention(
project project()
.getLayout() .getLayout()
.getBuildDirectory() .getBuildDirectory()
.map(it -> it.dir("generated").dir("pkl").dir(spec.getName()))); .map(it -> it.dir("generated").dir("pkl").dir(spec.getName())));
spec.getSourceSet() spec.getSourceSet()
.convention( .convention(
project project()
.getProviders() .getProviders()
.provider( .provider(
() -> { () -> {
var sourceSets = project.getExtensions().findByType(SourceSetContainer.class); var sourceSets =
project().getExtensions().findByType(SourceSetContainer.class);
if (sourceSets == null) { if (sourceSets == null) {
return null; return null;
} }
@@ -371,7 +379,7 @@ public class PklPlugin implements Plugin<Project> {
// Refer to configureCodeGenSpecSourceDirectories for logic which links the codegen task // Refer to configureCodeGenSpecSourceDirectories for logic which links the codegen task
// to sourceSet.getResources().getSourceDirectories(). // to sourceSet.getResources().getSourceDirectories().
var modulePath = project.files(); var modulePath = project().files();
modulePath modulePath
.from(getResourceSourceDirectoriesExceptSpecOutput(spec)) .from(getResourceSourceDirectoriesExceptSpecOutput(spec))
// This technically breaks the dependency on compile classpath builder tasks, // This technically breaks the dependency on compile classpath builder tasks,
@@ -411,14 +419,14 @@ public class PklPlugin implements Plugin<Project> {
String languageName, String languageName,
Function<? super SourceSet, ? extends Optional<SourceDirectorySet>> Function<? super SourceSet, ? extends Optional<SourceDirectorySet>>
extractSourceDirectorySet) { extractSourceDirectorySet) {
var task = project.getTasks().named(spec.getName(), CodeGenTask.class); var task = project().getTasks().named(spec.getName(), CodeGenTask.class);
var sourceSet = spec.getSourceSet().get(); var sourceSet = spec.getSourceSet().get();
extractSourceDirectorySet extractSourceDirectorySet
.apply(sourceSet) .apply(sourceSet)
.ifPresentOrElse( .ifPresentOrElse(
dirSet -> dirSet.srcDir(task.flatMap(t -> t.getOutputDir().dir(languageName))), dirSet -> dirSet.srcDir(task.flatMap(t -> t.getOutputDir().dir(languageName))),
() -> () ->
project project()
.getLogger() .getLogger()
.debug( .debug(
"Source directory set for language {} is not available, " "Source directory set for language {} is not available, "
@@ -431,12 +439,12 @@ public class PklPlugin implements Plugin<Project> {
// Must be called from Project.afterEvaluate() only, because this method depends // Must be called from Project.afterEvaluate() only, because this method depends
// on user-provided configuration not accessible with lazy configuration. // on user-provided configuration not accessible with lazy configuration.
private void configureIdeaModule(CodeGenSpec spec) { private void configureIdeaModule(CodeGenSpec spec) {
project project()
.getPluginManager() .getPluginManager()
.withPlugin( .withPlugin(
"idea", "idea",
plugin -> { plugin -> {
var module = project.getExtensions().getByType(IdeaModel.class).getModule(); var module = project().getExtensions().getByType(IdeaModel.class).getModule();
var outputDir = spec.getOutputDir().get().getAsFile(); var outputDir = spec.getOutputDir().get().getAsFile();
module.getGeneratedSourceDirs().add(outputDir); module.getGeneratedSourceDirs().add(outputDir);
if (spec.getSourceSet().get().getName().toLowerCase().contains("test")) { if (spec.getSourceSet().get().getName().toLowerCase().contains("test")) {
@@ -521,11 +529,11 @@ public class PklPlugin implements Plugin<Project> {
private TaskProvider<AnalyzeImportsTask> createAnalyzeImportsTask(ModulesSpec spec) { private TaskProvider<AnalyzeImportsTask> createAnalyzeImportsTask(ModulesSpec spec) {
var outputFile = var outputFile =
project project()
.getLayout() .getLayout()
.getBuildDirectory() .getBuildDirectory()
.file("pkl-gradle/imports/" + spec.getName() + ".json"); .file("pkl-gradle/imports/" + spec.getName() + ".json");
return project return project()
.getTasks() .getTasks()
.register( .register(
spec.getName() + "GatherImports", spec.getName() + "GatherImports",
@@ -567,7 +575,7 @@ public class PklPlugin implements Plugin<Project> {
private <T extends ModulesTask> TaskProvider<T> createModulesTask( private <T extends ModulesTask> TaskProvider<T> createModulesTask(
Class<T> taskClass, ModulesSpec spec) { Class<T> taskClass, ModulesSpec spec) {
var analyzeImportsTask = createAnalyzeImportsTask(spec); var analyzeImportsTask = createAnalyzeImportsTask(spec);
return project return project()
.getTasks() .getTasks()
.register( .register(
spec.getName(), spec.getName(),
@@ -576,7 +584,7 @@ public class PklPlugin implements Plugin<Project> {
} }
private <T extends BasePklTask> TaskProvider<T> createTask(Class<T> taskClass, BasePklSpec spec) { private <T extends BasePklTask> TaskProvider<T> createTask(Class<T> taskClass, BasePklSpec spec) {
return project return project()
.getTasks() .getTasks()
.register(spec.getName(), taskClass, task -> configureBaseTask(task, spec)); .register(spec.getName(), taskClass, task -> configureBaseTask(task, spec));
} }
@@ -1,4 +1,4 @@
@NonnullByDefault @NullMarked
package org.pkl.gradle; package org.pkl.gradle;
import org.pkl.core.util.NonnullByDefault; import org.jspecify.annotations.NullMarked;
@@ -1,4 +1,4 @@
@NonnullByDefault @NullMarked
package org.pkl.gradle.spec; package org.pkl.gradle.spec;
import org.pkl.core.util.NonnullByDefault; import org.jspecify.annotations.NullMarked;
@@ -28,6 +28,7 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.inject.Inject; import javax.inject.Inject;
import org.gradle.api.DefaultTask; import org.gradle.api.DefaultTask;
import org.gradle.api.Transformer;
import org.gradle.api.file.ConfigurableFileCollection; import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.file.DirectoryProperty; import org.gradle.api.file.DirectoryProperty;
import org.gradle.api.model.ObjectFactory; import org.gradle.api.model.ObjectFactory;
@@ -45,10 +46,9 @@ import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.PathSensitive; import org.gradle.api.tasks.PathSensitive;
import org.gradle.api.tasks.PathSensitivity; import org.gradle.api.tasks.PathSensitivity;
import org.gradle.api.tasks.TaskAction; import org.gradle.api.tasks.TaskAction;
import org.jspecify.annotations.Nullable;
import org.pkl.commons.cli.CliBaseOptions; import org.pkl.commons.cli.CliBaseOptions;
import org.pkl.core.evaluatorSettings.Color; import org.pkl.core.evaluatorSettings.Color;
import org.pkl.core.util.LateInit;
import org.pkl.core.util.Nullable;
import org.pkl.gradle.utils.PluginUtils; import org.pkl.gradle.utils.PluginUtils;
@CacheableTask @CacheableTask
@@ -86,27 +86,21 @@ public abstract class BasePklTask extends DefaultTask {
@Optional @Optional
@PathSensitive(PathSensitivity.ABSOLUTE) @PathSensitive(PathSensitivity.ABSOLUTE)
public Provider<File> getSettingsModuleFile() { public Provider<File> getSettingsModuleFile() {
//noinspection RedundantCast
return getParsedSettingsModule() return getParsedSettingsModule()
// NullAway needs this redundant cast
.map( .map(
it -> { (Transformer<@Nullable File, Object>)
if (it instanceof File file) { object -> object instanceof File file ? file : null);
return file;
}
return null;
});
} }
@Input @Input
@Optional @Optional
public Provider<URI> getSettingsModuleUri() { public Provider<URI> getSettingsModuleUri() {
//noinspection RedundantCast
return getParsedSettingsModule() return getParsedSettingsModule()
.map( // NullAway needs this redundant cast
it -> { .map((Transformer<@Nullable URI, Object>) object -> object instanceof URI uri ? uri : null);
if (it instanceof URI uri) {
return uri;
}
return null;
});
} }
// Exposed as a task input via evalRootDirPath, because we only need to depend // Exposed as a task input via evalRootDirPath, because we only need to depend
@@ -180,13 +174,13 @@ public abstract class BasePklTask extends DefaultTask {
protected abstract void doRunTask(); protected abstract void doRunTask();
@LateInit protected CliBaseOptions cachedOptions; protected @Nullable CliBaseOptions __cachedOptions;
// Must be called during task execution time only. // Must be called during task execution time only.
@Internal @Internal
protected CliBaseOptions getCliBaseOptions() { protected CliBaseOptions getCliBaseOptions() {
if (cachedOptions == null) { if (__cachedOptions == null) {
cachedOptions = __cachedOptions =
new CliBaseOptions( new CliBaseOptions(
getSourceModulesAsUris(), getSourceModulesAsUris(),
patternsFromStrings(getAllowedModules().get()), patternsFromStrings(getAllowedModules().get()),
@@ -215,7 +209,7 @@ public abstract class BasePklTask extends DefaultTask {
null, null,
getPowerAssertions().getOrElse(false)); getPowerAssertions().getOrElse(false));
} }
return cachedOptions; return __cachedOptions;
} }
@Internal @Internal
@@ -145,8 +145,8 @@ public abstract class ModulesTask extends BasePklTask {
@Internal @Internal
@Override @Override
protected CliBaseOptions getCliBaseOptions() { protected CliBaseOptions getCliBaseOptions() {
if (cachedOptions == null) { if (__cachedOptions == null) {
cachedOptions = __cachedOptions =
new CliBaseOptions( new CliBaseOptions(
getSourceModulesAsUris(), getSourceModulesAsUris(),
patternsFromStrings(getAllowedModules().get()), patternsFromStrings(getAllowedModules().get()),
@@ -175,6 +175,6 @@ public abstract class ModulesTask extends BasePklTask {
null, null,
getPowerAssertions().getOrElse(false)); getPowerAssertions().getOrElse(false));
} }
return cachedOptions; return __cachedOptions;
} }
} }
@@ -1,4 +1,4 @@
@NonnullByDefault @NullMarked
package org.pkl.gradle.task; package org.pkl.gradle.task;
import org.pkl.core.util.NonnullByDefault; import org.jspecify.annotations.NullMarked;
@@ -1,4 +1,4 @@
@NonnullByDefault @NullMarked
package org.pkl.gradle.utils; package org.pkl.gradle.utils;
import org.pkl.core.util.NonnullByDefault; import org.jspecify.annotations.NullMarked;