com.google.errorprone.VisitorState Java Examples

The following examples show how to use com.google.errorprone.VisitorState. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: NullAway.java    From NullAway with MIT License 6 votes vote down vote up
@SuppressWarnings("unused")
private Description.Builder changeReturnNullabilityFix(
    Tree suggestTree, Description.Builder builder, VisitorState state) {
  if (suggestTree.getKind() != Tree.Kind.METHOD) {
    throw new RuntimeException("This should be a MethodTree");
  }
  SuggestedFix.Builder fixBuilder = SuggestedFix.builder();
  MethodTree methodTree = (MethodTree) suggestTree;
  int countNullableAnnotations = 0;
  for (AnnotationTree annotationTree : methodTree.getModifiers().getAnnotations()) {
    if (state.getSourceForNode(annotationTree.getAnnotationType()).endsWith("Nullable")) {
      fixBuilder.delete(annotationTree);
      countNullableAnnotations += 1;
    }
  }
  assert countNullableAnnotations > 1;
  return builder.addFix(fixBuilder.build());
}
 
Example #2
Source File: NullAway.java    From NullAway with MIT License 6 votes vote down vote up
private boolean relevantInitializerMethodOrBlock(
    TreePath enclosingBlockPath, VisitorState state) {
  Tree methodLambdaOrBlock = enclosingBlockPath.getLeaf();
  if (methodLambdaOrBlock instanceof LambdaExpressionTree) {
    return false;
  } else if (methodLambdaOrBlock instanceof MethodTree) {
    MethodTree methodTree = (MethodTree) methodLambdaOrBlock;
    if (isConstructor(methodTree) && !constructorInvokesAnother(methodTree, state)) return true;
    if (ASTHelpers.getSymbol(methodTree).isStatic()) {
      Set<MethodTree> staticInitializerMethods =
          class2Entities.get(enclosingClassSymbol(enclosingBlockPath)).staticInitializerMethods();
      return staticInitializerMethods.size() == 1
          && staticInitializerMethods.contains(methodTree);
    } else {
      Set<MethodTree> instanceInitializerMethods =
          class2Entities
              .get(enclosingClassSymbol(enclosingBlockPath))
              .instanceInitializerMethods();
      return instanceInitializerMethods.size() == 1
          && instanceInitializerMethods.contains(methodTree);
    }
  } else {
    // initializer or field declaration
    return true;
  }
}
 
Example #3
Source File: ErrorBuilder.java    From NullAway with MIT License 6 votes vote down vote up
/**
 * create an error description for a nullability warning
 *
 * @param errorMessage the error message object.
 * @param suggestTree the location at which a fix suggestion should be made
 * @param descriptionBuilder the description builder for the error.
 * @param state the visitor state (used for e.g. suppression finding).
 * @return the error description
 */
public Description createErrorDescription(
    ErrorMessage errorMessage,
    @Nullable Tree suggestTree,
    Description.Builder descriptionBuilder,
    VisitorState state) {
  Description.Builder builder = descriptionBuilder.setMessage(errorMessage.message);
  if (errorMessage.messageType.equals(GET_ON_EMPTY_OPTIONAL)
      && hasPathSuppression(state.getPath(), OPTIONAL_CHECK_NAME)) {
    return Description.NO_MATCH;
  }

  if (config.suggestSuppressions() && suggestTree != null) {
    builder = addSuggestedSuppression(errorMessage, suggestTree, builder);
  }
  // #letbuildersbuild
  return builder.build();
}
 
Example #4
Source File: AnnotationChecker.java    From grpc-java-api-checker with Apache License 2.0 6 votes vote down vote up
/**
 * Returns the description if tree is annotated.
 */
private Description match(Tree tree, VisitorState state) {
  Symbol symbol = ASTHelpers.getSymbol(tree);
  if (symbol == null) {
    return NO_MATCH;
  }
  AnnotationMirror annotation = findAnnotatedApi(symbol);
  if (annotation == null) {
    return NO_MATCH;
  }
  if (requireAnnotationOnMethodHierarchy && symbol instanceof MethodSymbol) {
    Set<MethodSymbol> superMethods =
            ASTHelpers.findSuperMethods((MethodSymbol) symbol, state.getTypes());
    for (MethodSymbol superMethod : superMethods) {
      AnnotationMirror superAnnotation = findAnnotatedApi(superMethod);
      if (superAnnotation == null) {
        return NO_MATCH;
      }
    }
  }
  return describe(tree, annotation);
}
 
