Skip to content

Commit

Permalink
Merge 441de37 into 4e88ba3
Browse files Browse the repository at this point in the history
  • Loading branch information
lazaroclapp committed May 26, 2020
2 parents 4e88ba3 + 441de37 commit 17ff023
Show file tree
Hide file tree
Showing 5 changed files with 73 additions and 1 deletion.
6 changes: 6 additions & 0 deletions nullaway/src/main/java/com/uber/nullaway/LibraryModels.java
Expand Up @@ -64,6 +64,12 @@ public interface LibraryModels {
*/
ImmutableSetMultimap<MethodRef, Integer> nullImpliesTrueParameters();

/**
* @return map from the names of non-null-querying methods to the indexes of the arguments that
* are compared against null.
*/
ImmutableSetMultimap<MethodRef, Integer> nullImpliesFalseParameters();

/** @return set of library methods that may return null */
ImmutableSet<MethodRef> nullableReturns();

Expand Down
Expand Up @@ -126,7 +126,7 @@ public NullnessHint onDataflowVisitMethodInvocation(
Symbol.MethodSymbol callee = ASTHelpers.getSymbol(node.getTree());
Preconditions.checkNotNull(callee);
setUnconditionalArgumentNullness(bothUpdates, node.getArguments(), callee, context);
setConditionalArgumentNullness(elseUpdates, node.getArguments(), callee, context);
setConditionalArgumentNullness(thenUpdates, elseUpdates, node.getArguments(), callee, context);
if (getOptLibraryModels(context).hasNonNullReturn(callee, types)) {
return NullnessHint.FORCE_NONNULL;
} else if (getOptLibraryModels(context).hasNullableReturn(callee, types)) {
Expand All @@ -137,15 +137,21 @@ public NullnessHint onDataflowVisitMethodInvocation(
}

private void setConditionalArgumentNullness(
AccessPathNullnessPropagation.Updates thenUpdates,
AccessPathNullnessPropagation.Updates elseUpdates,
List<Node> arguments,
Symbol.MethodSymbol callee,
Context context) {
Set<Integer> nullImpliesTrueParameters =
getOptLibraryModels(context).nullImpliesTrueParameters(callee);
Set<Integer> nullImpliesFalseParameters =
getOptLibraryModels(context).nullImpliesFalseParameters(callee);
for (AccessPath accessPath : accessPathsAtIndexes(nullImpliesTrueParameters, arguments)) {
elseUpdates.set(accessPath, NONNULL);
}
for (AccessPath accessPath : accessPathsAtIndexes(nullImpliesFalseParameters, arguments)) {
thenUpdates.set(accessPath, NONNULL);
}
}

private static Iterable<AccessPath> accessPathsAtIndexes(
Expand Down Expand Up @@ -448,6 +454,11 @@ private static class DefaultLibraryModels implements LibraryModels {
0)
.build();

private static final ImmutableSetMultimap<MethodRef, Integer> NULL_IMPLIES_FALSE_PARAMETERS =
new ImmutableSetMultimap.Builder<MethodRef, Integer>()
.put(methodRef("java.util.Objects", "nonNull(java.lang.Object)"), 0)
.build();

private static final ImmutableSet<MethodRef> NULLABLE_RETURNS =
new ImmutableSet.Builder<MethodRef>()
.add(methodRef("java.lang.ref.Reference", "get()"))
Expand Down Expand Up @@ -537,6 +548,11 @@ public ImmutableSetMultimap<MethodRef, Integer> nullImpliesTrueParameters() {
return NULL_IMPLIES_TRUE_PARAMETERS;
}

@Override
public ImmutableSetMultimap<MethodRef, Integer> nullImpliesFalseParameters() {
return NULL_IMPLIES_FALSE_PARAMETERS;
}

@Override
public ImmutableSet<MethodRef> nullableReturns() {
return NULLABLE_RETURNS;
Expand All @@ -558,6 +574,8 @@ private static class CombinedLibraryModels implements LibraryModels {

private final ImmutableSetMultimap<MethodRef, Integer> nullImpliesTrueParameters;

private final ImmutableSetMultimap<MethodRef, Integer> nullImpliesFalseParameters;

private final ImmutableSet<MethodRef> nullableReturns;

private final ImmutableSet<MethodRef> nonNullReturns;
Expand All @@ -571,6 +589,8 @@ public CombinedLibraryModels(Iterable<LibraryModels> models) {
new ImmutableSetMultimap.Builder<>();
ImmutableSetMultimap.Builder<MethodRef, Integer> nullImpliesTrueParametersBuilder =
new ImmutableSetMultimap.Builder<>();
ImmutableSetMultimap.Builder<MethodRef, Integer> nullImpliesFalseParametersBuilder =
new ImmutableSetMultimap.Builder<>();
ImmutableSet.Builder<MethodRef> nullableReturnsBuilder = new ImmutableSet.Builder<>();
ImmutableSet.Builder<MethodRef> nonNullReturnsBuilder = new ImmutableSet.Builder<>();
for (LibraryModels libraryModels : models) {
Expand All @@ -588,6 +608,10 @@ public CombinedLibraryModels(Iterable<LibraryModels> models) {
libraryModels.nullImpliesTrueParameters().entries()) {
nullImpliesTrueParametersBuilder.put(entry);
}
for (Map.Entry<MethodRef, Integer> entry :
libraryModels.nullImpliesFalseParameters().entries()) {
nullImpliesFalseParametersBuilder.put(entry);
}
for (MethodRef name : libraryModels.nullableReturns()) {
nullableReturnsBuilder.add(name);
}
Expand All @@ -599,6 +623,7 @@ public CombinedLibraryModels(Iterable<LibraryModels> models) {
explicitlyNullableParameters = explicitlyNullableParametersBuilder.build();
nonNullParameters = nonNullParametersBuilder.build();
nullImpliesTrueParameters = nullImpliesTrueParametersBuilder.build();
nullImpliesFalseParameters = nullImpliesFalseParametersBuilder.build();
nullableReturns = nullableReturnsBuilder.build();
nonNullReturns = nonNullReturnsBuilder.build();
}
Expand All @@ -623,6 +648,11 @@ public ImmutableSetMultimap<MethodRef, Integer> nullImpliesTrueParameters() {
return nullImpliesTrueParameters;
}

@Override
public ImmutableSetMultimap<MethodRef, Integer> nullImpliesFalseParameters() {
return nullImpliesFalseParameters;
}

@Override
public ImmutableSet<MethodRef> nullableReturns() {
return nullableReturns;
Expand Down Expand Up @@ -674,6 +704,7 @@ public boolean nameNotPresent(Symbol.MethodSymbol symbol) {
private final NameIndexedMap<ImmutableSet<Integer>> explicitlyNullableParams;
private final NameIndexedMap<ImmutableSet<Integer>> nonNullParams;
private final NameIndexedMap<ImmutableSet<Integer>> nullImpliesTrueParams;
private final NameIndexedMap<ImmutableSet<Integer>> nullImpliesFalseParams;
private final NameIndexedMap<Boolean> nullableRet;
private final NameIndexedMap<Boolean> nonNullRet;

Expand All @@ -684,6 +715,8 @@ public OptimizedLibraryModels(LibraryModels models, Context context) {
makeOptimizedIntSetLookup(names, models.explicitlyNullableParameters());
nonNullParams = makeOptimizedIntSetLookup(names, models.nonNullParameters());
nullImpliesTrueParams = makeOptimizedIntSetLookup(names, models.nullImpliesTrueParameters());
nullImpliesFalseParams =
makeOptimizedIntSetLookup(names, models.nullImpliesFalseParameters());
nullableRet = makeOptimizedBoolLookup(names, models.nullableReturns());
nonNullRet = makeOptimizedBoolLookup(names, models.nonNullReturns());
}
Expand Down Expand Up @@ -712,6 +745,10 @@ ImmutableSet<Integer> nullImpliesTrueParameters(Symbol.MethodSymbol symbol) {
return lookupImmutableSet(symbol, nullImpliesTrueParams);
}

ImmutableSet<Integer> nullImpliesFalseParameters(Symbol.MethodSymbol symbol) {
return lookupImmutableSet(symbol, nullImpliesFalseParams);
}

private ImmutableSet<Integer> lookupImmutableSet(
Symbol.MethodSymbol symbol, NameIndexedMap<ImmutableSet<Integer>> lookup) {
ImmutableSet<Integer> result = lookup.get(symbol);
Expand Down
19 changes: 19 additions & 0 deletions nullaway/src/test/java/com/uber/nullaway/NullAwayTest.java
Expand Up @@ -2473,4 +2473,23 @@ public void testMapWithCustomPut() { // See https://github.com/uber/NullAway/iss
"}")
.doTest();
}

@Test
public void defaultLibraryModelsObjectNonNull() {
compilationHelper
.addSourceLines(
"Test.java",
"package com.uber;",
"import java.util.Objects;",
"import javax.annotation.Nullable;",
"public class Test {",
" String foo(@Nullable Object o) {",
" if (Objects.nonNull(o)) {",
" return o.toString();",
" };",
" return \"\";",
" }",
"}")
.doTest();
}
}
Expand Up @@ -47,6 +47,11 @@ public ImmutableSetMultimap<MethodRef, Integer> nullImpliesTrueParameters() {
.build();
}

@Override
public ImmutableSetMultimap<MethodRef, Integer> nullImpliesFalseParameters() {
return ImmutableSetMultimap.of();
}

@Override
public ImmutableSet<MethodRef> nullableReturns() {
return ImmutableSet.of();
Expand Down
Expand Up @@ -51,6 +51,11 @@ public ImmutableSetMultimap<MethodRef, Integer> nullImpliesTrueParameters() {
return ImmutableSetMultimap.of();
}

@Override
public ImmutableSetMultimap<MethodRef, Integer> nullImpliesFalseParameters() {
return ImmutableSetMultimap.of();
}

@Override
public ImmutableSet<MethodRef> nullableReturns() {
return ImmutableSet.of();
Expand Down

0 comments on commit 17ff023

Please sign in to comment.