Skip to content

Commit

Permalink
Merge branch 'master' into jspecify-array-index
Browse files Browse the repository at this point in the history
  • Loading branch information
msridhar committed Jun 18, 2024
2 parents 9be512b + a4ce249 commit 5df5697
Show file tree
Hide file tree
Showing 14 changed files with 217 additions and 132 deletions.
4 changes: 2 additions & 2 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionSha256Sum=544c35d6bd849ae8a5ed0bcea39ba677dc40f49df7d1835561582da2009b961d
distributionUrl=https\://services.gradle.org/distributions/gradle-8.7-bin.zip
distributionSha256Sum=a4b4158601f8636cdeeab09bd76afb640030bb5b144aafe261a5e8af027dc612
distributionUrl=https\://services.gradle.org/distributions/gradle-8.8-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
2 changes: 1 addition & 1 deletion gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
# Darwin, MinGW, and NonStop.
#
# (3) This script is generated from the Groovy template
# https://github.com/gradle/gradle/blob/HEAD/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# https://github.com/gradle/gradle/blob/HEAD/platforms/jvm/plugins-application/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt
# within the Gradle project.
#
# You can find Gradle at https://github.com/gradle/gradle/.
Expand Down
23 changes: 15 additions & 8 deletions nullaway/src/main/java/com/uber/nullaway/NullAway.java
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
import com.uber.nullaway.generics.GenericsChecks;
import com.uber.nullaway.handlers.Handler;
import com.uber.nullaway.handlers.Handlers;
import com.uber.nullaway.handlers.MethodAnalysisContext;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
Expand Down Expand Up @@ -384,7 +385,7 @@ public Description matchMethodInvocation(MethodInvocationTree tree, VisitorState
return Description.NO_MATCH;
}
Symbol.MethodSymbol methodSymbol = getSymbolForMethodInvocation(tree);
handler.onMatchMethodInvocation(this, tree, state, methodSymbol);
handler.onMatchMethodInvocation(tree, new MethodAnalysisContext(this, state, methodSymbol));
// assuming this list does not include the receiver
List<? extends ExpressionTree> actualParams = tree.getArguments();
return handleInvocation(tree, state, methodSymbol, actualParams);
Expand Down Expand Up @@ -644,7 +645,7 @@ public Description matchMethod(MethodTree tree, VisitorState state) {
// overridden method (if overridden method is in an annotated
// package)
Symbol.MethodSymbol methodSymbol = ASTHelpers.getSymbol(tree);
handler.onMatchMethod(this, tree, state, methodSymbol);
handler.onMatchMethod(tree, new MethodAnalysisContext(this, state, methodSymbol));
boolean isOverriding = ASTHelpers.hasAnnotation(methodSymbol, "java.lang.Override", state);
boolean exhaustiveOverride = config.exhaustiveOverride();
if (isOverriding || !exhaustiveOverride) {
Expand Down Expand Up @@ -712,8 +713,13 @@ public Description matchParameterizedType(ParameterizedTypeTree tree, VisitorSta
return Description.NO_MATCH;
}
if (config.isJSpecifyMode()) {
GenericsChecks.checkInstantiationForParameterizedTypedTree(
tree, state, this, config, handler);
Symbol baseClass = ASTHelpers.getSymbol(tree);
boolean isNullUnmarked =
baseClass != null && codeAnnotationInfo.isSymbolUnannotated(baseClass, config, handler);
if (!isNullUnmarked) {
GenericsChecks.checkInstantiationForParameterizedTypedTree(
tree, state, this, config, handler);
}
}
return Description.NO_MATCH;
}
Expand Down Expand Up @@ -952,7 +958,8 @@ public Description matchLambdaExpression(LambdaExpressionTree tree, VisitorState
// we need to update environment mapping before running the handler, as some handlers
// (like Rx nullability) run dataflow analysis
updateEnvironmentMapping(state.getPath(), state);
handler.onMatchLambdaExpression(this, tree, state, funcInterfaceMethod);
handler.onMatchLambdaExpression(
tree, new MethodAnalysisContext(this, state, funcInterfaceMethod));
if (codeAnnotationInfo.isSymbolUnannotated(funcInterfaceMethod, config, handler)) {
return Description.NO_MATCH;
}
Expand Down Expand Up @@ -996,7 +1003,7 @@ public Description matchMemberReference(MemberReferenceTree tree, VisitorState s
Symbol.MethodSymbol referencedMethod = ASTHelpers.getSymbol(tree);
Symbol.MethodSymbol funcInterfaceSymbol =
NullabilityUtil.getFunctionalInterfaceMethod(tree, state.getTypes());
handler.onMatchMethodReference(this, tree, state, referencedMethod);
handler.onMatchMethodReference(tree, new MethodAnalysisContext(this, state, referencedMethod));
return checkOverriding(funcInterfaceSymbol, referencedMethod, tree, state);
}

Expand Down Expand Up @@ -1440,7 +1447,7 @@ private boolean okToReadBeforeInitialized(TreePath path, VisitorState state) {
} else {
castToNonNullArg =
handler.castToNonNullArgumentPositionsForMethod(
this, state, methodSymbol, arguments, null);
arguments, null, new MethodAnalysisContext(this, state, methodSymbol));
}
if (castToNonNullArg != null && leaf.equals(arguments.get(castToNonNullArg))) {
return true;
Expand Down Expand Up @@ -1813,7 +1820,7 @@ private Description checkCastToNonNullTakesNullable(
} else {
castToNonNullPosition =
handler.castToNonNullArgumentPositionsForMethod(
this, state, methodSymbol, actualParams, null);
actualParams, null, new MethodAnalysisContext(this, state, methodSymbol));
}
if (castToNonNullPosition != null) {
ExpressionTree actual = actualParams.get(castToNonNullPosition);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,22 +60,22 @@ protected AbstractFieldContractHandler(String annotName) {
/**
* Verifies that the method being processed adheres to the annotation specifications.
*
* @param analysis NullAway instance.
* @param tree Method tree under processing.
* @param state Error Prone {@link VisitorState}.
* @param methodSymbol Processing method symbol.
* @param methodAnalysisContext The MethodAnalysisContext object
*/
@Override
public void onMatchMethod(
NullAway analysis, MethodTree tree, VisitorState state, Symbol.MethodSymbol methodSymbol) {
public void onMatchMethod(MethodTree tree, MethodAnalysisContext methodAnalysisContext) {

Symbol.MethodSymbol methodSymbol = methodAnalysisContext.methodSymbol();
VisitorState state = methodAnalysisContext.state();
Set<String> annotationContent =
NullabilityUtil.getAnnotationValueArray(methodSymbol, annotName, false);
boolean isAnnotated = annotationContent != null;
boolean isValid =
isAnnotated
&& validateAnnotationSyntax(
castToNonNull(annotationContent), analysis, tree, state, methodSymbol)
&& validateAnnotationSemantics(analysis, state, tree, methodSymbol);
castToNonNull(annotationContent), tree, methodAnalysisContext)
&& validateAnnotationSemantics(tree, methodAnalysisContext);
if (isAnnotated && !isValid) {
return;
}
Expand All @@ -90,8 +90,9 @@ && validateAnnotationSyntax(
} else {
fieldNames = Collections.emptySet();
}
validateOverridingRules(fieldNames, analysis, state, tree, closestOverriddenMethod);
super.onMatchMethod(analysis, tree, state, methodSymbol);
validateOverridingRules(
fieldNames, methodAnalysisContext.analysis(), state, tree, closestOverriddenMethod);
super.onMatchMethod(tree, methodAnalysisContext);
}

/**
Expand All @@ -117,9 +118,10 @@ protected abstract void validateOverridingRules(
* Validates that a method implementation matches the semantics of the annotation.
*
* @return Returns true, if the annotation conforms to the semantic rules.
* @param methodAnalysisContext The MethodAnalysisContext object
*/
protected abstract boolean validateAnnotationSemantics(
NullAway analysis, VisitorState state, MethodTree tree, Symbol.MethodSymbol methodSymbol);
MethodTree tree, MethodAnalysisContext methodAnalysisContext);

/**
* Validates whether the parameter inside annotation conforms to the syntax rules. Parameters must
Expand All @@ -137,14 +139,13 @@ protected abstract boolean validateAnnotationSemantics(
* <p>
*
* @return Returns true, if the annotation conforms to the syntax rules.
* @param methodAnalysisContext The MethodAnalysisContext object
*/
protected boolean validateAnnotationSyntax(
Set<String> content,
NullAway analysis,
MethodTree tree,
VisitorState state,
Symbol.MethodSymbol methodSymbol) {
Set<String> content, MethodTree tree, MethodAnalysisContext methodAnalysisContext) {
String message;
VisitorState state = methodAnalysisContext.state();
NullAway analysis = methodAnalysisContext.analysis();
if (content.isEmpty()) {
// we should not allow useless annotations.
message =
Expand Down Expand Up @@ -187,7 +188,8 @@ protected boolean validateAnnotationSyntax(
fieldName = fieldName.substring(fieldName.lastIndexOf(".") + 1);
}
}
Symbol.ClassSymbol classSymbol = castToNonNull(ASTHelpers.enclosingClass(methodSymbol));
Symbol.ClassSymbol classSymbol =
castToNonNull(ASTHelpers.enclosingClass(methodAnalysisContext.methodSymbol()));
VariableElement field = getInstanceFieldOfClass(classSymbol, fieldName);
if (field == null) {
message =
Expand All @@ -197,6 +199,7 @@ protected boolean validateAnnotationSyntax(
+ fieldName
+ " in class "
+ classSymbol.getSimpleName();

state.reportMatch(
analysis
.getErrorBuilder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,35 +73,25 @@ public void onMatchTopLevelClass(
}

@Override
public void onMatchMethod(
NullAway analysis, MethodTree tree, VisitorState state, Symbol.MethodSymbol methodSymbol) {
public void onMatchMethod(MethodTree tree, MethodAnalysisContext methodAnalysisContext) {
// NoOp
}

@Override
public void onMatchMethodInvocation(
NullAway analysis,
MethodInvocationTree tree,
VisitorState state,
Symbol.MethodSymbol methodSymbol) {
MethodInvocationTree tree, MethodAnalysisContext methodAnalysisContext) {
// NoOp
}

@Override
public void onMatchLambdaExpression(
NullAway analysis,
LambdaExpressionTree tree,
VisitorState state,
Symbol.MethodSymbol methodSymbol) {
LambdaExpressionTree tree, MethodAnalysisContext methodAnalysisContext) {
// NoOp
}

@Override
public void onMatchMethodReference(
NullAway analysis,
MemberReferenceTree tree,
VisitorState state,
Symbol.MethodSymbol methodSymbol) {
MemberReferenceTree tree, MethodAnalysisContext methodAnalysisContext) {
// NoOp
}

Expand Down Expand Up @@ -238,11 +228,9 @@ public MethodInvocationNode onCFGBuildPhase1AfterVisitMethodInvocation(
@Override
@Nullable
public Integer castToNonNullArgumentPositionsForMethod(
NullAway analysis,
VisitorState state,
Symbol.MethodSymbol methodSymbol,
List<? extends ExpressionTree> actualParams,
@Nullable Integer previousArgumentPosition) {
@Nullable Integer previousArgumentPosition,
MethodAnalysisContext methodAnalysisContext) {
// NoOp
return previousArgumentPosition;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,43 +80,33 @@ public void onMatchTopLevelClass(
}

@Override
public void onMatchMethod(
NullAway analysis, MethodTree tree, VisitorState state, Symbol.MethodSymbol methodSymbol) {
public void onMatchMethod(MethodTree tree, MethodAnalysisContext methodAnalysisContext) {
for (Handler h : handlers) {
h.onMatchMethod(analysis, tree, state, methodSymbol);
h.onMatchMethod(tree, methodAnalysisContext);
}
}

@Override
public void onMatchLambdaExpression(
NullAway analysis,
LambdaExpressionTree tree,
VisitorState state,
Symbol.MethodSymbol methodSymbol) {
LambdaExpressionTree tree, MethodAnalysisContext methodAnalysisContext) {
for (Handler h : handlers) {
h.onMatchLambdaExpression(analysis, tree, state, methodSymbol);
h.onMatchLambdaExpression(tree, methodAnalysisContext);
}
}

@Override
public void onMatchMethodReference(
NullAway analysis,
MemberReferenceTree tree,
VisitorState state,
Symbol.MethodSymbol methodSymbol) {
MemberReferenceTree tree, MethodAnalysisContext methodAnalysisContext) {
for (Handler h : handlers) {
h.onMatchMethodReference(analysis, tree, state, methodSymbol);
h.onMatchMethodReference(tree, methodAnalysisContext);
}
}

@Override
public void onMatchMethodInvocation(
NullAway analysis,
MethodInvocationTree tree,
VisitorState state,
Symbol.MethodSymbol methodSymbol) {
MethodInvocationTree tree, MethodAnalysisContext methodAnalysisContext) {
for (Handler h : handlers) {
h.onMatchMethodInvocation(analysis, tree, state, methodSymbol);
h.onMatchMethodInvocation(tree, methodAnalysisContext);
}
}

Expand Down Expand Up @@ -310,15 +300,13 @@ public MethodInvocationNode onCFGBuildPhase1AfterVisitMethodInvocation(
@Override
@Nullable
public Integer castToNonNullArgumentPositionsForMethod(
NullAway analysis,
VisitorState state,
Symbol.MethodSymbol methodSymbol,
List<? extends ExpressionTree> actualParams,
@Nullable Integer previousArgumentPosition) {
@Nullable Integer previousArgumentPosition,
MethodAnalysisContext methodAnalysisContext) {
for (Handler h : handlers) {
previousArgumentPosition =
h.castToNonNullArgumentPositionsForMethod(
analysis, state, methodSymbol, actualParams, previousArgumentPosition);
actualParams, previousArgumentPosition, methodAnalysisContext);
}
return previousArgumentPosition;
}
Expand Down
Loading

0 comments on commit 5df5697

Please sign in to comment.