Example #5
Source File: NullAway.java    From NullAway with MIT License 6 votes vote down vote up
private Symbol.MethodSymbol getSymbolOfSuperConstructor(
    Symbol.MethodSymbol anonClassConstructorSymbol, VisitorState state) {
  // get the statements in the body of the anonymous class constructor
  List<? extends StatementTree> statements =
      getTreesInstance(state).getTree(anonClassConstructorSymbol).getBody().getStatements();
  // there should be exactly one statement, which is an invocation of the super constructor
  if (statements.size() == 1) {
    StatementTree stmt = statements.get(0);
    if (stmt instanceof ExpressionStatementTree) {
      ExpressionTree expression = ((ExpressionStatementTree) stmt).getExpression();
      if (expression instanceof MethodInvocationTree) {
        return ASTHelpers.getSymbol((MethodInvocationTree) expression);
      }
    }
  }
  throw new IllegalStateException("unexpected anonymous class constructor body " + statements);
}
 
Example #6
Source File: NullAway.java    From NullAway with MIT License 6 votes vote down vote up
private Description checkPossibleUninitFieldRead(
    ExpressionTree tree,
    VisitorState state,
    Symbol symbol,
    TreePath path,
    TreePath enclosingBlockPath) {
  if (!fieldInitializedByPreviousInitializer(symbol, enclosingBlockPath, state)
      && !fieldAlwaysInitializedBeforeRead(symbol, path, state, enclosingBlockPath)) {
    ErrorMessage errorMessage =
        new ErrorMessage(
            MessageTypes.NONNULL_FIELD_READ_BEFORE_INIT,
            "read of @NonNull field " + symbol + " before initialization");
    return errorBuilder.createErrorDescription(errorMessage, buildDescription(tree), state);
  } else {
    return Description.NO_MATCH;
  }
}
 
Example #7
Source File: XPFlagCleaner.java    From piranha with Apache License 2.0 6 votes vote down vote up
@Override
public Description matchCompilationUnit(
    CompilationUnitTree compilationUnitTree, VisitorState visitorState) {
  if (!initialized && !disabled) {
    Preconditions.checkNotNull(
        flags,
        "The configuration-aware constructor should have been called at this point, and flags set to "
            + "a non-null value.");
    try {
      init(flags);
    } catch (PiranhaConfigurationException pe) {
      disabled = true;
    }
  }
  if (countsCollected) {
    // Clear out this info
    countsCollected = false;
    usageCounts = null;
    deletedUsages = null;
  }
  cuPath = visitorState.getPath();
  return Description.NO_MATCH;
}
 
Example #8
Source File: RestrictiveAnnotationHandler.java    From NullAway with MIT License 6 votes vote down vote up
@Override
public ImmutableSet<Integer> onUnannotatedInvocationGetNonNullPositions(
    NullAway analysis,
    VisitorState state,
    Symbol.MethodSymbol methodSymbol,
    List<? extends ExpressionTree> actualParams,
    ImmutableSet<Integer> nonNullPositions) {
  HashSet<Integer> positions = new HashSet<Integer>();
  positions.addAll(nonNullPositions);
  for (int i = 0; i < methodSymbol.getParameters().size(); ++i) {
    if (Nullness.paramHasNonNullAnnotation(methodSymbol, i, config)) {
      positions.add(i);
    }
  }
  return ImmutableSet.copyOf(positions);
}
 
Example #9
Source File: XPFlagCleaner.java    From piranha with Apache License 2.0 6 votes vote down vote up
@Override
public Description matchClass(ClassTree classTree, VisitorState visitorState) {
  Symbol.ClassSymbol classSymbol = ASTHelpers.getSymbol(classTree);
  if (classSymbol.getKind().equals(ElementKind.ENUM) && isTreatmentGroupEnum(classSymbol)) {
    treatmentGroupsEnum = classSymbol.fullname.toString();
    if (classSymbol.getNestingKind().isNested()) {
      return buildDescription(classTree).addFix(SuggestedFix.delete(classTree)).build();
    } else {
      String emptyEnum =
          PiranhaUtils.DELETE_REQUEST_COMMENT
              + "enum "
              + classSymbol.getSimpleName().toString()
              + " { }";
      return buildDescription(classTree)
          .addFix(SuggestedFix.replace(classTree, emptyEnum))
          .build();
    }
  }
  return Description.NO_MATCH;
}
 
