/**
   * In the first enclosing class, find the top-level member that contains tree. TODO: should we
   * look whether these elements are enclosed within another class that is itself under
   * construction.
   *
   * <p>Are there any other type of top level objects?
   */
  private Tree findTopLevelClassMemberForTree(TreePath path) {
    ClassTree enclosingClass = TreeUtils.enclosingClass(path);
    if (enclosingClass != null) {

      List<? extends Tree> classMembers = enclosingClass.getMembers();
      TreePath searchPath = path;
      while (searchPath.getParentPath() != null && searchPath.getParentPath() != enclosingClass) {
        searchPath = searchPath.getParentPath();
        if (classMembers.contains(searchPath.getLeaf())) {
          return searchPath.getLeaf();
        }
      }
    }
    return null;
  }
 @Override
 public Description matchCompilationUnit(CompilationUnitTree tree, VisitorState state) {
   if (tree.getTypeDecls().size() <= 1) {
     // package-info.java files have zero top-level declarations, everything
     // else should have exactly one.
     return Description.NO_MATCH;
   }
   if (tree.getPackageName() == null) {
     // Real code doesn't use the default package.
     return Description.NO_MATCH;
   }
   List<String> names = new ArrayList<>();
   for (Tree member : tree.getTypeDecls()) {
     if (member instanceof ClassTree) {
       ClassTree classMember = (ClassTree) member;
       switch (classMember.getKind()) {
         case CLASS:
         case INTERFACE:
         case ANNOTATION_TYPE:
         case ENUM:
           SuppressWarnings suppression =
               ASTHelpers.getAnnotation(classMember, SuppressWarnings.class);
           if (suppression != null
               && !Collections.disjoint(Arrays.asList(suppression.value()), allNames())) {
             // If any top-level classes have @SuppressWarnings("TopLevel"), ignore
             // this compilation unit. We can't rely on the normal suppression
             // mechanism because the only enclosing element is the package declaration,
             // and @SuppressWarnings can't be applied to packages.
             return Description.NO_MATCH;
           }
           names.add(classMember.getSimpleName().toString());
           break;
         default:
           break;
       }
     }
   }
   if (names.size() <= 1) {
     // this can happen with multiple type declarations if some of them are
     // empty (e.g. ";" at the top level counts as an empty type decl)
     return Description.NO_MATCH;
   }
   String message =
       String.format(
           "Expected at most one top-level class declaration, instead found: %s",
           Joiner.on(", ").join(names));
   return buildDescription(tree.getPackageName()).setMessage(message).build();
 }
Example #3
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;
  }
  /**
   * Find the index of the current class member.
   *
   * @param wc
   * @param classTree
   * @param offset
   * @return
   */
  static int findClassMemberIndex(WorkingCopy wc, ClassTree classTree, int offset) {

    int index = 0;
    SourcePositions sp = wc.getTrees().getSourcePositions();
    GuardedDocument gdoc = null;
    try {
      Document doc = wc.getDocument();
      if (doc != null && doc instanceof GuardedDocument) {
        gdoc = (GuardedDocument) doc;
      }
    } catch (IOException ioe) {
    }

    Tree lastMember = null;
    for (Tree tree : classTree.getMembers()) {
      if (offset <= sp.getStartPosition(wc.getCompilationUnit(), tree)) {
        if (gdoc == null) {
          break;
        }
        int pos =
            (int)
                (lastMember != null
                    ? sp.getEndPosition(wc.getCompilationUnit(), lastMember)
                    : sp.getStartPosition(wc.getCompilationUnit(), classTree));
        pos = gdoc.getGuardedBlockChain().adjustToBlockEnd(pos);
        if (pos <= sp.getStartPosition(wc.getCompilationUnit(), tree)) {
          break;
        }
      }
      index++;
      lastMember = tree;
    }
    return index;
  }
  private static List<? extends TypeMirror> computeClass(
      Set<ElementKind> types, CompilationInfo info, TreePath parent, Tree error, int offset) {
    ClassTree ct = (ClassTree) parent.getLeaf();

    if (ct.getExtendsClause() == error) {
      types.add(ElementKind.CLASS);
      return null;
    }

    for (Tree t : ct.getImplementsClause()) {
      if (t == error) {
        types.add(ElementKind.INTERFACE);
        return null;
      }
    }

    // XXX: annotation types...

    return null;
  }
