blob: 14aa8781a6ea94f57058995c45c55dd3af2633ae [file] [log] [blame]
/*
* 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 android.webkit.WebView;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableSortedSet;
import com.google.common.collect.Iterables;
import java.io.File;
import java.lang.ref.WeakReference;
import java.net.URLClassLoader;
import java.util.ArrayDeque;
import java.util.Collection;
import java.util.Deque;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import javax.annotation.Nullable;
import javax.lang.model.element.Element;
import javax.lang.model.util.Elements;
public class NullAwayNativeModels {
public static void referenceStuff() {
AtomicReference<Object> ref = new AtomicReference<>(null);
Object x = ref.get();
// BUG: Diagnostic contains: dereferenced expression
x.toString();
// BUG: Diagnostic contains: dereferenced expression
ref.get().toString();
WeakReference<Object> w = new WeakReference<Object>(x);
// BUG: Diagnostic contains: dereferenced expression
w.get().hashCode();
Exception e = new RuntimeException();
// BUG: Diagnostic contains: dereferenced expression
e.getMessage().hashCode();
}
// we will add bug annotations when we have full support for maps
public static void mapStuff(Map<Object, Object> m) {
// BUG: Diagnostic contains: dereferenced expression
m.get(new Object()).toString();
Object value = m.get(new Object());
// BUG: Diagnostic contains: dereferenced expression
value.toString();
HashMap<Object, Object> h = new HashMap<>();
Object value2 = h.get(new Object());
// BUG: Diagnostic contains: dereferenced expression
value2.toString();
}
static void mapGetNullCheck() {
Object x = new Object();
Map<Object, Object> m = new HashMap<>();
if (m.get(x) != null) {
m.get(x).toString();
}
HashMap<Object, Object> m2 = (HashMap) m;
if (m2.get(x) != null) {
m2.get(x).hashCode();
}
}
static void mapContainsKeyCheck() {
Object x = new Object();
Map<Object, Object> m = new HashMap<>();
if (m.containsKey(x)) {
m.get(x).toString();
}
if (m.containsKey(x)) {
Object y = m.get(x);
y.toString();
}
HashMap<Object, Object> m2 = (HashMap) m;
if (m2.containsKey(x)) {
m2.get(x).hashCode();
}
if (m2.containsKey(x)) {
Object y = m2.get(x);
y.hashCode();
}
Object z = new Object();
if (m2.containsKey(z)) {
// BUG: Diagnostic contains: dereferenced expression
m2.get(x).hashCode();
}
if (m2.containsKey(z)) {
Object y = m2.get(x);
// BUG: Diagnostic contains: dereferenced expression
y.hashCode();
}
// test negation
if (!m2.containsKey(x)) {
return;
}
Object y = m2.get(x);
y.hashCode();
}
static class Wrapper {
Object wrapped = new Object();
public Object getWrapped() {
return wrapped;
}
}
static final String KEY = "key";
static void harderMapContainsKeyCheck() {
Map m = new HashMap();
Wrapper w = new Wrapper();
if (m.containsKey(w.getWrapped())) {
m.get(w.getWrapped()).toString();
}
if (m.containsKey(w.getWrapped())) {
Object o = m.get(w.getWrapped());
o.toString();
}
if (m.get(w.getWrapped()) != null) {
m.get(w.getWrapped()).toString();
}
if (m.get(w.getWrapped()) != null) {
Object o = m.get(w.getWrapped());
o.toString();
}
if (m.containsKey(KEY)) {
m.get(KEY).toString();
}
if (m.containsKey(KEY)) {
Object o = m.get(KEY);
o.toString();
}
}
static void testLinkedHashMap() {
LinkedHashMap m = new LinkedHashMap();
Object o = new Object();
if (m.containsKey(o)) {
m.get(o).toString();
}
}
static void mapContainsKeyPut() {
Object x = new Object();
Map<Object, Object> m = new HashMap<>();
if (!m.containsKey(x)) {
m.put(x, new Object());
}
m.get(x).toString();
HashMap<Object, Object> m2 = new HashMap<>();
if (!m2.containsKey(x)) {
m2.put(x, x);
}
m2.get(x).toString();
Object y = new Object(), z = new Object();
if (!m2.containsKey(z)) {
m2.put(y, new Object());
}
// BUG: Diagnostic contains: dereferenced expression
m2.get(z).toString();
LinkedHashMap m3 = new LinkedHashMap();
if (!m3.containsKey(y)) {
m3.put(y, new Object());
}
m3.get(y).hashCode();
}
static void immutableMapStuff() {
ImmutableMap m = ImmutableMap.of();
Object res = m.get(new Object());
// BUG: Diagnostic contains: dereferenced expression
res.toString();
Object x = new Object();
if (m.containsKey(x)) {
m.get(x).toString();
}
}
static void failIfNull(@Nullable Object o1, @Nullable Object o2) {
org.junit.Assert.assertNotNull(o1);
o1.toString();
org.junit.Assert.assertNotNull("Null!", o2);
o2.toString();
org.junit.jupiter.api.Assertions.assertNotNull(o1);
o1.toString();
org.junit.jupiter.api.Assertions.assertNotNull(o2, "Null!");
o2.toString();
org.junit.jupiter.api.Assertions.assertNotNull(o2, () -> "Null!");
o2.toString();
}
static void nonNullParameters() {
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
NullAwayNativeModels.class.getResource(null);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
NullAwayNativeModels.class.isAssignableFrom(null);
String s = null;
// BUG: Diagnostic contains: passing @Nullable parameter 's' where @NonNull is required
File f = new File(s);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
URLClassLoader.newInstance(null, NullAwayNativeModels.class.getClassLoader());
}
static void elementStuff(Element e, Elements elems) {
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
e.getAnnotation(null);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
elems.getPackageElement(null);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
elems.getTypeElement(null);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
elems.getDocComment(null);
}
static void arrayDequeStuff() {
ArrayDeque<Object> d = new ArrayDeque<>();
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
d.add(null);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
d.addFirst(null);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
d.addLast(null);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
d.offerFirst(null);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
d.offerLast(null);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
d.offer(null);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
d.push(null);
Object[] o = null;
// BUG: Diagnostic contains: passing @Nullable parameter 'o' where @NonNull is required
d.toArray(o);
// this should be fine
d.toArray();
}
static void dequeStuff() {
Deque<Object> d = new ArrayDeque<>();
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
d.add(null);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
d.addFirst(null);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
d.addLast(null);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
d.offerFirst(null);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
d.offerLast(null);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
d.offer(null);
// BUG: Diagnostic contains: passing @Nullable parameter 'null' where @NonNull is required
d.push(null);
Object[] o = null;
// BUG: Diagnostic contains: passing @Nullable parameter 'o' where @NonNull is required
d.toArray(o);
}
static void guavaStuff() {
Collection<String> c = null;
Object o = null;
// BUG: Diagnostic contains: passing @Nullable parameter 'c' where @NonNull is required
ImmutableList.builder().addAll(c).build();
// BUG: Diagnostic contains: passing @Nullable parameter 'o' where @NonNull is required
ImmutableList.builder().add(o).build();
// BUG: Diagnostic contains: passing @Nullable parameter 'c' where @NonNull is required
ImmutableSet.builder().addAll(c).build();
// BUG: Diagnostic contains: passing @Nullable parameter 'o' where @NonNull is required
ImmutableSet.builder().add(o).build();
// BUG: Diagnostic contains: passing @Nullable parameter 'c' where @NonNull is required
ImmutableSortedSet.builder().addAll(c).build();
// BUG: Diagnostic contains: passing @Nullable parameter 'o' where @NonNull is required
ImmutableSortedSet.builder().add(o).build();
// BUG: Diagnostic contains: passing @Nullable parameter 'c' where @NonNull is required
Iterables.getFirst(c, "hi");
}
static void androidStuff() {
android.webkit.WebView webView = new WebView();
// BUG: Diagnostic contains: dereferenced expression
webView.getUrl().toString();
String s = null;
if (!android.text.TextUtils.isEmpty(s)) {
// no warning due to isEmpty check
s.hashCode();
}
}
static void apacheCommonsStuff() {
String s = null;
if (!org.apache.commons.lang.StringUtils.isEmpty(s)) {
// no warning due to isEmpty check
s.hashCode();
}
String t = null;
if (!org.apache.commons.lang3.StringUtils.isEmpty(t)) {
// no warning due to isEmpty check
t.hashCode();
}
}
}