Example #10
Source File: PrivateStaticFinalLoggers.java    From besu with Apache License 2.0 6 votes vote down vote up
@Override
public Description matchVariable(final VariableTree tree, final VisitorState state) {
  final Symbol.VarSymbol sym = ASTHelpers.getSymbol(tree);
  if (sym == null || sym.getKind() != ElementKind.FIELD) {
    return NO_MATCH;
  }
  if (sym.getModifiers()
      .containsAll(List.of(Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL))) {
    return NO_MATCH;
  }
  if (!isSubtype(
      getType(tree), state.getTypeFromString("org.apache.logging.log4j.Logger"), state)) {
    return NO_MATCH;
  }
  return buildDescription(tree)
      .addFix(addModifiers(tree, state, Modifier.PRIVATE, Modifier.STATIC, Modifier.FINAL))
      .build();
}
 
Example #11
Source File: StreamNullabilityPropagator.java    From NullAway with MIT License 6 votes vote down vote up
@Override
public void onMatchReturn(NullAway analysis, ReturnTree tree, VisitorState state) {
  // Figure out the enclosing method node
  TreePath enclosingMethodOrLambda =
      NullabilityUtil.findEnclosingMethodOrLambdaOrInitializer(state.getPath());
  if (enclosingMethodOrLambda == null) {
    throw new RuntimeException("no enclosing method, lambda or initializer!");
  }
  if (!(enclosingMethodOrLambda.getLeaf() instanceof MethodTree
      || enclosingMethodOrLambda.getLeaf() instanceof LambdaExpressionTree)) {
    throw new RuntimeException(
        "return statement outside of a method or lambda! (e.g. in an initializer block)");
  }
  Tree leaf = enclosingMethodOrLambda.getLeaf();
  if (filterMethodOrLambdaSet.contains(leaf)) {
    returnToEnclosingMethodOrLambda.put(tree, leaf);
    // We need to manually trigger the dataflow analysis to run on the filter method,
    // this ensures onDataflowVisitReturn(...) gets called for all return statements in this
    // method before
    // onDataflowInitialStore(...) is called for all successor methods in the observable chain.
    // Caching should prevent us from re-analyzing any given method.
    AccessPathNullnessAnalysis nullnessAnalysis = analysis.getNullnessAnalysis(state);
    nullnessAnalysis.forceRunOnMethod(new TreePath(state.getPath(), leaf), state.context);
  }
}
 
Example #12
Source File: XPFlagCleaner.java    From piranha with Apache License 2.0 6 votes vote down vote up
@Override
public Description matchVariable(VariableTree tree, VisitorState state) {
  Symbol sym = FindIdentifiers.findIdent(xpFlagName, state);
  // Check if this is the flag definition and remove it.
  if (sym != null && sym.isEnum() && sym.equals(ASTHelpers.getSymbol(tree))) {
    xpSym = sym;
    // Remove the flag symbol. This only works because the error prone patch is applied once
    // after all files have been analyzed, otherwise targets that use the flag but haven't been
    // cleaned up would be broken. We use replace with a position adjustment, to get rid of the
    // trailing "," if present on the parent.
    String enumAsStr = state.getSourceForNode(state.getPath().getParentPath().getLeaf());
    String varAsStrWithComma = tree.getName().toString() + ",";
    if (enumAsStr.contains(varAsStrWithComma)) {
      return buildDescription(tree).addFix(SuggestedFix.replace(tree, "", 0, 1)).build();
    } else {
      // Fallback for single/last enum variable detection
      return buildDescription(tree).addFix(SuggestedFix.delete(tree)).build();
    }
  } else if (sym == null
      && tree != null
      && ASTHelpers.getSymbol(tree) != null
      && xpFlagName.equals(ASTHelpers.getSymbol(tree).getConstantValue())) {
    return buildDescription(tree).addFix(SuggestedFix.delete(tree)).build();
  }
  return Description.NO_MATCH;
}
 
