diff --git a/nullaway/src/test/java/com/uber/nullaway/Java8Tests.java b/nullaway/src/test/java/com/uber/nullaway/Java8Tests.java index 954367ad10..d21168c922 100644 --- a/nullaway/src/test/java/com/uber/nullaway/Java8Tests.java +++ b/nullaway/src/test/java/com/uber/nullaway/Java8Tests.java @@ -3,31 +3,487 @@ import org.junit.Test; public class Java8Tests extends NullAwayTestsBase { - @SuppressWarnings("deprecation") @Test public void java8PositiveCases() { - defaultCompilationHelper.addSourceFile("testdata/NullAwayJava8PositiveCases.java").doTest(); + defaultCompilationHelper + .addSourceLines( + "NullAwayJava8PositiveCases.java", + """ + package com.uber.nullaway.testdata; + + import io.reactivex.functions.BiFunction; + import io.reactivex.functions.Function; + import javax.annotation.Nonnull; + import javax.annotation.Nullable; + + public class NullAwayJava8PositiveCases { + + @FunctionalInterface + interface RetNonNullFunction { + + Object getVal(); + } + + public static void testRetNonNull() { + RetNonNullFunction p = + () -> { + // BUG: Diagnostic contains: returning @Nullable expression from method with + return null; + }; + p.getVal(); + } + + @FunctionalInterface + interface NullableParamFunction { + + U takeVal(@Nullable T x); + } + + @FunctionalInterface + interface NonNullParamFunction { + + String takeVal(Object x); + } + + static void testNullableParam() { + // BUG: Diagnostic contains: dereferenced expression x is @Nullable + NullableParamFunction n = (x) -> x.toString(); + // BUG: Diagnostic contains: parameter x is @NonNull, but parameter in functional interface + NullableParamFunction n2 = (Object x) -> x.toString(); + // BUG: Diagnostic contains: dereferenced expression x is @Nullable + NonNullParamFunction n3 = (@Nullable Object x) -> x.toString(); + // BUG: Diagnostic contains: parameter x is @NonNull, but parameter in functional interface + NullableParamFunction n4 = (@Nonnull Object x) -> x.toString(); + } + + static void testAnnoatedThirdParty() { + // BUG: Diagnostic contains: returning @Nullable expression from method with @NonNull return + Function f1 = (x) -> null; // io.reactivex.(Bi)Function is anotated + Function f2 = + (x) -> { + // BUG: Diagnostic contains: returning @Nullable expression from method with @NonNull + return null; + }; + // BUG: Diagnostic contains: returning @Nullable expression from method with @NonNull return + BiFunction f3 = (x, y) -> null; + } + + //////////////////////// + // method references // + //////////////////////// + + interface Function { + R apply(T t); + } + + static R map(T t, Function fun) { + return fun.apply(t); + } + + static U applyTakeVal(NullableParamFunction nn) { + return nn.takeVal(null); + } + + @Nullable + static Object returnNull(String t) { + return null; + } + + static String derefParam(Object o) { + return o.toString(); + } + + static void testRefsToStaticMethods() { + String ex = "hi"; + // BUG: Diagnostic contains: referenced method returns @Nullable, but functional + map(ex, NullAwayJava8PositiveCases::returnNull); + // BUG: Diagnostic contains: parameter o of referenced method is @NonNull, but + applyTakeVal(NullAwayJava8PositiveCases::derefParam); + } + + @FunctionalInterface + interface NullableSecondParamFunction { + + String takeVal(T x, @Nullable Object y); + } + + static String applyDoubleTakeVal(NullableSecondParamFunction ns, T firstParam) { + return ns.takeVal(firstParam, null); + } + + static class MethodContainer { + + @Nullable + Object returnNull(String t) { + return null; + } + + @Nullable + String returnNullWithNullableParam(@Nullable Object t) { + return null; + } + + String derefSecondParam(Object w, Object z) { + return z.toString(); + } + + String derefParam(Object p) { + return p.toString(); + } + + String makeStr() { + return "buzz"; + } + + void testRefsToInstanceMethods() { + String ex = "bye"; + MethodContainer m = new MethodContainer(); + // BUG: Diagnostic contains: referenced method returns @Nullable, but functional + map(ex, m::returnNull); + // BUG: Diagnostic contains: parameter z of referenced method is @NonNull, but + applyDoubleTakeVal(m::derefSecondParam, new Object()); + // BUG: Diagnostic contains: parameter p of referenced method is @NonNull, but parameter in + applyDoubleTakeVal(MethodContainer::derefParam, m); + // BUG: Diagnostic contains: referenced method returns @Nullable, but functional interface + applyDoubleTakeVal(MethodContainer::returnNullWithNullableParam, m); + // BUG: Diagnostic contains: unbound instance method reference cannot be used + applyTakeVal(MethodContainer::makeStr); + } + } + + static class MethodContainerSub extends MethodContainer { + @Override + String derefSecondParam(Object w, @Nullable Object z) { + return "" + ((z != null) ? z.hashCode() : 10); + } + + void testSuperRef() { + // BUG: Diagnostic contains: parameter z of referenced method is @NonNull, but parameter + applyDoubleTakeVal(super::derefSecondParam, new Object()); + } + } + + static class ConstructorRefs { + + public ConstructorRefs(Object p) {} + + class Inner { + + public Inner(Object q) {} + } + + void testConstRefs() { + // BUG: Diagnostic contains: parameter p of referenced method is @NonNull, but parameter + applyTakeVal(ConstructorRefs::new); + // BUG: Diagnostic contains: parameter q of referenced method is @NonNull, but parameter + applyTakeVal(Inner::new); + } + } + } + + """) + .doTest(); } - @SuppressWarnings("deprecation") @Test public void java8NegativeCases() { - defaultCompilationHelper.addSourceFile("testdata/NullAwayJava8NegativeCases.java").doTest(); + defaultCompilationHelper + .addSourceLines( + "NullAwayJava8NegativeCases.java", + """ + package com.uber.nullaway.testdata; + + import java.util.Collections; + import java.util.Comparator; + import java.util.List; + import java.util.function.BiFunction; + import javax.annotation.Nullable; + + public class NullAwayJava8NegativeCases { + + @FunctionalInterface + interface RetNullableFunction { + + @Nullable + Object getVal(); + } + + public static void testLambda() { + RetNullableFunction p = + () -> { + return null; + }; + p.getVal(); + } + + @FunctionalInterface + interface NonNullParamFunction { + + String takeVal(Object x); + } + + @FunctionalInterface + interface NullableParamFunction { + + U takeVal(@Nullable T x); + } + + static void testNonNullParam() { + NonNullParamFunction n = (x) -> x.toString(); + NonNullParamFunction n2 = (@Nullable Object x) -> (x == null) ? "null" : x.toString(); + NullableParamFunction n3 = (@Nullable Object x) -> (x == null) ? "null" : x.toString(); + NullableParamFunction n4 = (x) -> (x == null) ? "null" : x.toString(); + } + + static void testBuiltIn() { + java.util.function.Function foo = (x) -> x.toString(); + BiFunction bar = (x, y) -> x.toString() + y.toString(); + java.util.function.Function foo2 = (x) -> null; // java.util.Function is + // unnanotated + java.util.function.Function foo3 = + (x) -> { + return null; + }; + } + + static class Size { + public Size(int h, int w) { + this.height = h; + this.width = w; + } + + public final int height; + public final int width; + } + + static void testSort(List intList, List sizeList) { + Collections.sort( + intList, + (a, b) -> { + return (b - a); + }); + Collections.sort( + intList, + (a, b) -> { + return a; + }); + Collections.sort( + sizeList, + (a, b) -> { + int aPixels = a.height * a.width; + int bPixels = b.height * b.width; + if (bPixels < aPixels) { + return -1; + } + if (bPixels > aPixels) { + return 1; + } + return 0; + }); + } + + static Comparator testLambdaExpressionsAreNotNull() { + return (a, b) -> { + return (b - a); + }; + } + + @FunctionalInterface + interface VoidFunction { + + void doSomething(); + } + + static void wrapDoSomething() { + RetNullableFunction r = () -> null; + VoidFunction v = () -> r.getVal(); + v.doSomething(); + } + + //////////////////////// + // method references // + //////////////////////// + + interface MyFunction { + R apply(T t); + } + + static R map(T t, MyFunction fun) { + return fun.apply(t); + } + + static U applyTakeVal(NullableParamFunction nn) { + return nn.takeVal(null); + } + + static Object returnNonNull(String t) { + return new Object(); + } + + static String derefParam(@Nullable Object o) { + return o != null ? o.toString() : ""; + } + + static void testRefsToStaticMethods() { + String ex = "hi"; + map(ex, NullAwayJava8NegativeCases::returnNonNull); + applyTakeVal(NullAwayJava8NegativeCases::derefParam); + } + + @FunctionalInterface + interface NullableSecondParamFunction { + + String takeVal(T x, @Nullable Object y); + } + + static String applyDoubleTakeVal(NullableSecondParamFunction ns, T firstParam) { + return ns.takeVal(firstParam, null); + } + + static class MethodContainer { + + Object returnNonNull(String t) { + return new Object(); + } + + String returnNonNullWithNullableParam(@Nullable Object t) { + return ""; + } + + String derefSecondParam(Object w, @Nullable Object z) { + return z != null ? z.toString() : w.toString(); + } + + String derefSecondParam2(Object w, Object z) { + return z.toString(); + } + + String derefParam(@Nullable Object p) { + return (p != null) ? p.toString() : ""; + } + + String makeStr() { + return "buzz"; + } + + void testRefsToInstanceMethods() { + String ex = "bye"; + MethodContainer m = new MethodContainer(); + map(ex, m::returnNonNull); + applyDoubleTakeVal(m::derefSecondParam, new Object()); + applyDoubleTakeVal(MethodContainer::derefParam, m); + applyDoubleTakeVal(MethodContainer::returnNonNullWithNullableParam, m); + map(this, MethodContainer::makeStr); + } + } + + static class MethodContainerSub extends MethodContainer { + @Override + String derefSecondParam2(Object w, @Nullable Object z) { + return "" + ((z != null) ? z.hashCode() : 10); + } + + void testOverrideWithMethodRef() { + applyDoubleTakeVal(this::derefSecondParam2, new Object()); + } + } + + static class ConstructorRefs { + + public ConstructorRefs(@Nullable Object p) {} + + class Inner { + + public Inner(@Nullable Object q) {} + } + + void testConstRefs() { + applyTakeVal(ConstructorRefs::new); + applyTakeVal(Inner::new); + } + } + } + + """) + .doTest(); } - @SuppressWarnings("deprecation") @Test public void functionalMethodSuperInterface() { defaultCompilationHelper - .addSourceFile("testdata/NullAwaySuperFunctionalInterface.java") + .addSourceLines( + "NullAwaySuperFunctionalInterface.java", + """ + package com.uber.nullaway.testdata; + + public class NullAwaySuperFunctionalInterface { + + public void passLambda() { + runLambda1(() -> {}); + runLambda2(() -> {}); + } + + private void runLambda1(F1 f) { + f.call(); + } + + private void runLambda2(F2 f) { + f.call(); + } + + @FunctionalInterface + private static interface F2 extends M0, F1 {} + + private static interface M0 {} + + @FunctionalInterface + private static interface F1 extends F0 {} + + @FunctionalInterface + private static interface F0 { + void call(); + } + } + + """) .doTest(); } - @SuppressWarnings("deprecation") @Test public void functionalMethodOverrideSuperInterface() { defaultCompilationHelper - .addSourceFile("testdata/NullAwayOverrideFunctionalInterfaces.java") + .addSourceLines( + "NullAwayOverrideFunctionalInterfaces.java", + """ + package com.uber.nullaway.testdata; + + import java.util.function.ToIntFunction; + + public class NullAwayOverrideFunctionalInterfaces { + + public void test() { + call(str -> 42); + } + + private int call(ObjToInt f) { + return f.call("The answer to life the universe and everything"); + } + + @FunctionalInterface + private static interface ObjToInt extends ObjToIntE, ToIntFunction { + @Override + default int applyAsInt(T t) { + return call(t); + } + } + + @FunctionalInterface + private static interface ObjToIntE { + int call(T t) throws E; + } + } + + """) .doTest(); } diff --git a/nullaway/src/test/java/com/uber/nullaway/ThriftTests.java b/nullaway/src/test/java/com/uber/nullaway/ThriftTests.java index 176e6bf2c5..b96c1a38ff 100644 --- a/nullaway/src/test/java/com/uber/nullaway/ThriftTests.java +++ b/nullaway/src/test/java/com/uber/nullaway/ThriftTests.java @@ -3,7 +3,6 @@ import java.util.Arrays; import org.junit.Test; -@SuppressWarnings("deprecation") public class ThriftTests extends NullAwayTestsBase { @Test public void testThriftIsSet() { @@ -175,7 +174,42 @@ public void testThriftAndCastToNonNull() { "-XepOpt:NullAway:CastToNonNullMethod=com.uber.nullaway.testdata.Util.castToNonNull", "-XepOpt:NullAway:TreatGeneratedAsUnannotated=true", "-XepOpt:NullAway:AcknowledgeRestrictiveAnnotations=true")) - .addSourceFile("testdata/Util.java") + .addSourceLines( + "Util.java", + """ + package com.uber.nullaway.testdata; + + import javax.annotation.Nullable; + + public class Util { + + public static T castToNonNull(@Nullable T x) { + if (x == null) { + throw new RuntimeException(); + } + return x; + } + + public static T castToNonNull(@Nullable T x, String msg) { + if (x == null) { + throw new RuntimeException(msg); + } + return x; + } + + public static T castToNonNull(String msg, @Nullable T x, int counter) { + // counter is needed to distinguish this method from the previous one when T == String + if (x == null) { + throw new RuntimeException(msg); + } + return x; + } + + public static T id(T x) { + return x; + } + } + """) .addSourceLines("TBase.java", "package org.apache.thrift;", "public interface TBase {}") .addSourceLines( "GeneratedClass.java", diff --git a/nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwayJava8NegativeCases.java b/nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwayJava8NegativeCases.java deleted file mode 100644 index e6a456ade6..0000000000 --- a/nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwayJava8NegativeCases.java +++ /dev/null @@ -1,234 +0,0 @@ -/* - * Copyright (c) 2017 Uber Technologies, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.uber.nullaway.testdata; - -import java.util.Collections; -import java.util.Comparator; -import java.util.List; -import java.util.function.BiFunction; -import javax.annotation.Nullable; - -public class NullAwayJava8NegativeCases { - - @FunctionalInterface - interface RetNullableFunction { - - @Nullable - Object getVal(); - } - - public static void testLambda() { - RetNullableFunction p = - () -> { - return null; - }; - p.getVal(); - } - - @FunctionalInterface - interface NonNullParamFunction { - - String takeVal(Object x); - } - - @FunctionalInterface - interface NullableParamFunction { - - U takeVal(@Nullable T x); - } - - static void testNonNullParam() { - NonNullParamFunction n = (x) -> x.toString(); - NonNullParamFunction n2 = (@Nullable Object x) -> (x == null) ? "null" : x.toString(); - NullableParamFunction n3 = (@Nullable Object x) -> (x == null) ? "null" : x.toString(); - NullableParamFunction n4 = (x) -> (x == null) ? "null" : x.toString(); - } - - static void testBuiltIn() { - java.util.function.Function foo = (x) -> x.toString(); - BiFunction bar = (x, y) -> x.toString() + y.toString(); - java.util.function.Function foo2 = (x) -> null; // java.util.Function is - // unnanotated - java.util.function.Function foo3 = - (x) -> { - return null; - }; - } - - static class Size { - public Size(int h, int w) { - this.height = h; - this.width = w; - } - - public final int height; - public final int width; - } - - static void testSort(List intList, List sizeList) { - Collections.sort( - intList, - (a, b) -> { - return (b - a); - }); - Collections.sort( - intList, - (a, b) -> { - return a; - }); - Collections.sort( - sizeList, - (a, b) -> { - int aPixels = a.height * a.width; - int bPixels = b.height * b.width; - if (bPixels < aPixels) { - return -1; - } - if (bPixels > aPixels) { - return 1; - } - return 0; - }); - } - - static Comparator testLambdaExpressionsAreNotNull() { - return (a, b) -> { - return (b - a); - }; - } - - @FunctionalInterface - interface VoidFunction { - - void doSomething(); - } - - static void wrapDoSomething() { - RetNullableFunction r = () -> null; - VoidFunction v = () -> r.getVal(); - v.doSomething(); - } - - //////////////////////// - // method references // - //////////////////////// - - interface MyFunction { - R apply(T t); - } - - static R map(T t, MyFunction fun) { - return fun.apply(t); - } - - static U applyTakeVal(NullableParamFunction nn) { - return nn.takeVal(null); - } - - static Object returnNonNull(String t) { - return new Object(); - } - - static String derefParam(@Nullable Object o) { - return o != null ? o.toString() : ""; - } - - static void testRefsToStaticMethods() { - String ex = "hi"; - map(ex, NullAwayJava8NegativeCases::returnNonNull); - applyTakeVal(NullAwayJava8NegativeCases::derefParam); - } - - @FunctionalInterface - interface NullableSecondParamFunction { - - String takeVal(T x, @Nullable Object y); - } - - static String applyDoubleTakeVal(NullableSecondParamFunction ns, T firstParam) { - return ns.takeVal(firstParam, null); - } - - static class MethodContainer { - - Object returnNonNull(String t) { - return new Object(); - } - - String returnNonNullWithNullableParam(@Nullable Object t) { - return ""; - } - - String derefSecondParam(Object w, @Nullable Object z) { - return z != null ? z.toString() : w.toString(); - } - - String derefSecondParam2(Object w, Object z) { - return z.toString(); - } - - String derefParam(@Nullable Object p) { - return (p != null) ? p.toString() : ""; - } - - String makeStr() { - return "buzz"; - } - - void testRefsToInstanceMethods() { - String ex = "bye"; - MethodContainer m = new MethodContainer(); - map(ex, m::returnNonNull); - applyDoubleTakeVal(m::derefSecondParam, new Object()); - applyDoubleTakeVal(MethodContainer::derefParam, m); - applyDoubleTakeVal(MethodContainer::returnNonNullWithNullableParam, m); - map(this, MethodContainer::makeStr); - } - } - - static class MethodContainerSub extends MethodContainer { - @Override - String derefSecondParam2(Object w, @Nullable Object z) { - return "" + ((z != null) ? z.hashCode() : 10); - } - - void testOverrideWithMethodRef() { - applyDoubleTakeVal(this::derefSecondParam2, new Object()); - } - } - - static class ConstructorRefs { - - public ConstructorRefs(@Nullable Object p) {} - - class Inner { - - public Inner(@Nullable Object q) {} - } - - void testConstRefs() { - applyTakeVal(ConstructorRefs::new); - applyTakeVal(Inner::new); - } - } -} diff --git a/nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwayJava8PositiveCases.java b/nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwayJava8PositiveCases.java deleted file mode 100644 index ce38c4d1c7..0000000000 --- a/nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwayJava8PositiveCases.java +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (c) 2017 Uber Technologies, Inc. - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -package com.uber.nullaway.testdata; - -import io.reactivex.functions.BiFunction; -import io.reactivex.functions.Function; -import javax.annotation.Nonnull; -import javax.annotation.Nullable; - -public class NullAwayJava8PositiveCases { - - @FunctionalInterface - interface RetNonNullFunction { - - Object getVal(); - } - - public static void testRetNonNull() { - RetNonNullFunction p = - () -> { - // BUG: Diagnostic contains: returning @Nullable expression from method with - return null; - }; - p.getVal(); - } - - @FunctionalInterface - interface NullableParamFunction { - - U takeVal(@Nullable T x); - } - - @FunctionalInterface - interface NonNullParamFunction { - - String takeVal(Object x); - } - - static void testNullableParam() { - // BUG: Diagnostic contains: dereferenced expression x is @Nullable - NullableParamFunction n = (x) -> x.toString(); - // BUG: Diagnostic contains: parameter x is @NonNull, but parameter in functional interface - NullableParamFunction n2 = (Object x) -> x.toString(); - // BUG: Diagnostic contains: dereferenced expression x is @Nullable - NonNullParamFunction n3 = (@Nullable Object x) -> x.toString(); - // BUG: Diagnostic contains: parameter x is @NonNull, but parameter in functional interface - NullableParamFunction n4 = (@Nonnull Object x) -> x.toString(); - } - - static void testAnnoatedThirdParty() { - // BUG: Diagnostic contains: returning @Nullable expression from method with @NonNull return - Function f1 = (x) -> null; // io.reactivex.(Bi)Function is anotated - Function f2 = - (x) -> { - // BUG: Diagnostic contains: returning @Nullable expression from method with @NonNull - return null; - }; - // BUG: Diagnostic contains: returning @Nullable expression from method with @NonNull return - BiFunction f3 = (x, y) -> null; - } - - //////////////////////// - // method references // - //////////////////////// - - interface Function { - R apply(T t); - } - - static R map(T t, Function fun) { - return fun.apply(t); - } - - static U applyTakeVal(NullableParamFunction nn) { - return nn.takeVal(null); - } - - @Nullable - static Object returnNull(String t) { - return null; - } - - static String derefParam(Object o) { - return o.toString(); - } - - static void testRefsToStaticMethods() { - String ex = "hi"; - // BUG: Diagnostic contains: referenced method returns @Nullable, but functional - map(ex, NullAwayJava8PositiveCases::returnNull); - // BUG: Diagnostic contains: parameter o of referenced method is @NonNull, but - applyTakeVal(NullAwayJava8PositiveCases::derefParam); - } - - @FunctionalInterface - interface NullableSecondParamFunction { - - String takeVal(T x, @Nullable Object y); - } - - static String applyDoubleTakeVal(NullableSecondParamFunction ns, T firstParam) { - return ns.takeVal(firstParam, null); - } - - static class MethodContainer { - - @Nullable - Object returnNull(String t) { - return null; - } - - @Nullable - String returnNullWithNullableParam(@Nullable Object t) { - return null; - } - - String derefSecondParam(Object w, Object z) { - return z.toString(); - } - - String derefParam(Object p) { - return p.toString(); - } - - String makeStr() { - return "buzz"; - } - - void testRefsToInstanceMethods() { - String ex = "bye"; - MethodContainer m = new MethodContainer(); - // BUG: Diagnostic contains: referenced method returns @Nullable, but functional - map(ex, m::returnNull); - // BUG: Diagnostic contains: parameter z of referenced method is @NonNull, but - applyDoubleTakeVal(m::derefSecondParam, new Object()); - // BUG: Diagnostic contains: parameter p of referenced method is @NonNull, but parameter in - applyDoubleTakeVal(MethodContainer::derefParam, m); - // BUG: Diagnostic contains: referenced method returns @Nullable, but functional interface - applyDoubleTakeVal(MethodContainer::returnNullWithNullableParam, m); - // BUG: Diagnostic contains: unbound instance method reference cannot be used - applyTakeVal(MethodContainer::makeStr); - } - } - - static class MethodContainerSub extends MethodContainer { - @Override - String derefSecondParam(Object w, @Nullable Object z) { - return "" + ((z != null) ? z.hashCode() : 10); - } - - void testSuperRef() { - // BUG: Diagnostic contains: parameter z of referenced method is @NonNull, but parameter - applyDoubleTakeVal(super::derefSecondParam, new Object()); - } - } - - static class ConstructorRefs { - - public ConstructorRefs(Object p) {} - - class Inner { - - public Inner(Object q) {} - } - - void testConstRefs() { - // BUG: Diagnostic contains: parameter p of referenced method is @NonNull, but parameter - applyTakeVal(ConstructorRefs::new); - // BUG: Diagnostic contains: parameter q of referenced method is @NonNull, but parameter - applyTakeVal(Inner::new); - } - } -} diff --git a/nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwayOverrideFunctionalInterfaces.java b/nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwayOverrideFunctionalInterfaces.java deleted file mode 100644 index 99469ebc2d..0000000000 --- a/nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwayOverrideFunctionalInterfaces.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (c) 2017 Brandon Mintern - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.uber.nullaway.testdata; - -import java.util.function.ToIntFunction; - -public class NullAwayOverrideFunctionalInterfaces { - - public void test() { - call(str -> 42); - } - - private int call(ObjToInt f) { - return f.call("The answer to life the universe and everything"); - } - - @FunctionalInterface - private static interface ObjToInt extends ObjToIntE, ToIntFunction { - @Override - default int applyAsInt(T t) { - return call(t); - } - } - - @FunctionalInterface - private static interface ObjToIntE { - int call(T t) throws E; - } -} diff --git a/nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwaySuperFunctionalInterface.java b/nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwaySuperFunctionalInterface.java deleted file mode 100644 index c300ae1aaa..0000000000 --- a/nullaway/src/test/resources/com/uber/nullaway/testdata/NullAwaySuperFunctionalInterface.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2017 Brandon Mintern - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.uber.nullaway.testdata; - -public class NullAwaySuperFunctionalInterface { - - public void passLambda() { - runLambda1(() -> {}); - runLambda2(() -> {}); - } - - private void runLambda1(F1 f) { - f.call(); - } - - private void runLambda2(F2 f) { - f.call(); - } - - @FunctionalInterface - private static interface F2 extends M0, F1 {} - - private static interface M0 {} - - @FunctionalInterface - private static interface F1 extends F0 {} - - @FunctionalInterface - private static interface F0 { - void call(); - } -}