Example #6
0
 private State checkClass(ClassTree classTree) {
   if (anonymousMode) {
     anonymousInnerCount++;
     if (anonymousInnerCount == anonymousInnerNumber) {
       return advanceDepth();
     }
   } else {
     if (classTree.getSimpleName().contentEquals(actualName)) {
       return advanceDepth();
     }
   }
   return State.DEAD_END;
 }
 /** Returns true if a class overrides Object.equals */
 private boolean overridesEquals(ClassTree node) {
   List<? extends Tree> members = node.getMembers();
   for (Tree member : members) {
     if (member instanceof MethodTree) {
       MethodTree mTree = (MethodTree) member;
       ExecutableElement enclosing = TreeUtils.elementFromDeclaration(mTree);
       if (overrides(enclosing, Object.class, "equals")) {
         return true;
       }
     }
   }
   return false;
 }
  /*
   * Method to implement the @UsesObjectEquals functionality.
   * If a class is marked @UsesObjectEquals, it must:
   *
   *    -not override .equals(Object)
   *    -be a subclass of Object or another class marked @UsesObjectEquals
   *
   * If a class is not marked @UsesObjectEquals, it must:
   *
   * 	  -not have a superclass marked @UsesObjectEquals
   *
   *
   * @see org.checkerframework.common.basetype.BaseTypeVisitor#visitClass(com.sun.source.tree.ClassTree, java.lang.Object)
   */
  @Override
  public Void visitClass(ClassTree node, Void p) {
    // Looking for an @UsesObjectEquals class declaration

    TypeElement elt = TreeUtils.elementFromDeclaration(node);
    UsesObjectEquals annotation = elt.getAnnotation(UsesObjectEquals.class);

    Tree superClass = node.getExtendsClause();
    Element elmt = null;
    if (superClass != null
        && (superClass instanceof IdentifierTree || superClass instanceof MemberSelectTree)) {
      elmt = TreeUtils.elementFromUse((ExpressionTree) superClass);
    }

    // if it's there, check to make sure does not override equals
    // and supertype is Object or @UsesObjectEquals
    if (annotation != null) {
      // check methods to ensure no .equals
      if (overridesEquals(node)) {
        checker.report(Result.failure("overrides.equals"), node);
      }

      if (!(superClass == null
          || (elmt != null && elmt.getAnnotation(UsesObjectEquals.class) != null))) {
        checker.report(Result.failure("superclass.unmarked"), node);
      }
    } else {
      // the class is not marked @UsesObjectEquals -> make sure its superclass isn't either.
      // this is impossible after design change making @UsesObjectEquals inherited?
      // check left in case of future design change back to non-inherited.
      if (superClass != null
          && (elmt != null && elmt.getAnnotation(UsesObjectEquals.class) != null)) {
        checker.report(Result.failure("superclass.marked"), node);
      }
    }

    return super.visitClass(node, p);
  }
 /** Are all fields committed-only? */
 protected boolean areAllFieldsCommittedOnly(ClassTree classTree) {
   if (!useFbc) {
     // In the rawness type system, no fields can store not fully
     // initialized objects.
     return true;
   }
   for (Tree member : classTree.getMembers()) {
     if (!member.getKind().equals(Tree.Kind.VARIABLE)) {
       continue;
     }
     VariableTree var = (VariableTree) member;
     VariableElement varElt = TreeUtils.elementFromDeclaration(var);
     // var is not committed-only
     if (getDeclAnnotation(varElt, NotOnlyInitialized.class) != null) {
       // var is not static -- need a check of initializer blocks,
       // not of constructor which is where this is used
       if (!varElt.getModifiers().contains(Modifier.STATIC)) {
         return false;
       }
     }
   }
   return true;
 }