Example #13
Source File: NullAway.java    From NullAway with MIT License 6 votes vote down vote up
private boolean isInitializerMethod(VisitorState state, Symbol.MethodSymbol symbol) {
  if (ASTHelpers.hasDirectAnnotationWithSimpleName(symbol, "Initializer")
      || config.isKnownInitializerMethod(symbol)) {
    return true;
  }
  for (AnnotationMirror anno : symbol.getAnnotationMirrors()) {
    String annoTypeStr = anno.getAnnotationType().toString();
    if (config.isInitializerMethodAnnotation(annoTypeStr)) {
      return true;
    }
  }
  Symbol.MethodSymbol closestOverriddenMethod =
      getClosestOverriddenMethod(symbol, state.getTypes());
  if (closestOverriddenMethod == null) {
    return false;
  }
  return isInitializerMethod(state, closestOverriddenMethod);
}
 
Example #14
Source File: NullAway.java    From NullAway with MIT License 6 votes vote down vote up
private Description checkReturnExpression(
    Tree tree, ExpressionTree retExpr, Symbol.MethodSymbol methodSymbol, VisitorState state) {
  Type returnType = methodSymbol.getReturnType();
  if (returnType.isPrimitive()) {
    // check for unboxing
    return doUnboxingCheck(state, retExpr);
  }
  if (returnType.toString().equals("java.lang.Void")) {
    return Description.NO_MATCH;
  }
  if (NullabilityUtil.isUnannotated(methodSymbol, config)
      || Nullness.hasNullableAnnotation(methodSymbol, config)) {
    return Description.NO_MATCH;
  }
  if (mayBeNullExpr(state, retExpr)) {
    final ErrorMessage errorMessage =
        new ErrorMessage(
            MessageTypes.RETURN_NULLABLE,
            "returning @Nullable expression from method with @NonNull return type");

    return errorBuilder.createErrorDescriptionForNullAssignment(
        errorMessage, retExpr, buildDescription(tree), state);
  }
  return Description.NO_MATCH;
}
 
Example #15
Source File: NullAway.java    From NullAway with MIT License 5 votes vote down vote up
/** does the constructor invoke another constructor in the same class via this(...)? */
private boolean constructorInvokesAnother(MethodTree constructor, VisitorState state) {
  BlockTree body = constructor.getBody();
  List<? extends StatementTree> statements = body.getStatements();
  if (statements.size() > 0) {
    StatementTree statementTree = statements.get(0);
    if (isThisCall(statementTree, state)) {
      return true;
    }
  }
  return false;
}
 
Example #16
Source File: StreamNullabilityPropagator.java    From NullAway with MIT License 5 votes vote down vote up
private void handleChainFromFilter(
    StreamTypeRecord streamType,
    MethodInvocationTree observableDotFilter,
    Tree filterMethodOrLambda,
    VisitorState state) {
  MethodInvocationTree outerCallInChain = observableDotFilter;
  if (outerCallInChain == null) {
    return;
  }
  // Traverse the observable call chain out through any pass-through methods
  do {
    outerCallInChain = observableOuterCallInChain.get(outerCallInChain);
    // Check for a map method (which might be a pass-through method or the first method after a
    // pass-through chain)
    if (observableCallToInnerMethodOrLambda.containsKey(outerCallInChain)) {
      // Update mapToFilterMap
      Symbol.MethodSymbol mapMethod = ASTHelpers.getSymbol(outerCallInChain);
      if (streamType.isMapMethod(mapMethod)) {
        MaplikeToFilterInstanceRecord record =
            new MaplikeToFilterInstanceRecord(
                streamType.getMaplikeMethodRecord(mapMethod), filterMethodOrLambda);
        mapToFilterMap.put(observableCallToInnerMethodOrLambda.get(outerCallInChain), record);
      }
    }
  } while (outerCallInChain != null
      && streamType.matchesType(ASTHelpers.getReceiverType(outerCallInChain), state)
      && streamType.isPassthroughMethod(ASTHelpers.getSymbol(outerCallInChain)));
}
 
