mirror of
https://github.com/apple/pkl.git
synced 2026-04-16 21:49:49 +02:00
Add nullability check to pkl-formatter (#1526)
This commit is contained in:
@@ -2,10 +2,28 @@
|
||||
# Manual edits can break the build and are not advised.
|
||||
# This file is expected to be part of source control.
|
||||
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
|
||||
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-context:1.41.0=swiftExportClasspathResolvable
|
||||
javax.inject:javax.inject:1=annotationProcessor,testAnnotationProcessor
|
||||
net.bytebuddy:byte-buddy:1.18.3=testCompileClasspath,testRuntimeClasspath
|
||||
org.apiguardian:apiguardian-api:1.1.2=testCompileClasspath
|
||||
org.assertj:assertj-core:3.27.7=testCompileClasspath,testRuntimeClasspath
|
||||
@@ -14,6 +32,8 @@ org.bouncycastle:bcpkix-jdk18on:1.80=kotlinBouncyCastleConfiguration
|
||||
org.bouncycastle:bcprov-jdk18on:1.80=kotlinBouncyCastleConfiguration
|
||||
org.bouncycastle:bcutil-jdk18on:1.80=kotlinBouncyCastleConfiguration
|
||||
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:2.3.20=kotlinInternalAbiValidation
|
||||
org.jetbrains.kotlin:kotlin-build-tools-api:2.3.20=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath
|
||||
@@ -46,7 +66,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:1.7.3=swiftExportClasspathResolvable
|
||||
org.jetbrains:annotations:13.0=kotlinBuildToolsApiClasspath,kotlinCompilerClasspath,kotlinCompilerPluginClasspathMain,kotlinCompilerPluginClasspathTest,kotlinInternalAbiValidation,kotlinKlibCommonizerClasspath,swiftExportClasspathResolvable,testCompileClasspath,testRuntimeClasspath
|
||||
org.jspecify:jspecify:1.0.0=compileClasspath,runtimeClasspath,testCompileClasspath,testRuntimeClasspath
|
||||
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-engine:6.0.3=testCompileClasspath,testRuntimeClasspath
|
||||
org.junit.jupiter:junit-jupiter-params:6.0.3=testCompileClasspath,testRuntimeClasspath
|
||||
@@ -56,4 +76,5 @@ org.junit.platform:junit-platform-launcher:6.0.3=testRuntimeClasspath
|
||||
org.junit:junit-bom:6.0.3=testCompileClasspath,testRuntimeClasspath
|
||||
org.msgpack:msgpack-core:0.9.11=testRuntimeClasspath
|
||||
org.opentest4j:opentest4j:1.3.0=testCompileClasspath,testRuntimeClasspath
|
||||
empty=annotationProcessor,apiDependenciesMetadata,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,sourcesJar,testAnnotationProcessor,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions
|
||||
org.pcollections:pcollections:4.0.1=annotationProcessor,testAnnotationProcessor
|
||||
empty=apiDependenciesMetadata,compileOnlyDependenciesMetadata,implementationDependenciesMetadata,intransitiveDependenciesMetadata,kotlinCompilerPluginClasspath,kotlinNativeCompilerPluginClasspath,kotlinScriptDefExtensions,sourcesJar,testApiDependenciesMetadata,testCompileOnlyDependenciesMetadata,testImplementationDependenciesMetadata,testIntransitiveDependenciesMetadata,testKotlinScriptDefExtensions
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
plugins {
|
||||
id("pklAllProjects")
|
||||
id("pklJavaLibrary")
|
||||
id("pklJSpecify")
|
||||
id("pklPublishLibrary")
|
||||
}
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Predicate;
|
||||
import java.util.regex.Pattern;
|
||||
import org.jspecify.annotations.Nullable;
|
||||
import org.pkl.parser.syntax.Operator;
|
||||
import org.pkl.parser.syntax.generic.Node;
|
||||
import org.pkl.parser.syntax.generic.NodeType;
|
||||
@@ -274,14 +275,14 @@ final class Builder {
|
||||
|
||||
gatherFacts(node, flat, lambdaCount, methodCallCount, indexBeforeFirstMethodCall);
|
||||
|
||||
BiFunction<Node, Node, FormatNode> leadingSeparator =
|
||||
BiFunction<Node, Node, @Nullable FormatNode> leadingSeparator =
|
||||
(prev, next) -> {
|
||||
if (prev.type == NodeType.OPERATOR) return null;
|
||||
if (next.type == NodeType.OPERATOR) return line();
|
||||
return spaceOrLine();
|
||||
};
|
||||
|
||||
BiFunction<Node, Node, FormatNode> trailingSeparator =
|
||||
BiFunction<Node, Node, @Nullable FormatNode> trailingSeparator =
|
||||
(prev, next) -> {
|
||||
if (prev.type == NodeType.OPERATOR) return null;
|
||||
if (next.type == NodeType.OPERATOR) return lambdaCount[0] > 1 ? forceLine() : line();
|
||||
@@ -360,7 +361,7 @@ final class Builder {
|
||||
return new List[] {leading, trailing};
|
||||
}
|
||||
|
||||
private static boolean isMethodCall(Node node) {
|
||||
private static boolean isMethodCall(@Nullable Node node) {
|
||||
if (node == null || node.type != NodeType.UNQUALIFIED_ACCESS_EXPR) return false;
|
||||
for (var child : node.children) {
|
||||
if (child.type == NodeType.ARGUMENT_LIST) return true;
|
||||
@@ -574,7 +575,7 @@ final class Builder {
|
||||
return new Group(newId(), formatGeneric(node.children, spaceOrLine()));
|
||||
}
|
||||
|
||||
private FormatNode formatParameterList(Node node, Integer id) {
|
||||
private FormatNode formatParameterList(Node node, @Nullable Integer id) {
|
||||
if (node.children.size() == 2) return new Text("()");
|
||||
var groupId = id != null ? id : newId();
|
||||
var nodes =
|
||||
@@ -630,7 +631,7 @@ final class Builder {
|
||||
Node node, boolean hasTrailingLambda, boolean twoBy2) {
|
||||
var children = node.children;
|
||||
var shouldMultiline = shouldMultilineNodes(node, n -> isTerminal(n, ","));
|
||||
BiFunction<Node, Node, FormatNode> sep =
|
||||
BiFunction<Node, Node, @Nullable FormatNode> sep =
|
||||
(prev, next) -> shouldMultiline ? forceSpaceyLine() : spaceOrLine();
|
||||
if (twoBy2) {
|
||||
var pairs = pairArguments(children);
|
||||
@@ -906,6 +907,8 @@ final class Builder {
|
||||
var prevNoNewlines = noNewlines;
|
||||
var elems = cursor.takeUntilBefore(n -> isTerminalSingle(n, ")"));
|
||||
noNewlines = !isMultilineList(elems);
|
||||
//noinspection ConstantValue
|
||||
assert prev != null;
|
||||
var baseSep = getBaseSeparator(prev, elems.get(0));
|
||||
if (baseSep != null) result.add(baseSep);
|
||||
result.addAll(formatGeneric(elems, (FormatNode) null));
|
||||
@@ -1337,24 +1340,26 @@ final class Builder {
|
||||
|
||||
// --- formatGeneric overloads ---
|
||||
|
||||
private List<FormatNode> formatGeneric(List<Node> children, FormatNode separator) {
|
||||
private List<FormatNode> formatGeneric(List<Node> children, @Nullable FormatNode separator) {
|
||||
return formatGeneric(children, (prev, next) -> separator);
|
||||
}
|
||||
|
||||
private List<FormatNode> formatGeneric(
|
||||
List<Node> children, BiFunction<Node, Node, FormatNode> separatorFn) {
|
||||
List<Node> children, BiFunction<Node, Node, @Nullable FormatNode> separatorFn) {
|
||||
return formatGenericWithGen(children, separatorFn, null);
|
||||
}
|
||||
|
||||
private List<FormatNode> formatGenericWithGen(
|
||||
List<Node> children, FormatNode separator, BiFunction<Node, Node, FormatNode> generatorFn) {
|
||||
List<Node> children,
|
||||
@Nullable FormatNode separator,
|
||||
BiFunction<Node, @Nullable Node, FormatNode> generatorFn) {
|
||||
return formatGenericWithGen(children, (prev, next) -> separator, generatorFn);
|
||||
}
|
||||
|
||||
private List<FormatNode> formatGenericWithGen(
|
||||
List<Node> children,
|
||||
BiFunction<Node, Node, FormatNode> separatorFn,
|
||||
BiFunction<Node, Node, FormatNode> generatorFn) {
|
||||
BiFunction<Node, Node, @Nullable FormatNode> separatorFn,
|
||||
@Nullable BiFunction<Node, @Nullable Node, FormatNode> generatorFn) {
|
||||
// skip semicolons
|
||||
var filtered = new ArrayList<Node>(children.size());
|
||||
for (var child : children) {
|
||||
@@ -1423,13 +1428,13 @@ final class Builder {
|
||||
return base != null ? base : separator;
|
||||
}
|
||||
|
||||
private FormatNode getSeparator(
|
||||
Node prev, Node next, BiFunction<Node, Node, FormatNode> separatorFn) {
|
||||
private @Nullable FormatNode getSeparator(
|
||||
Node prev, Node next, BiFunction<Node, Node, @Nullable FormatNode> separatorFn) {
|
||||
var base = getBaseSeparator(prev, next);
|
||||
return base != null ? base : separatorFn.apply(prev, next);
|
||||
}
|
||||
|
||||
private FormatNode getBaseSeparator(Node prev, Node next) {
|
||||
private @Nullable FormatNode getBaseSeparator(Node prev, Node next) {
|
||||
if (endsInLineComment(prev)) {
|
||||
return linesBetween(prev, next) > 1 ? TWO_NEWLINES : mustForceLine();
|
||||
}
|
||||
@@ -1637,14 +1642,14 @@ final class Builder {
|
||||
return new Indent(List.of(nodes));
|
||||
}
|
||||
|
||||
private static Node firstProperChild(Node node) {
|
||||
private static @Nullable Node firstProperChild(Node node) {
|
||||
for (var child : node.children) {
|
||||
if (isProper(child)) return child;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Node lastProperNode(List<Node> nodes) {
|
||||
private static @Nullable Node lastProperNode(List<Node> nodes) {
|
||||
for (var i = nodes.size() - 1; i >= 0; i--) {
|
||||
if (isProper(nodes.get(i))) return nodes.get(i);
|
||||
}
|
||||
@@ -1699,7 +1704,7 @@ final class Builder {
|
||||
|
||||
static final class PeekableIterator<T> implements Iterator<T> {
|
||||
private final Iterator<T> iterator;
|
||||
private T peeked;
|
||||
private @Nullable T peeked;
|
||||
private boolean hasPeeked = false;
|
||||
|
||||
PeekableIterator(Iterator<T> iterator) {
|
||||
@@ -1710,6 +1715,7 @@ final class Builder {
|
||||
public T next() {
|
||||
if (hasPeeked) {
|
||||
hasPeeked = false;
|
||||
if (peeked == null) throw new NoSuchElementException();
|
||||
return peeked;
|
||||
}
|
||||
return iterator.next();
|
||||
@@ -1722,7 +1728,7 @@ final class Builder {
|
||||
|
||||
T peek() {
|
||||
if (!hasNext()) throw new NoSuchElementException();
|
||||
if (hasPeeked) return peeked;
|
||||
if (hasPeeked && peeked != null) return peeked;
|
||||
peeked = iterator.next();
|
||||
hasPeeked = true;
|
||||
return peeked;
|
||||
|
||||
@@ -37,8 +37,8 @@ final class Generator {
|
||||
node(node, Wrap.DETECT);
|
||||
}
|
||||
|
||||
@SuppressWarnings("StatementWithEmptyBody")
|
||||
private void node(FormatNode node, Wrap wrap) {
|
||||
//noinspection StatementWithEmptyBody
|
||||
if (node instanceof Empty) {
|
||||
// nothing
|
||||
} else if (node instanceof Nodes n) {
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
@NullMarked
|
||||
package org.pkl.formatter;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
Reference in New Issue
Block a user