Example #10
0
    @Override
    public ChangeInfo implement() throws Exception {
      JavaSource js = JavaSource.forFileObject(sourceCode);

      js.runModificationTask(
              new Task<WorkingCopy>() {
                @Override
                public void run(WorkingCopy parameter) throws Exception {
                  parameter.toPhase(Phase.RESOLVED);
                  TypeElement suppressWarningsAnnotation = null;

                  for (String ann : SUPPRESS_WARNINGS_ANNOTATIONS) {
                    if ((suppressWarningsAnnotation = parameter.getElements().getTypeElement(ann))
                        != null) break;
                  }

                  if (suppressWarningsAnnotation == null) {
                    NotifyDescriptor nd =
                        new NotifyDescriptor.Message(
                            "Cannot find SuppressWarnings annotation with Retention.CLASS, please add some on the classpath",
                            NotifyDescriptor.WARNING_MESSAGE);
                    DialogDisplayer.getDefault().notifyLater(nd);
                    return;
                  }

                  int realPos;

                  if (pos != (-1)) {
                    realPos = pos;
                  } else {
                    realPos =
                        (int) parameter.getCompilationUnit().getLineMap().getPosition(line, 0);
                  }

                  TreePath tp = parameter.getTreeUtilities().pathFor(realPos);

                  while (tp != null && !ANNOTATABLE.contains(tp.getLeaf().getKind())) {
                    tp = tp.getParentPath();
                  }

                  if (tp == null) return;

                  ModifiersTree mods;
                  Tree leaf = tp.getLeaf();

                  switch (leaf.getKind()) {
                    case ANNOTATION_TYPE:
                    case CLASS:
                    case ENUM:
                    case INTERFACE:
                      mods = ((ClassTree) leaf).getModifiers();
                      break;
                    case METHOD:
                      mods = ((MethodTree) leaf).getModifiers();
                      break;
                    case VARIABLE:
                      mods = ((MethodTree) leaf).getModifiers();
                      break;
                    default:
                      throw new IllegalStateException(leaf.getKind().name());
                  }

                  parameter.rewrite(
                      mods,
                      GeneratorUtilities.get(parameter)
                          .appendToAnnotationValue(
                              mods,
                              suppressWarningsAnnotation,
                              "value",
                              parameter.getTreeMaker().Literal(bugId)));
                }
              })
          .commit();

      return null;
    }
