comparingValuesUsing(
*
* Note that keys will always be compared with regular object equality ({@link Object#equals}).
*/
- public final class UsingCorrespondence {
+ public final class UsingCorrespondence {
private final Correspondence super A, ? super E> correspondence;
@@ -554,10 +566,10 @@ private UsingCorrespondence(Correspondence super A, ? super E> correspondence)
* Fails if the multimap does not contain an entry with the given key and a value that
* corresponds to the given value.
*/
- public void containsEntry(@Nullable Object expectedKey, @Nullable E expectedValue) {
- if (actual.containsKey(expectedKey)) {
+ public void containsEntry(@Nullable Object expectedKey, E expectedValue) {
+ if (checkNotNull(actual).containsKey(expectedKey)) {
// Found matching key.
- Collection actualValues = getCastActual().asMap().get(expectedKey);
+ Collection actualValues = checkNotNull(getCastActual().asMap().get(expectedKey));
Correspondence.ExceptionStore exceptions = Correspondence.ExceptionStore.forMapValues();
for (A actualValue : actualValues) {
if (correspondence.safeCompare(actualValue, expectedValue, exceptions)) {
@@ -647,9 +659,9 @@ public void containsEntry(@Nullable Object expectedKey, @Nullable E expectedValu
* Fails if the multimap contains an entry with the given key and a value that corresponds to
* the given value.
*/
- public void doesNotContainEntry(@Nullable Object excludedKey, @Nullable E excludedValue) {
- if (actual.containsKey(excludedKey)) {
- Collection actualValues = getCastActual().asMap().get(excludedKey);
+ public void doesNotContainEntry(@Nullable Object excludedKey, E excludedValue) {
+ if (checkNotNull(actual).containsKey(excludedKey)) {
+ Collection actualValues = checkNotNull(getCastActual().asMap().get(excludedKey));
List matchingValues = new ArrayList<>();
Correspondence.ExceptionStore exceptions = Correspondence.ExceptionStore.forMapValues();
for (A actualValue : actualValues) {
@@ -714,7 +726,8 @@ public Ordered containsExactlyEntriesIn(Multimap, ? extends E> expectedMultima
* public containsExactlyEntriesIn method. This is recommended by Effective Java item 31 (3rd
* edition).
*/
- private Ordered internalContainsExactlyEntriesIn(
+ @SuppressWarnings("deprecation") // TODO(b/134064106): design an alternative to no-arg check()
+ private Ordered internalContainsExactlyEntriesIn(
Multimap expectedMultimap) {
// Note: The non-fuzzy MultimapSubject.containsExactlyEntriesIn has a custom implementation
// and produces somewhat better failure messages simply asserting about the iterables of
@@ -724,8 +737,8 @@ private Ordered internalContainsExactlyEntriesIn(
// complexity for little gain.
return check()
.about(iterableEntries())
- .that(actual.entries())
- .comparingElementsUsing(new EntryCorrespondence(correspondence))
+ .that(checkNotNull(actual).entries())
+ .comparingElementsUsing(MultimapSubject.entryCorrespondence(correspondence))
.containsExactlyElementsIn(expectedMultimap.entries());
}
@@ -748,7 +761,8 @@ public Ordered containsAtLeastEntriesIn(Multimap, ? extends E> expectedMultima
* public containsAtLeastEntriesIn method. This is recommended by Effective Java item 31 (3rd
* edition).
*/
- private Ordered internalContainsAtLeastEntriesIn(
+ @SuppressWarnings("deprecation") // TODO(b/134064106): design an alternative to no-arg check()
+ private Ordered internalContainsAtLeastEntriesIn(
Multimap expectedMultimap) {
// Note: The non-fuzzy MultimapSubject.containsAtLeastEntriesIn has a custom implementation
// and produces somewhat better failure messages simply asserting about the iterables of
@@ -758,8 +772,8 @@ private Ordered internalContainsAtLeastEntriesIn(
// complexity for little gain.
return check()
.about(iterableEntries())
- .that(actual.entries())
- .comparingElementsUsing(new EntryCorrespondence(correspondence))
+ .that(checkNotNull(actual).entries())
+ .comparingElementsUsing(MultimapSubject.entryCorrespondence(correspondence))
.containsAtLeastElementsIn(expectedMultimap.entries());
}
@@ -797,30 +811,20 @@ public Ordered containsAtLeast(@Nullable Object k0, @Nullable E v0, @Nullable Ob
@SuppressWarnings("unchecked") // throwing ClassCastException is the correct behaviour
private Multimap, A> getCastActual() {
- return (Multimap, A>) actual;
+ return (Multimap, A>) checkNotNull(actual);
}
}
- private static final class EntryCorrespondence
- extends Correspondence, Map.Entry> {
-
- private final Correspondence super A, ? super E> valueCorrespondence;
-
- EntryCorrespondence(Correspondence super A, ? super E> valueCorrespondence) {
- this.valueCorrespondence = valueCorrespondence;
- }
-
- @Override
- public boolean compare(Map.Entry actual, Map.Entry expected) {
- return Objects.equal(actual.getKey(), expected.getKey())
- && valueCorrespondence.compare(actual.getValue(), expected.getValue());
- }
-
- @Override
- public String toString() {
- return lenientFormat(
- "has a key that is equal to and a value that %s the key and value of",
- valueCorrespondence);
- }
+ private static <
+ K extends @Nullable Object, A extends @Nullable Object, E extends @Nullable Object>
+ Correspondence, Map.Entry> entryCorrespondence(
+ Correspondence super A, ? super E> valueCorrespondence) {
+ return Correspondence.from(
+ (Map.Entry actual, Map.Entry expected) ->
+ Objects.equal(actual.getKey(), expected.getKey())
+ && valueCorrespondence.compare(actual.getValue(), expected.getValue()),
+ lenientFormat(
+ "has a key that is equal to and a value that %s the key and value of",
+ valueCorrespondence));
}
}
diff --git a/core/src/main/java/com/google/common/truth/MultisetSubject.java b/core/src/main/java/com/google/common/truth/MultisetSubject.java
index 40037fe38..264b30c89 100644
--- a/core/src/main/java/com/google/common/truth/MultisetSubject.java
+++ b/core/src/main/java/com/google/common/truth/MultisetSubject.java
@@ -16,9 +16,10 @@
package com.google.common.truth;
import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
import com.google.common.collect.Multiset;
-import org.checkerframework.checker.nullness.qual.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Propositions for {@link Multiset} subjects.
@@ -27,17 +28,17 @@
*/
public final class MultisetSubject extends IterableSubject {
- private final Multiset> actual;
+ private final @Nullable Multiset> actual;
MultisetSubject(FailureMetadata metadata, @Nullable Multiset> multiset) {
- super(metadata, multiset);
+ super(metadata, multiset, /* typeDescriptionOverride= */ "multiset");
this.actual = multiset;
}
/** Fails if the element does not have the given count. */
public final void hasCount(@Nullable Object element, int expectedCount) {
checkArgument(expectedCount >= 0, "expectedCount(%s) must be >= 0", expectedCount);
- int actualCount = ((Multiset>) actual).count(element);
+ int actualCount = checkNotNull(actual).count(element);
check("count(%s)", element).that(actualCount).isEqualTo(expectedCount);
}
}
diff --git a/core/src/main/java/com/google/common/truth/ObjectArraySubject.java b/core/src/main/java/com/google/common/truth/ObjectArraySubject.java
index 2b6184e42..712fc30a0 100644
--- a/core/src/main/java/com/google/common/truth/ObjectArraySubject.java
+++ b/core/src/main/java/com/google/common/truth/ObjectArraySubject.java
@@ -15,24 +15,25 @@
*/
package com.google.common.truth;
+import static com.google.common.base.Preconditions.checkNotNull;
+
import java.util.Arrays;
-import org.checkerframework.checker.nullness.qual.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* A Subject for {@code Object[]} and more generically {@code T[]}.
*
* @author Christian Gruber
*/
-public final class ObjectArraySubject extends AbstractArraySubject {
- private final T[] actual;
+public final class ObjectArraySubject extends AbstractArraySubject {
+ private final T @Nullable [] actual;
- ObjectArraySubject(
- FailureMetadata metadata, @Nullable T @Nullable [] o, @Nullable String typeDescription) {
+ ObjectArraySubject(FailureMetadata metadata, T @Nullable [] o, @Nullable String typeDescription) {
super(metadata, o, typeDescription);
this.actual = o;
}
public IterableSubject asList() {
- return checkNoNeedToDisplayBothValues("asList()").that(Arrays.asList(actual));
+ return checkNoNeedToDisplayBothValues("asList()").that(Arrays.asList(checkNotNull(actual)));
}
}
diff --git a/extensions/java8/src/main/java/com/google/common/truth/OptionalDoubleSubject.java b/core/src/main/java/com/google/common/truth/OptionalDoubleSubject.java
similarity index 75%
rename from extensions/java8/src/main/java/com/google/common/truth/OptionalDoubleSubject.java
rename to core/src/main/java/com/google/common/truth/OptionalDoubleSubject.java
index 4a9aa5f88..96403a4bc 100644
--- a/extensions/java8/src/main/java/com/google/common/truth/OptionalDoubleSubject.java
+++ b/core/src/main/java/com/google/common/truth/OptionalDoubleSubject.java
@@ -19,16 +19,19 @@
import static com.google.common.truth.Fact.simpleFact;
import java.util.OptionalDouble;
-import org.checkerframework.checker.nullness.qual.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Propositions for Java 8 {@link OptionalDouble} subjects.
*
* @author Ben Douglass
+ * @since 1.3.0 (previously part of {@code truth-java8-extension})
*/
+@SuppressWarnings("Java7ApiChecker") // used only from APIs with Java 8 in their signatures
+@IgnoreJRERequirement
public final class OptionalDoubleSubject extends Subject {
- private final OptionalDouble actual;
+ private final @Nullable OptionalDouble actual;
OptionalDoubleSubject(
FailureMetadata failureMetadata,
@@ -78,7 +81,18 @@ public void hasValue(double expected) {
}
}
- public static Subject.Factory optionalDoubles() {
+ /**
+ * Obsolete factory instance. This factory was previously necessary for assertions like {@code
+ * assertWithMessage(...).about(optionalDoubles()).that(optional)....}. Now, you can perform
+ * assertions like that without the {@code about(...)} call.
+ *
+ * @deprecated Instead of {@code about(optionalDoubles()).that(...)}, use just {@code that(...)}.
+ * Similarly, instead of {@code assertAbout(optionalDoubles()).that(...)}, use just {@code
+ * assertThat(...)}.
+ */
+ @Deprecated
+ @SuppressWarnings("InlineMeSuggester") // We want users to remove the surrounding call entirely.
+ public static Factory optionalDoubles() {
return (metadata, subject) -> new OptionalDoubleSubject(metadata, subject, "optionalDouble");
}
}
diff --git a/extensions/java8/src/main/java/com/google/common/truth/OptionalIntSubject.java b/core/src/main/java/com/google/common/truth/OptionalIntSubject.java
similarity index 72%
rename from extensions/java8/src/main/java/com/google/common/truth/OptionalIntSubject.java
rename to core/src/main/java/com/google/common/truth/OptionalIntSubject.java
index 957594f72..37921f8b4 100644
--- a/extensions/java8/src/main/java/com/google/common/truth/OptionalIntSubject.java
+++ b/core/src/main/java/com/google/common/truth/OptionalIntSubject.java
@@ -19,15 +19,18 @@
import static com.google.common.truth.Fact.simpleFact;
import java.util.OptionalInt;
-import org.checkerframework.checker.nullness.qual.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Propositions for Java 8 {@link OptionalInt} subjects.
*
* @author Ben Douglass
+ * @since 1.3.0 (previously part of {@code truth-java8-extension})
*/
+@SuppressWarnings("Java7ApiChecker") // used only from APIs with Java 8 in their signatures
+@IgnoreJRERequirement
public final class OptionalIntSubject extends Subject {
- private final OptionalInt actual;
+ private final @Nullable OptionalInt actual;
OptionalIntSubject(
FailureMetadata failureMetadata,
@@ -71,7 +74,18 @@ public void hasValue(int expected) {
}
}
- public static Subject.Factory optionalInts() {
+ /**
+ * Obsolete factory instance. This factory was previously necessary for assertions like {@code
+ * assertWithMessage(...).about(optionalInts()).that(optional)....}. Now, you can perform
+ * assertions like that without the {@code about(...)} call.
+ *
+ * @deprecated Instead of {@code about(optionalInts()).that(...)}, use just {@code that(...)}.
+ * Similarly, instead of {@code assertAbout(optionalInts()).that(...)}, use just {@code
+ * assertThat(...)}.
+ */
+ @Deprecated
+ @SuppressWarnings("InlineMeSuggester") // We want users to remove the surrounding call entirely.
+ public static Factory optionalInts() {
return (metadata, subject) -> new OptionalIntSubject(metadata, subject, "optionalInt");
}
}
diff --git a/extensions/java8/src/main/java/com/google/common/truth/OptionalLongSubject.java b/core/src/main/java/com/google/common/truth/OptionalLongSubject.java
similarity index 72%
rename from extensions/java8/src/main/java/com/google/common/truth/OptionalLongSubject.java
rename to core/src/main/java/com/google/common/truth/OptionalLongSubject.java
index 9b57b9a4a..237706b6c 100644
--- a/extensions/java8/src/main/java/com/google/common/truth/OptionalLongSubject.java
+++ b/core/src/main/java/com/google/common/truth/OptionalLongSubject.java
@@ -19,15 +19,18 @@
import static com.google.common.truth.Fact.simpleFact;
import java.util.OptionalLong;
-import org.checkerframework.checker.nullness.qual.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Propositions for Java 8 {@link OptionalLong} subjects.
*
* @author Ben Douglass
+ * @since 1.3.0 (previously part of {@code truth-java8-extension})
*/
+@SuppressWarnings("Java7ApiChecker") // used only from APIs with Java 8 in their signatures
+@IgnoreJRERequirement
public final class OptionalLongSubject extends Subject {
- private final OptionalLong actual;
+ private final @Nullable OptionalLong actual;
OptionalLongSubject(
FailureMetadata failureMetadata,
@@ -71,7 +74,18 @@ public void hasValue(long expected) {
}
}
- public static Subject.Factory optionalLongs() {
+ /**
+ * Obsolete factory instance. This factory was previously necessary for assertions like {@code
+ * assertWithMessage(...).about(optionalLongs()).that(optional)....}. Now, you can perform
+ * assertions like that without the {@code about(...)} call.
+ *
+ * @deprecated Instead of {@code about(optionalLongs()).that(...)}, use just {@code that(...)}.
+ * Similarly, instead of {@code assertAbout(optionalLongs()).that(...)}, use just {@code
+ * assertThat(...)}.
+ */
+ @Deprecated
+ @SuppressWarnings("InlineMeSuggester") // We want users to remove the surrounding call entirely.
+ public static Factory optionalLongs() {
return (metadata, subject) -> new OptionalLongSubject(metadata, subject, "optionalLong");
}
}
diff --git a/extensions/java8/src/main/java/com/google/common/truth/OptionalSubject.java b/core/src/main/java/com/google/common/truth/OptionalSubject.java
similarity index 69%
rename from extensions/java8/src/main/java/com/google/common/truth/OptionalSubject.java
rename to core/src/main/java/com/google/common/truth/OptionalSubject.java
index 1b9fb5c96..246888041 100644
--- a/extensions/java8/src/main/java/com/google/common/truth/OptionalSubject.java
+++ b/core/src/main/java/com/google/common/truth/OptionalSubject.java
@@ -19,19 +19,24 @@
import static com.google.common.truth.Fact.simpleFact;
import java.util.Optional;
-import org.checkerframework.checker.nullness.qual.Nullable;
+import org.jspecify.annotations.Nullable;
/**
* Propositions for Java 8 {@link Optional} subjects.
*
* @author Christian Gruber
+ * @since 1.3.0 (previously part of {@code truth-java8-extension})
*/
+@SuppressWarnings("Java7ApiChecker") // used only from APIs with Java 8 in their signatures
+@IgnoreJRERequirement
public final class OptionalSubject extends Subject {
- private final Optional> actual;
+ @SuppressWarnings("NullableOptional") // Truth always accepts nulls, no matter the type
+ private final @Nullable Optional> actual;
OptionalSubject(
FailureMetadata failureMetadata,
- @Nullable Optional> subject,
+ @SuppressWarnings("NullableOptional") // Truth always accepts nulls, no matter the type
+ @Nullable Optional> subject,
@Nullable String typeDescription) {
super(failureMetadata, subject, typeDescription);
this.actual = subject;
@@ -68,7 +73,7 @@ public void isEmpty() {
* assertThat(myOptional.get()).contains("foo");
* }
*/
- public void hasValue(Object expected) {
+ public void hasValue(@Nullable Object expected) {
if (expected == null) {
throw new NullPointerException("Optional cannot have a null value.");
}
@@ -81,7 +86,18 @@ public void hasValue(Object expected) {
}
}
- public static Subject.Factory> optionals() {
+ /**
+ * Obsolete factory instance. This factory was previously necessary for assertions like {@code
+ * assertWithMessage(...).about(paths()).that(path)....}. Now, you can perform assertions like
+ * that without the {@code about(...)} call.
+ *
+ * @deprecated Instead of {@code about(optionals()).that(...)}, use just {@code that(...)}.
+ * Similarly, instead of {@code assertAbout(optionals()).that(...)}, use just {@code
+ * assertThat(...)}.
+ */
+ @Deprecated
+ @SuppressWarnings("InlineMeSuggester") // We want users to remove the surrounding call entirely.
+ public static Factory> optionals() {
return (metadata, subject) -> new OptionalSubject(metadata, subject, "optional");
}
}
diff --git a/core/src/main/java/com/google/common/truth/Ordered.java b/core/src/main/java/com/google/common/truth/Ordered.java
index 00ed0cc3c..2f7efed38 100644
--- a/core/src/main/java/com/google/common/truth/Ordered.java
+++ b/core/src/main/java/com/google/common/truth/Ordered.java
@@ -15,6 +15,7 @@
*/
package com.google.common.truth;
+
/**
* Returned by calls like {@link IterableSubject#containsExactly}, {@code Ordered} lets the caller
* additionally check that the expected elements were present in the order they were passed to the
diff --git a/core/src/main/java/com/google/common/truth/PathSubject.java b/core/src/main/java/com/google/common/truth/PathSubject.java
new file mode 100644
index 000000000..5957779d1
--- /dev/null
+++ b/core/src/main/java/com/google/common/truth/PathSubject.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2017 Google, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.google.common.truth;
+
+import com.google.common.annotations.GwtIncompatible;
+import com.google.j2objc.annotations.J2ObjCIncompatible;
+import java.nio.file.Path;
+import org.jspecify.annotations.Nullable;
+
+/**
+ * Assertions for {@link Path} instances.
+ *
+ * @since 1.3.0 (previously part of {@code truth-java8-extension})
+ */
+@GwtIncompatible
+@J2ObjCIncompatible
+@J2ktIncompatible
+public final class PathSubject extends Subject {
+ PathSubject(FailureMetadata failureMetadata, @Nullable Path actual) {
+ super(failureMetadata, actual);
+ }
+
+ /**
+ * Obsolete factory instance. This factory was previously necessary for assertions like {@code
+ * assertWithMessage(...).about(intStreams()).that(stream)....}. Now, you can perform assertions
+ * like that without the {@code about(...)} call.
+ *
+ * @deprecated Instead of {@code about(paths()).that(...)}, use just {@code that(...)}. Similarly,
+ * instead of {@code assertAbout(paths()).that(...)}, use just {@code assertThat(...)}.
+ */
+ @Deprecated
+ @SuppressWarnings("InlineMeSuggester") // We want users to remove the surrounding call entirely.
+ public static Factory paths() {
+ return PathSubject::new;
+ }
+}
diff --git a/core/src/main/java/com/google/common/truth/Platform.java b/core/src/main/java/com/google/common/truth/Platform.java
index c0719697a..f3e9059f6 100644
--- a/core/src/main/java/com/google/common/truth/Platform.java
+++ b/core/src/main/java/com/google/common/truth/Platform.java
@@ -15,6 +15,7 @@
*/
package com.google.common.truth;
+import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Suppliers.memoize;
import static com.google.common.base.Throwables.throwIfUnchecked;
import static com.google.common.truth.DiffUtils.generateUnifiedDiff;
@@ -23,6 +24,7 @@
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
import com.google.common.base.Throwables;
import com.google.common.collect.ImmutableList;
import java.lang.reflect.Constructor;
@@ -30,7 +32,7 @@
import java.lang.reflect.Method;
import java.util.List;
import java.util.regex.Pattern;
-import org.checkerframework.checker.nullness.qual.Nullable;
+import org.jspecify.annotations.Nullable;
import org.junit.ComparisonFailure;
import org.junit.rules.TestRule;
@@ -54,20 +56,23 @@ static boolean containsMatch(String actual, String regex) {
}
/**
- * Returns an array containing all of the exceptions that were suppressed to deliver the given
+ * Returns an array containing all the exceptions that were suppressed to deliver the given
* exception. If suppressed exceptions are not supported (pre-Java 1.7), an empty array will be
* returned.
*/
static Throwable[] getSuppressed(Throwable throwable) {
try {
Method getSuppressed = throwable.getClass().getMethod("getSuppressed");
- return (Throwable[]) getSuppressed.invoke(throwable);
+ return (Throwable[]) checkNotNull(getSuppressed.invoke(throwable));
} catch (NoSuchMethodException e) {
return new Throwable[0];
} catch (IllegalAccessException e) {
- throw new RuntimeException(e);
+ // We're calling a public method on a public class.
+ throw newLinkageError(e);
} catch (InvocationTargetException e) {
- throw new RuntimeException(e);
+ throwIfUnchecked(e.getCause());
+ // getSuppressed has no `throws` clause.
+ throw newLinkageError(e);
}
}
@@ -160,20 +165,12 @@ private static ImmutableList splitLines(String s) {
abstract static class PlatformComparisonFailure extends ComparisonFailure {
private final String message;
- /** Separate cause field, in case initCause() fails. */
- private final @Nullable Throwable cause;
-
PlatformComparisonFailure(
String message, String expected, String actual, @Nullable Throwable cause) {
super(message, expected, actual);
this.message = message;
- this.cause = cause;
- try {
- initCause(cause);
- } catch (IllegalStateException alreadyInitializedBecauseOfHarmonyBug) {
- // See Truth.SimpleAssertionError.
- }
+ initCause(cause);
}
@Override
@@ -181,17 +178,11 @@ public final String getMessage() {
return message;
}
- @Override
- @SuppressWarnings("UnsynchronizedOverridesSynchronized")
- public final Throwable getCause() {
- return cause;
- }
-
// To avoid printing the class name before the message.
// TODO(cpovirk): Write a test that fails without this. Ditto for SimpleAssertionError.
@Override
public final String toString() {
- return getLocalizedMessage();
+ return checkNotNull(getLocalizedMessage());
}
}
@@ -204,7 +195,7 @@ static String floatToString(float value) {
}
/** Turns a non-double, non-float object into a string. */
- static String stringValueOfNonFloatingPoint(Object o) {
+ static String stringValueOfNonFloatingPoint(@Nullable Object o) {
return String.valueOf(o);
}
@@ -215,7 +206,7 @@ static String getStackTraceAsString(Throwable throwable) {
/** Tests if current platform is Android. */
static boolean isAndroid() {
- return System.getProperty("java.runtime.name").contains("Android");
+ return checkNotNull(System.getProperty("java.runtime.name", "")).contains("Android");
}
/**
@@ -308,27 +299,28 @@ static boolean isKotlinRange(Iterable> iterable) {
// (If the class isn't available, then nothing could be an instance of ClosedRange.)
}
- private static final Supplier