Example #17
Source File: ErrorBuilder.java    From NullAway with MIT License 5 votes vote down vote up
/**
 * create an error description for a generalized @Nullable value to @NonNull location assignment.
 *
 * <p>This includes: field assignments, method arguments and method returns
 *
 * @param errorMessage the error message object.
 * @param suggestTreeIfCastToNonNull the location at which a fix suggestion should be made if a
 *     castToNonNull method is available (usually the expression to cast)
 * @param descriptionBuilder the description builder for the error.
 * @param state the visitor state for the location which triggered the error (i.e. for suppression
 *     finding)
 * @return the error description.
 */
Description createErrorDescriptionForNullAssignment(
    ErrorMessage errorMessage,
    @Nullable Tree suggestTreeIfCastToNonNull,
    Description.Builder descriptionBuilder,
    VisitorState state) {
  if (config.getCastToNonNullMethod() != null) {
    return createErrorDescription(
        errorMessage, suggestTreeIfCastToNonNull, descriptionBuilder, state);
  } else {
    return createErrorDescription(
        errorMessage, suppressibleNode(state.getPath()), descriptionBuilder, state);
  }
}
 
Example #18
Source File: NullAway.java    From NullAway with MIT License 5 votes vote down vote up
public boolean nullnessFromDataflow(VisitorState state, ExpressionTree expr) {
  Nullness nullness =
      getNullnessAnalysis(state).getNullness(new TreePath(state.getPath(), expr), state.context);
  if (nullness == null) {
    // this may be unsound, like for field initializers
    // figure out if we care
    return false;
  }
  return nullnessToBool(nullness);
}
 
Example #19
Source File: LibraryModelsHandler.java    From NullAway with MIT License 5 votes vote down vote up
@Override
public ImmutableSet<Integer> onUnannotatedInvocationGetNonNullPositions(
    NullAway analysis,
    VisitorState state,
    Symbol.MethodSymbol methodSymbol,
    List<? extends ExpressionTree> actualParams,
    ImmutableSet<Integer> nonNullPositions) {
  return Sets.union(
          nonNullPositions, getOptLibraryModels(state.context).nonNullParameters(methodSymbol))
      .immutableCopy();
}
 
Example #20
Source File: CompositeHandler.java    From NullAway with MIT License 5 votes vote down vote up
@Override
public void onMatchMethodReference(
    NullAway analysis,
    MemberReferenceTree tree,
    VisitorState state,
    Symbol.MethodSymbol methodSymbol) {
  for (Handler h : handlers) {
    h.onMatchMethodReference(analysis, tree, state, methodSymbol);
  }
}
 
Example #21
Source File: NullAway.java    From NullAway with MIT License 5 votes vote down vote up
private boolean mayBeNullMethodCall(
    VisitorState state, ExpressionTree expr, Symbol.MethodSymbol exprSymbol) {
  boolean exprMayBeNull = true;
  if (NullabilityUtil.isUnannotated(exprSymbol, config)) {
    exprMayBeNull = false;
  }
  if (!Nullness.hasNullableAnnotation(exprSymbol, config)) {
    exprMayBeNull = false;
  }
  exprMayBeNull = handler.onOverrideMayBeNullExpr(this, expr, state, exprMayBeNull);
  return exprMayBeNull ? nullnessFromDataflow(state, expr) : false;
}
 
Example #22
Source File: AnnotatedApiUsageChecker.java    From guava-beta-checker with Apache License 2.0 5 votes vote down vote up
@Override
public final Description matchIdentifier(IdentifierTree tree, VisitorState state) {
  // We don't match any call to super() because currently we have no good way of identifying
  // super() calls that are generated and not actually present in the source code. Originally,
  // we were using state.getEndPosition to check if the end position in source for the tree was
  // <= 0, but end positions are not guaranteed to be enabled in error-prone, in which case all
  // super() calls would be matched anyway. This isn't likely to matter much in practice unless
  // a class is subclassing a non-annotated class that has an annotated no-arg constructor.
  // TODO(cgdecker): Revisit this if/when we have a way of detecting generated super() calls.
  return isSuperCall(tree) ? NO_MATCH : matchTree(tree);
}
 