Example #11
0
  public void run(WorkingCopy workingCopy) throws Exception {
    try {
      workingCopy.toPhase(JavaSource.Phase.ELEMENTS_RESOLVED);

      CompilationUnitTree cut = workingCopy.getCompilationUnit();
      ClassTree classTree = (ClassTree) cut.getTypeDecls().get(0);

      TreeMaker make = workingCopy.getTreeMaker();

      // Import org.glassfish.openesb.pojose.api.annotation.POJO
      //       org.glassfish.openesb.pojose.api.annotation.Operation

      CompilationUnitTree copy =
          make.addCompUnitImport(
              cut,
              make.Import(make.Identifier(GeneratorUtil.PROVIDER_QUAL_CLASS_ANNOTATION), false));
      // workingCopy.rewrite(cut, copy);
      // cut = workingCopy.getCompilationUnit();
      // classTree = (ClassTree) cut.getTypeDecls().get(0);

      CompilationUnitTree copy1 =
          make.addCompUnitImport(
              copy,
              make.Import(
                  make.Identifier(GeneratorUtil.POJO_QUAL_OPERATION_ANNOTATION_CLASS), false));

      copy =
          make.addCompUnitImport(
              copy1, make.Import(make.Identifier(GeneratorUtil.CTX_QUAL_CLASS_ANNOTATION), false));

      copy1 =
          make.addCompUnitImport(
              copy, make.Import(make.Identifier(GeneratorUtil.RSRC_QUAL_CLASS_ANNOTATION), false));

      workingCopy.rewrite(cut, copy1);
      cut = workingCopy.getCompilationUnit();
      classTree = (ClassTree) cut.getTypeDecls().get(0);

      // ADD POJO CLASS TYPE ANNOTATION
      /*
      Document dox = workingCopy.getDocument();
      Element[] arrayOfElements = dox.getRootElements();
      for ( Element el : arrayOfElements) {
         displayElements(el,0);
      }*/

      List<ExpressionTree> argumentValueList = new ArrayList<ExpressionTree>();
      if (annotationArguments != null) {
        Set<Map.Entry<String, Object>> annArgValSet = annotationArguments.entrySet();
        for (Map.Entry<String, Object> mapenty : annArgValSet) {
          argumentValueList.add(
              GeneratorUtil.createAnnotationArgument(make, mapenty.getKey(), mapenty.getValue()));
        }
      }
      AnnotationTree pojoAnnTypeTree =
          GeneratorUtil.createAnnotation(
              make, workingCopy, GeneratorUtil.PROVIDER_CLASS_ANNOTATION, argumentValueList);

      ModifiersTree oldTree = classTree.getModifiers();
      ModifiersTree newTree = make.Modifiers(oldTree, Collections.singletonList(pojoAnnTypeTree));
      workingCopy.rewrite(oldTree, newTree);
      cut = workingCopy.getCompilationUnit();
      classTree = (ClassTree) cut.getTypeDecls().get(0);

      ModifiersTree modifiers =
          handleModifiersAndAnnotations(make, workingCopy, GeneratorUtil.RSRC_ANNOTATION, null);

      VariableTree variableTree =
          GeneratorUtil.createField(
              make,
              workingCopy,
              modifiers,
              GeneratorUtil
                  .POJO_CTX_VARIABLE, // TODO: Check if this variable is not used by this class.
              GeneratorUtil.CTX_ANNOTATION, // NOI18N
              null);

      ClassTree newClassTree1 = make.addClassMember(classTree, variableTree);
      // workingCopy.rewrite(classTree, newClassTree1);

      // CompilationUnitTree modClassTree = make.addCompUnitTypeDecl(cut, pojoAnnTypeTree);
      // workingCopy.rewrite(cut, modClassTree);
      cut = workingCopy.getCompilationUnit();
      classTree = newClassTree1; // (ClassTree) cut.getTypeDecls().get(0);
      // ADD POJO OPERATION.
      boolean bOperationReturnsVoid =
          methodReturnType == null || methodReturnType.equals(GeneratorUtil.GENERATE_VOID);
      argumentValueList = new ArrayList<ExpressionTree>();
      if (!bOperationReturnsVoid && this.operationArguments != null) {
        Set<Map.Entry<String, Object>> annArgValSet = operationArguments.entrySet();
        for (Map.Entry<String, Object> mapenty : annArgValSet) {
          argumentValueList.add(
              GeneratorUtil.createAnnotationArgument(make, mapenty.getKey(), mapenty.getValue()));
        }
      }
      AnnotationTree anTree =
          GeneratorUtil.createAnnotation(make, workingCopy, annotationType, argumentValueList);
      Tree returnType = null;
      boolean bReturnVoid = false;
      if (bOperationReturnsVoid) {
        returnType = make.PrimitiveType(TypeKind.VOID); // return type
        bReturnVoid = true;
      } else {
        returnType = GeneratorUtil.createType(make, workingCopy, methodReturnType);
      }

      List<TypeParameterTree> listOfInputTypes = new ArrayList<TypeParameterTree>();
      List<VariableTree> listOfInputVariables = new ArrayList<VariableTree>();
      //   ModifiersTree modTree = make.Modifiers(Collections.singleton(Modifier.PUBLIC));
      ModifiersTree parMods = make.Modifiers(Collections.EMPTY_SET, Collections.EMPTY_LIST);

      int ix = 0;
      String inputVariableName = null;
      String inputVariableType = null;
      VariableTree inputIdentifier = null;
      for (String argumentType : methodArgumentType) {
        if (!argumentType.equals("")) {
          //  listOfInputTypes.add(  make.TypeParameter(argumentType, null));
          inputVariableName = GeneratorUtil.POJO_VARIABLE_NAME_PREFIX + (ix++);
          inputVariableType = argumentType;
          inputIdentifier =
              GeneratorUtil.createField(
                  make,
                  workingCopy,
                  parMods
                  /** modTree* */
                  ,
                  inputVariableName,
                  argumentType,
                  null);
          listOfInputVariables.add(inputIdentifier);
        }
      }

      BlockTree blockTree = null;
      if (bReturnVoid) {
        blockTree = make.Block(Collections.EMPTY_LIST, false);
      } else {
        // List<ExpressionTree> returnExpList =
        // Collections.singletonList((ExpressionTree)make.Identifier("null"));
        if (inputVariableType != null
            && this.methodReturnType != null
            && methodReturnType.equals(inputVariableType)) {
          ReturnTree retTree = make.Return(make.Identifier(inputVariableName));
          blockTree = make.Block(Collections.singletonList(retTree), false);

        } else {
          ReturnTree retTree = make.Return(make.Identifier("null"));
          blockTree = make.Block(Collections.singletonList(retTree), false);
        }
      }

      MethodTree newMethod =
          make.Method(
              make.Modifiers(
                  Collections.singleton(Modifier.PUBLIC), // modifiers
                  Collections.singletonList(anTree)), // modifiers and annotations
              methodName, // name
              returnType, // return type
              Collections.EMPTY_LIST, // listOfInputTypes, // type parameters for parameters
              listOfInputVariables, // parameters
              Collections.EMPTY_LIST,
              blockTree, // empty statement block
              null // default value - not applicable here, used by annotations
              );
      ClassTree oldClassTree = (ClassTree) cut.getTypeDecls().get(0);
      ClassTree newClassTree = make.addClassMember(classTree, newMethod);
      workingCopy.rewrite(oldClassTree, newClassTree);
    } catch (Exception e) {
      myException = e;
      throw e;
    }
  }
Example #12
0
 @Override
 public String toString() {
   return String.format(
       "method %s (%s) / class %s (%s)",
       (mt != null ? mt.getName() : "null"), mrt, (ct != null ? ct.getSimpleName() : "null"), act);
 }