private static IMethod findIncludingSupertypes(
     IMethodBinding method, IType type, IProgressMonitor pm) throws JavaModelException {
   IMethod inThisType = Bindings.findMethod(method, type);
   if (inThisType != null) return inThisType;
   IType[] superTypes = JavaModelUtil.getAllSuperTypes(type, pm);
   for (int i = 0; i < superTypes.length; i++) {
     IMethod m = Bindings.findMethod(method, superTypes[i]);
     if (m != null) return m;
   }
   return null;
 }
  public void registerAddedStaticImport(IBinding binding) {
    if (binding instanceof IVariableBinding) {
      ITypeBinding declaringType = ((IVariableBinding) binding).getDeclaringClass();
      fAddedStaticImports.add(
          new StaticImportData(
              Bindings.getRawQualifiedName(declaringType), binding.getName(), true));

    } else if (binding instanceof IMethodBinding) {
      ITypeBinding declaringType = ((IMethodBinding) binding).getDeclaringClass();
      fAddedStaticImports.add(
          new StaticImportData(
              Bindings.getRawQualifiedName(declaringType), binding.getName(), false));

    } else {
      throw new IllegalArgumentException(binding.toString());
    }
  }
 public ITypeBinding[] getExceptions(boolean includeRuntimeExceptions) {
   if (includeRuntimeExceptions) return fAllExceptions;
   List<ITypeBinding> result = new ArrayList<>(fAllExceptions.length);
   for (int i = 0; i < fAllExceptions.length; i++) {
     ITypeBinding exception = fAllExceptions[i];
     if (!includeRuntimeExceptions && Bindings.isRuntimeException(exception)) continue;
     result.add(exception);
   }
   return result.toArray(new ITypeBinding[result.size()]);
 }
 private Type getConstantType() throws JavaModelException {
   if (fConstantTypeCache == null) {
     IExpressionFragment fragment = getSelectedExpression();
     ITypeBinding typeBinding = guessBindingForReference(fragment.getAssociatedExpression());
     AST ast = fCuRewrite.getAST();
     typeBinding = Bindings.normalizeForDeclarationUse(typeBinding, ast);
     ImportRewrite importRewrite = fCuRewrite.getImportRewrite();
     ImportRewriteContext context =
         new ContextSensitiveImportRewriteContext(
             fCuRewrite.getRoot(), fSelectionStart, importRewrite);
     fConstantTypeCache = importRewrite.addImport(typeBinding, ast, context);
   }
   return fConstantTypeCache;
 }
  public NewVariableCorrectionProposal(
      String label,
      ICompilationUnit cu,
      int variableKind,
      SimpleName node,
      ITypeBinding senderBinding,
      int relevance,
      Image image) {
    super(label, cu, null, relevance, image);
    if (senderBinding == null) {
      Assert.isTrue(variableKind == PARAM || variableKind == LOCAL);
    } else {
      Assert.isTrue(Bindings.isDeclarationBinding(senderBinding));
    }

    fVariableKind = variableKind;
    fOriginalNode = node;
    fSenderBinding = senderBinding;
  }
 private void initReturnType(ImportRewrite rewriter) {
   AST ast = fEnclosingBodyDeclaration.getAST();
   fReturnType = null;
   fReturnTypeBinding = null;
   switch (fReturnKind) {
     case ACCESS_TO_LOCAL:
       VariableDeclaration declaration =
           ASTNodes.findVariableDeclaration(fReturnValue, fEnclosingBodyDeclaration);
       fReturnType =
           ASTNodeFactory.newType(
               ast,
               declaration,
               rewriter,
               new ContextSensitiveImportRewriteContext(declaration, rewriter));
       if (declaration.resolveBinding() != null) {
         fReturnTypeBinding = declaration.resolveBinding().getType();
       }
       break;
     case EXPRESSION:
       Expression expression = (Expression) getFirstSelectedNode();
       if (expression.getNodeType() == ASTNode.CLASS_INSTANCE_CREATION) {
         fExpressionBinding = ((ClassInstanceCreation) expression).getType().resolveBinding();
       } else {
         fExpressionBinding = expression.resolveTypeBinding();
       }
       if (fExpressionBinding != null) {
         if (fExpressionBinding.isNullType()) {
           getStatus()
               .addFatalError(
                   RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_null_type,
                   JavaStatusContext.create(fCUnit, expression));
         } else {
           ITypeBinding normalizedBinding =
               Bindings.normalizeForDeclarationUse(fExpressionBinding, ast);
           if (normalizedBinding != null) {
             ImportRewriteContext context =
                 new ContextSensitiveImportRewriteContext(fEnclosingBodyDeclaration, rewriter);
             fReturnType = rewriter.addImport(normalizedBinding, ast, context);
             fReturnTypeBinding = normalizedBinding;
           }
         }
       } else {
         fReturnType = ast.newPrimitiveType(PrimitiveType.VOID);
         fReturnTypeBinding = ast.resolveWellKnownType("void"); // $NON-NLS-1$
         getStatus()
             .addError(
                 RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_determine_return_type,
                 JavaStatusContext.create(fCUnit, expression));
       }
       break;
     case RETURN_STATEMENT_VALUE:
       LambdaExpression enclosingLambdaExpr =
           ASTResolving.findEnclosingLambdaExpression(getFirstSelectedNode());
       if (enclosingLambdaExpr != null) {
         fReturnType = ASTNodeFactory.newReturnType(enclosingLambdaExpr, ast, rewriter, null);
         IMethodBinding methodBinding = enclosingLambdaExpr.resolveMethodBinding();
         fReturnTypeBinding = methodBinding != null ? methodBinding.getReturnType() : null;
       } else if (fEnclosingBodyDeclaration.getNodeType() == ASTNode.METHOD_DECLARATION) {
         fReturnType = ((MethodDeclaration) fEnclosingBodyDeclaration).getReturnType2();
         fReturnTypeBinding = fReturnType != null ? fReturnType.resolveBinding() : null;
       }
       break;
     default:
       fReturnType = ast.newPrimitiveType(PrimitiveType.VOID);
       fReturnTypeBinding = ast.resolveWellKnownType("void"); // $NON-NLS-1$
   }
   if (fReturnType == null) {
     fReturnType = ast.newPrimitiveType(PrimitiveType.VOID);
     fReturnTypeBinding = ast.resolveWellKnownType("void"); // $NON-NLS-1$
   }
 }
  private ASTRewrite doAddLocal(CompilationUnit cu) {
    AST ast = cu.getAST();

    Block body;
    BodyDeclaration decl = ASTResolving.findParentBodyDeclaration(fOriginalNode);
    IBinding targetContext = null;
    if (decl instanceof MethodDeclaration) {
      body = (((MethodDeclaration) decl).getBody());
      targetContext = ((MethodDeclaration) decl).resolveBinding();
    } else if (decl instanceof Initializer) {
      body = (((Initializer) decl).getBody());
      targetContext = Bindings.getBindingOfParentType(decl);
    } else {
      return null;
    }
    ASTRewrite rewrite = ASTRewrite.create(ast);

    ImportRewrite imports = createImportRewrite((CompilationUnit) decl.getRoot());
    ImportRewriteContext importRewriteContext =
        new ContextSensitiveImportRewriteContext(decl, imports);

    SimpleName[] names = getAllReferences(body);
    ASTNode dominant = getDominantNode(names);

    Statement dominantStatement = ASTResolving.findParentStatement(dominant);
    if (ASTNodes.isControlStatementBody(dominantStatement.getLocationInParent())) {
      dominantStatement = (Statement) dominantStatement.getParent();
    }

    SimpleName node = names[0];

    if (isAssigned(dominantStatement, node)) {
      // x = 1; -> int x = 1;
      Assignment assignment = (Assignment) node.getParent();

      // trick to avoid comment removal around the statement: keep the expression statement
      // and replace the assignment with an VariableDeclarationExpression
      VariableDeclarationFragment newDeclFrag = ast.newVariableDeclarationFragment();
      VariableDeclarationExpression newDecl = ast.newVariableDeclarationExpression(newDeclFrag);
      newDecl.setType(evaluateVariableType(ast, imports, importRewriteContext, targetContext));

      Expression placeholder = (Expression) rewrite.createCopyTarget(assignment.getRightHandSide());
      newDeclFrag.setInitializer(placeholder);
      newDeclFrag.setName(ast.newSimpleName(node.getIdentifier()));
      rewrite.replace(assignment, newDecl, null);

      addLinkedPosition(rewrite.track(newDecl.getType()), false, KEY_TYPE);
      addLinkedPosition(rewrite.track(newDeclFrag.getName()), true, KEY_NAME);

      setEndPosition(rewrite.track(assignment.getParent()));

      return rewrite;
    } else if ((dominant != dominantStatement) && isForStatementInit(dominantStatement, node)) {
      //	for (x = 1;;) ->for (int x = 1;;)

      Assignment assignment = (Assignment) node.getParent();

      VariableDeclarationFragment frag = ast.newVariableDeclarationFragment();
      VariableDeclarationExpression expression = ast.newVariableDeclarationExpression(frag);
      frag.setName(ast.newSimpleName(node.getIdentifier()));
      Expression placeholder = (Expression) rewrite.createCopyTarget(assignment.getRightHandSide());
      frag.setInitializer(placeholder);
      expression.setType(evaluateVariableType(ast, imports, importRewriteContext, targetContext));

      rewrite.replace(assignment, expression, null);

      addLinkedPosition(rewrite.track(expression.getType()), false, KEY_TYPE);
      addLinkedPosition(rewrite.track(frag.getName()), true, KEY_NAME);

      setEndPosition(rewrite.track(expression));

      return rewrite;

    } else if ((dominant != dominantStatement)
        && isEnhancedForStatementVariable(dominantStatement, node)) {
      //	for (x: collectionOfT) -> for (T x: collectionOfT)

      EnhancedForStatement enhancedForStatement = (EnhancedForStatement) dominantStatement;
      SingleVariableDeclaration parameter = enhancedForStatement.getParameter();
      Expression expression = enhancedForStatement.getExpression();

      SimpleName newName = (SimpleName) rewrite.createMoveTarget(node);
      rewrite.set(parameter, SingleVariableDeclaration.NAME_PROPERTY, newName, null);

      ITypeBinding elementBinding = null;
      ITypeBinding typeBinding = expression.resolveTypeBinding();
      if (typeBinding != null) {
        if (typeBinding.isArray()) {
          elementBinding = typeBinding.getElementType();
        } else {
          ITypeBinding iterable =
              Bindings.findTypeInHierarchy(typeBinding, "java.lang.Iterable"); // $NON-NLS-1$
          if (iterable != null) {
            ITypeBinding[] typeArguments = iterable.getTypeArguments();
            if (typeArguments.length == 1) {
              elementBinding = typeArguments[0];
              elementBinding = Bindings.normalizeForDeclarationUse(elementBinding, ast);
            }
          }
        }
      }
      Type type;
      if (elementBinding != null) {
        type = imports.addImport(elementBinding, ast, importRewriteContext);
      } else {
        type = ast.newSimpleType(ast.newSimpleName("Object")); // $NON-NLS-1$
      }

      rewrite.set(parameter, SingleVariableDeclaration.TYPE_PROPERTY, type, null);

      addLinkedPosition(rewrite.track(type), false, KEY_TYPE);
      addLinkedPosition(rewrite.track(newName), true, KEY_NAME);

      setEndPosition(rewrite.track(expression));

      return rewrite;
    }

    //	foo(x) -> int x; foo(x)

    VariableDeclarationFragment newDeclFrag = ast.newVariableDeclarationFragment();
    VariableDeclarationStatement newDecl = ast.newVariableDeclarationStatement(newDeclFrag);

    newDeclFrag.setName(ast.newSimpleName(node.getIdentifier()));
    newDecl.setType(evaluateVariableType(ast, imports, importRewriteContext, targetContext));
    //		newDeclFrag.setInitializer(ASTNodeFactory.newDefaultExpression(ast, newDecl.getType(), 0));

    addLinkedPosition(rewrite.track(newDecl.getType()), false, KEY_TYPE);
    addLinkedPosition(rewrite.track(node), true, KEY_NAME);
    addLinkedPosition(rewrite.track(newDeclFrag.getName()), false, KEY_NAME);

    Statement statement = dominantStatement;
    List<? extends ASTNode> list = ASTNodes.getContainingList(statement);
    while (list == null
        && statement.getParent() instanceof Statement) { // parent must be if, for or while
      statement = (Statement) statement.getParent();
      list = ASTNodes.getContainingList(statement);
    }
    if (list != null) {
      ASTNode parent = statement.getParent();
      StructuralPropertyDescriptor childProperty = statement.getLocationInParent();
      if (childProperty.isChildListProperty()) {
        rewrite
            .getListRewrite(parent, (ChildListPropertyDescriptor) childProperty)
            .insertBefore(newDecl, statement, null);
        return rewrite;
      } else {
        return null;
      }
    }
    return rewrite;
  }
  public static void getMissingJavadocCommentProposals(
      IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals)
      throws CoreException {
    ASTNode node = problem.getCoveringNode(context.getASTRoot());
    if (node == null) {
      return;
    }
    BodyDeclaration declaration = ASTResolving.findParentBodyDeclaration(node);
    if (declaration == null) {
      return;
    }
    ICompilationUnit cu = context.getCompilationUnit();
    ITypeBinding binding = Bindings.getBindingOfParentType(declaration);
    if (binding == null) {
      return;
    }

    if (declaration instanceof MethodDeclaration) {
      MethodDeclaration methodDecl = (MethodDeclaration) declaration;
      IMethodBinding methodBinding = methodDecl.resolveBinding();
      IMethodBinding overridden = null;
      if (methodBinding != null) {
        overridden = Bindings.findOverriddenMethod(methodBinding, true);
      }

      String string =
          CodeGeneration.getMethodComment(
              cu, binding.getName(), methodDecl, overridden, String.valueOf('\n'));
      if (string != null) {
        String label = CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_method_description;
        proposals.add(
            new AddJavadocCommentProposal(
                label,
                cu,
                IProposalRelevance.ADD_JAVADOC_METHOD,
                declaration.getStartPosition(),
                string));
      }
    } else if (declaration instanceof AbstractTypeDeclaration) {
      String typeQualifiedName = Bindings.getTypeQualifiedName(binding);
      String[] typeParamNames;
      if (declaration instanceof TypeDeclaration) {
        List<TypeParameter> typeParams = ((TypeDeclaration) declaration).typeParameters();
        typeParamNames = new String[typeParams.size()];
        for (int i = 0; i < typeParamNames.length; i++) {
          typeParamNames[i] = (typeParams.get(i)).getName().getIdentifier();
        }
      } else {
        typeParamNames = new String[0];
      }
      String string =
          CodeGeneration.getTypeComment(
              cu, typeQualifiedName, typeParamNames, String.valueOf('\n'));
      if (string != null) {
        String label = CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_type_description;
        proposals.add(
            new AddJavadocCommentProposal(
                label,
                cu,
                IProposalRelevance.ADD_JAVADOC_TYPE,
                declaration.getStartPosition(),
                string));
      }
    } else if (declaration instanceof FieldDeclaration) {
      String comment = "/**\n *\n */\n"; // $NON-NLS-1$
      List<VariableDeclarationFragment> fragments = ((FieldDeclaration) declaration).fragments();
      if (fragments != null && fragments.size() > 0) {
        VariableDeclaration decl = fragments.get(0);
        String fieldName = decl.getName().getIdentifier();
        String typeName = binding.getName();
        comment = CodeGeneration.getFieldComment(cu, typeName, fieldName, String.valueOf('\n'));
      }
      if (comment != null) {
        String label = CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_field_description;
        proposals.add(
            new AddJavadocCommentProposal(
                label,
                cu,
                IProposalRelevance.ADD_JAVADOC_FIELD,
                declaration.getStartPosition(),
                comment));
      }
    } else if (declaration instanceof EnumConstantDeclaration) {
      EnumConstantDeclaration enumDecl = (EnumConstantDeclaration) declaration;
      String id = enumDecl.getName().getIdentifier();
      String comment =
          CodeGeneration.getFieldComment(cu, binding.getName(), id, String.valueOf('\n'));
      String label = CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_enumconst_description;
      proposals.add(
          new AddJavadocCommentProposal(
              label,
              cu,
              IProposalRelevance.ADD_JAVADOC_ENUM,
              declaration.getStartPosition(),
              comment));
    }
  }
  private ClipboardData getClipboardData(ITypeRoot inputElement, int offset, int length) {
    CompilationUnit astRoot =
        SharedASTProvider.getAST(inputElement, SharedASTProvider.WAIT_ACTIVE_ONLY, null);
    if (astRoot == null) {
      return null;
    }

    // do process import if selection spans over import declaration or package
    List<ImportDeclaration> list = astRoot.imports();
    if (!list.isEmpty()) {
      if (offset < ((ASTNode) list.get(list.size() - 1)).getStartPosition()) {
        return null;
      }
    } else if (astRoot.getPackage() != null) {
      if (offset < ((ASTNode) astRoot.getPackage()).getStartPosition()) {
        return null;
      }
    }

    ArrayList<SimpleName> typeImportsRefs = new ArrayList<SimpleName>();
    ArrayList<SimpleName> staticImportsRefs = new ArrayList<SimpleName>();

    ImportReferencesCollector.collect(
        astRoot,
        inputElement.getJavaProject(),
        new Region(offset, length),
        typeImportsRefs,
        staticImportsRefs);

    if (typeImportsRefs.isEmpty() && staticImportsRefs.isEmpty()) {
      return null;
    }

    HashSet<String> namesToImport = new HashSet<String>(typeImportsRefs.size());
    for (int i = 0; i < typeImportsRefs.size(); i++) {
      Name curr = typeImportsRefs.get(i);
      IBinding binding = curr.resolveBinding();
      if (binding != null && binding.getKind() == IBinding.TYPE) {
        ITypeBinding typeBinding = (ITypeBinding) binding;
        if (typeBinding.isArray()) {
          typeBinding = typeBinding.getElementType();
        }
        if (typeBinding.isTypeVariable()
            || typeBinding.isCapture()
            || typeBinding.isWildcardType()) { // can be removed when bug 98473 is fixed
          continue;
        }

        if (typeBinding.isMember() || typeBinding.isTopLevel()) {
          String name = Bindings.getRawQualifiedName(typeBinding);
          if (name.length() > 0) {
            namesToImport.add(name);
          }
        }
      }
    }

    HashSet<String> staticsToImport = new HashSet<String>(staticImportsRefs.size());
    for (int i = 0; i < staticImportsRefs.size(); i++) {
      Name curr = staticImportsRefs.get(i);
      IBinding binding = curr.resolveBinding();
      if (binding != null) {
        StringBuffer buf = new StringBuffer(Bindings.getImportName(binding));
        if (binding.getKind() == IBinding.METHOD) {
          buf.append("()"); // $NON-NLS-1$
        }
        staticsToImport.add(buf.toString());
      }
    }

    if (namesToImport.isEmpty() && staticsToImport.isEmpty()) {
      return null;
    }

    String[] typeImports = namesToImport.toArray(new String[namesToImport.size()]);
    String[] staticImports = staticsToImport.toArray(new String[staticsToImport.size()]);
    return new ClipboardData(inputElement, typeImports, staticImports);
  }