Example #23
Source File: CompositeHandler.java    From NullAway with MIT License 5 votes vote down vote up
@Override
public void onMatchTopLevelClass(
    NullAway analysis, ClassTree tree, VisitorState state, Symbol.ClassSymbol classSymbol) {
  for (Handler h : handlers) {
    h.onMatchTopLevelClass(analysis, tree, state, classSymbol);
  }
}
 
Example #24
Source File: CompositeHandler.java    From NullAway with MIT License 5 votes vote down vote up
@Override
public void onMatchMethod(
    NullAway analysis, MethodTree tree, VisitorState state, Symbol.MethodSymbol methodSymbol) {
  for (Handler h : handlers) {
    h.onMatchMethod(analysis, tree, state, methodSymbol);
  }
}
 
Example #25
Source File: AnnotatedApiUsageChecker.java    From guava-beta-checker with Apache License 2.0 5 votes vote down vote up
@Override
public final Description matchMemberSelect(MemberSelectTree tree, VisitorState state) {
  if (ASTHelpers.findEnclosingNode(state.getPath(), ImportTree.class) != null) {
    return Description.NO_MATCH;
  }
  return matchTree(tree);
}
 
Example #26
Source File: NullAway.java    From NullAway with MIT License 5 votes vote down vote up
/**
 * @param symbol the field being read
 * @param pathToRead TreePath to the read operation
 * @param state visitor state
 * @param enclosingBlockPath TreePath to enclosing initializer block
 * @return true if within the initializer, the field is always initialized before the read
 *     operation, false otherwise
 */
private boolean fieldAlwaysInitializedBeforeRead(
    Symbol symbol, TreePath pathToRead, VisitorState state, TreePath enclosingBlockPath) {
  AccessPathNullnessAnalysis nullnessAnalysis = getNullnessAnalysis(state);
  Set<Element> nonnullFields;
  if (symbol.isStatic()) {
    nonnullFields = nullnessAnalysis.getNonnullStaticFieldsBefore(pathToRead, state.context);
  } else {
    nonnullFields = new LinkedHashSet<>();
    nonnullFields.addAll(
        nullnessAnalysis.getNonnullFieldsOfReceiverBefore(pathToRead, state.context));
    nonnullFields.addAll(safeInitByCalleeBefore(pathToRead, state, enclosingBlockPath));
  }
  return nonnullFields.contains(symbol);
}
 
Example #27
Source File: NullAway.java    From NullAway with MIT License 5 votes vote down vote up
@Override
public Description matchCompoundAssignment(CompoundAssignmentTree tree, VisitorState state) {
  if (!matchWithinClass) {
    return Description.NO_MATCH;
  }
  Type lhsType = ASTHelpers.getType(tree.getVariable());
  Type stringType = state.getTypeFromString("java.lang.String");
  if (lhsType != null && !state.getTypes().isSameType(lhsType, stringType)) {
    // both LHS and RHS could get unboxed
    return doUnboxingCheck(state, tree.getVariable(), tree.getExpression());
  }
  return Description.NO_MATCH;
}
 
Example #28
Source File: BaseNoOpHandler.java    From NullAway with MIT License 5 votes vote down vote up
@Override
public void onMatchMethodInvocation(
    NullAway analysis,
    MethodInvocationTree tree,
    VisitorState state,
    Symbol.MethodSymbol methodSymbol) {
  // NoOp
}
 
Example #29
Source File: CompositeHandler.java    From NullAway with MIT License 5 votes vote down vote up
@Override
public Optional<ErrorMessage> onExpressionDereference(
    ExpressionTree expr, ExpressionTree baseExpr, VisitorState state) {
  Optional<ErrorMessage> optionalErrorMessage;
  for (Handler h : handlers) {
    optionalErrorMessage = h.onExpressionDereference(expr, baseExpr, state);
    if (optionalErrorMessage.isPresent()) return optionalErrorMessage;
  }
  return Optional.empty();
}
 
Example #30
Source File: CompositeHandler.java    From NullAway with MIT License 5 votes vote down vote up
@Override
public boolean includeApInfoInSavedContext(AccessPath accessPath, VisitorState state) {
  boolean shouldFilter = false;
  for (Handler h : handlers) {
    shouldFilter |= h.includeApInfoInSavedContext(accessPath, state);
  }
  return shouldFilter;
}