@Override
  public Description matchMethod(MethodTree methodTree, VisitorState state) {
    // if method is itself annotated with @Inject or it has no ancestor methods, return NO_MATCH;
    if (hasInjectAnnotation().matches(methodTree, state)) {
      return Description.NO_MATCH;
    }

    boolean foundJavaxInject = false;
    for (MethodSymbol superMethod :
        ASTHelpers.findSuperMethods(ASTHelpers.getSymbol(methodTree), state.getTypes())) {

      // With a Guice annotation, Guice will still inject the subclass-overridden method.
      if (ASTHelpers.hasAnnotation(superMethod, GUICE_INJECT_ANNOTATION, state)) {
        return Description.NO_MATCH;
      }

      // is not necessarily a match even if we find javax Inject on an ancestor
      // since a higher up ancestor may have @com.google.inject.Inject
      foundJavaxInject |= ASTHelpers.hasAnnotation(superMethod, JAVAX_INJECT_ANNOTATION, state);
    }

    if (foundJavaxInject) {
      return describeMatch(
          methodTree,
          SuggestedFix.builder()
              .addImport(JAVAX_INJECT_ANNOTATION)
              .prefixWith(methodTree, "@Inject\n")
              .build());
    }
    return Description.NO_MATCH;
  }
Пример #2
0
  @Override
  public Description matchClass(ClassTree classTree, VisitorState state) {

    TypeSymbol symbol = ASTHelpers.getSymbol(classTree);
    if (symbol.getKind() != ElementKind.CLASS) {
      return Description.NO_MATCH;
    }

    MethodTree equals = null;
    for (Tree member : classTree.getMembers()) {
      if (!(member instanceof MethodTree)) {
        continue;
      }
      MethodTree methodTree = (MethodTree) member;
      if (EQUALS_MATCHER.matches(methodTree, state)) {
        equals = methodTree;
      }
    }
    if (equals == null) {
      return Description.NO_MATCH;
    }

    MethodSymbol hashCodeSym =
        ASTHelpers.resolveExistingMethod(
            state,
            symbol,
            state.getName("hashCode"),
            ImmutableList.<Type>of(),
            ImmutableList.<Type>of());

    if (hashCodeSym.owner.equals(state.getSymtab().objectType.tsym)) {
      return describeMatch(equals);
    }
    return Description.NO_MATCH;
  }
Пример #3
0
  @Override
  public boolean matches(ExpressionTree expressionTree, VisitorState state) {
    Symbol sym = ASTHelpers.getSymbol(expressionTree);
    if (sym == null) {
      return false;
    }
    if (!(sym instanceof MethodSymbol)) {
      throw new IllegalArgumentException(
          "DescendantOf matcher expects a method call but found "
              + sym.getClass()
              + ". Expression: "
              + expressionTree);
    }
    if (sym.isStatic()) {
      return false;
    }

    if (methodName.equals(sym.toString())) {
      Type accessedReferenceType = sym.owner.type;
      Type collectionType = state.getTypeFromString(fullClassName);
      if (collectionType != null) {
        return state
            .getTypes()
            .isSubtype(accessedReferenceType, state.getTypes().erasure(collectionType));
      }
    }

    return false;
  }
Пример #4
0
 // TODO(eaftan): refactor other code that accesses symbols to use this method
 public static Symbol getSymbol(Tree tree) {
   if (tree instanceof ClassTree) {
     return getSymbol((ClassTree) tree);
   }
   if (tree instanceof MethodTree) {
     return getSymbol((MethodTree) tree);
   }
   if (tree instanceof VariableTree) {
     return getSymbol((VariableTree) tree);
   }
   if (tree instanceof JCFieldAccess) {
     return ((JCFieldAccess) tree).sym;
   }
   if (tree instanceof JCIdent) {
     return ((JCIdent) tree).sym;
   }
   if (tree instanceof JCMethodInvocation) {
     return ASTHelpers.getSymbol((MethodInvocationTree) tree);
   }
   if (tree instanceof JCNewClass) {
     return ((JCNewClass) tree).constructor;
   }
   if (tree instanceof AnnotationTree) {
     return getSymbol(((AnnotationTree) tree).getAnnotationType());
   }
   if (tree instanceof PackageTree) {
     return getSymbol((PackageTree) tree);
   }
   return null;
 }
Пример #5
0
 /** Gets the symbol for a method invocation. */
 public static MethodSymbol getSymbol(MethodInvocationTree tree) {
   Symbol sym = ASTHelpers.getSymbol(tree.getMethodSelect());
   if (!(sym instanceof MethodSymbol)) {
     // Defensive. Would only occur if there are errors in the AST.
     return null;
   }
   return (MethodSymbol) sym;
 }
Пример #6
0
 @Override
 @Nullable
 protected Unifier defaultAction(Tree node, @Nullable Unifier unifier) {
   Symbol symbol = ASTHelpers.getSymbol(node);
   if (symbol != null
       && symbol.getEnclosingElement() != null
       && symbol
           .getEnclosingElement()
           .getQualifiedName()
           .contentEquals(classIdent().getQualifiedName())
       && symbol.getSimpleName().contentEquals(member())) {
     return memberType().unify(symbol.asType(), unifier);
   }
   return null;
 }
Пример #7
0
 @Override
 public Optional<MatchState> matchResult(ExpressionTree tree, VisitorState state) {
   Symbol sym = ASTHelpers.getSymbol(tree);
   if (!(sym instanceof MethodSymbol)) {
     return Optional.absent();
   }
   if (tree instanceof NewClassTree) {
     // Don't match constructors as they are neither static nor instance methods.
     return Optional.absent();
   }
   if (tree instanceof MethodInvocationTree) {
     tree = ((MethodInvocationTree) tree).getMethodSelect();
   }
   return Optional.of(
       MatchState.create(ASTHelpers.getReceiverType(tree), (MethodSymbol) sym));
 }
Пример #8
0
    @Override
    public boolean matches(ExpressionTree expressionTree, VisitorState state) {
      Symbol sym = ASTHelpers.getSymbol(expressionTree);
      if (sym != null && sym.getSimpleName().toString().startsWith("log")) {
        return true;
      }

      if (sym != null && sym.isStatic()) {
        if (sym.owner.getQualifiedName().toString().contains("Logger")) {
          return true;
        }
      } else if (expressionTree instanceof MemberSelectTree) {
        if (((MemberSelectTree) expressionTree).getExpression().toString().startsWith("log")) {
          return true;
        }
      }

      return false;
    }
Пример #9
0
 private boolean inEqualsOrCompareTo(Type classType, Type type, VisitorState state) {
   MethodTree methodTree = ASTHelpers.findEnclosingNode(state.getPath(), MethodTree.class);
   if (methodTree == null) {
     return false;
   }
   MethodSymbol sym = ASTHelpers.getSymbol(methodTree);
   if (sym == null || sym.isStatic()) {
     return false;
   }
   Symbol compareTo = getOnlyMember(state, state.getSymtab().comparableType, "compareTo");
   Symbol equals = getOnlyMember(state, state.getSymtab().objectType, "equals");
   if (!sym.overrides(compareTo, classType.tsym, state.getTypes(), false)
       && !sym.overrides(equals, classType.tsym, state.getTypes(), false)) {
     return false;
   }
   if (!ASTHelpers.isSameType(type, classType, state)) {
     return false;
   }
   return true;
 }
Пример #10
0
 @Override
 public boolean matches(ExpressionTree expressionTree, VisitorState state) {
   Symbol sym = ASTHelpers.getSymbol(expressionTree);
   return sym != null && sym.getSimpleName().toString().startsWith("assert");
 }