private static String getArgument(TagElement curr) {
   List<? extends ASTNode> fragments = curr.fragments();
   if (!fragments.isEmpty()) {
     Object first = fragments.get(0);
     if (first instanceof Name) {
       return ASTNodes.getSimpleNameIdentifier((Name) first);
     } else if (first instanceof TextElement && TagElement.TAG_PARAM.equals(curr.getTagName())) {
       String text = ((TextElement) first).getText();
       if ("<".equals(text) && fragments.size() >= 3) { // $NON-NLS-1$
         Object second = fragments.get(1);
         Object third = fragments.get(2);
         if (second instanceof Name
             && third instanceof TextElement
             && ">".equals(((TextElement) third).getText())) { // $NON-NLS-1$
           return '<' + ASTNodes.getSimpleNameIdentifier((Name) second) + '>';
         }
       } else if (text.startsWith(String.valueOf('<'))
           && text.endsWith(String.valueOf('>'))
           && text.length() > 2) {
         return text.substring(1, text.length() - 1);
       }
     }
   }
   return null;
 }
Пример #2
0
  private static VariableDeclaration getVariableDeclaration(Name node) {
    IBinding binding = node.resolveBinding();
    if (binding == null && node.getParent() instanceof VariableDeclaration)
      return (VariableDeclaration) node.getParent();

    if (binding != null && binding.getKind() == IBinding.VARIABLE) {
      CompilationUnit cu = (CompilationUnit) ASTNodes.getParent(node, CompilationUnit.class);
      return ASTNodes.findVariableDeclaration(((IVariableBinding) binding), cu);
    }
    return null;
  }
 private int findFieldInsertIndex(
     List<BodyDeclaration> decls, FieldDeclaration newDecl, int maxOffset) {
   if (maxOffset != -1) {
     for (int i = decls.size() - 1; i >= 0; i--) {
       BodyDeclaration curr = decls.get(i);
       if (maxOffset > curr.getStartPosition() + curr.getLength()) {
         return ASTNodes.getInsertionIndex(newDecl, decls.subList(0, i + 1));
       }
     }
     return 0;
   }
   return ASTNodes.getInsertionIndex(newDecl, decls);
 }
  /*
   * Evaluates possible return expressions. The favourite expression is returned.
   */
  private Expression evaluateReturnExpressions(
      AST ast, ITypeBinding returnBinding, int returnOffset) {
    CompilationUnit root = (CompilationUnit) fMethodDecl.getRoot();

    Expression result = null;
    if (returnBinding != null) {
      ScopeAnalyzer analyzer = new ScopeAnalyzer(root);
      IBinding[] bindings =
          analyzer.getDeclarationsInScope(
              returnOffset, ScopeAnalyzer.VARIABLES | ScopeAnalyzer.CHECK_VISIBILITY);
      for (int i = 0; i < bindings.length; i++) {
        IVariableBinding curr = (IVariableBinding) bindings[i];
        ITypeBinding type = curr.getType();
        if (type != null && type.isAssignmentCompatible(returnBinding) && testModifier(curr)) {
          if (result == null) {
            result = ast.newSimpleName(curr.getName());
          }
          addLinkedPositionProposal(RETURN_EXPRESSION_KEY, curr.getName(), null);
        }
      }
    }
    Expression defaultExpression =
        ASTNodeFactory.newDefaultExpression(
            ast, fMethodDecl.getReturnType2(), fMethodDecl.getExtraDimensions());
    addLinkedPositionProposal(RETURN_EXPRESSION_KEY, ASTNodes.asString(defaultExpression), null);
    if (result == null) {
      return defaultExpression;
    }
    return result;
  }
  private static boolean canAddFinal(IBinding binding, ASTNode declNode) {
    if (!(binding instanceof IVariableBinding)) return false;

    IVariableBinding varbinding = (IVariableBinding) binding;
    int modifiers = varbinding.getModifiers();
    if (Modifier.isFinal(modifiers)
        || Modifier.isVolatile(modifiers)
        || Modifier.isTransient(modifiers)) return false;

    ASTNode parent = ASTNodes.getParent(declNode, VariableDeclarationExpression.class);
    if (parent != null && ((VariableDeclarationExpression) parent).fragments().size() > 1)
      return false;

    if (varbinding.isField() && !Modifier.isPrivate(modifiers)) return false;

    if (varbinding.isParameter()) {
      ASTNode varDecl = declNode.getParent();
      if (varDecl instanceof MethodDeclaration) {
        MethodDeclaration declaration = (MethodDeclaration) varDecl;
        if (declaration.getBody() == null) return false;
      }
    }

    return true;
  }
 private ASTNode getCommonParent(ASTNode node1, ASTNode node2) {
   ASTNode parent = node1.getParent();
   while (parent != null && !ASTNodes.isParent(node2, parent)) {
     parent = parent.getParent();
   }
   return parent;
 }
 /**
  * Checks if the assignment needs a downcast and inserts it if necessary
  *
  * @param expression the right hand-side
  * @param expressionType the type of the right hand-side. Can be null
  * @param ast the AST
  * @param variableType the Type of the variable the expression will be assigned to
  * @param is50OrHigher if <code>true</code> java 5.0 code will be assumed
  * @return the casted expression if necessary
  */
 private static Expression createNarrowCastIfNessecary(
     Expression expression,
     ITypeBinding expressionType,
     AST ast,
     ITypeBinding variableType,
     boolean is50OrHigher) {
   PrimitiveType castTo = null;
   if (variableType.isEqualTo(expressionType)) return expression; // no cast for same type
   if (is50OrHigher) {
     if (ast.resolveWellKnownType("java.lang.Character").isEqualTo(variableType)) // $NON-NLS-1$
     castTo = ast.newPrimitiveType(PrimitiveType.CHAR);
     if (ast.resolveWellKnownType("java.lang.Byte").isEqualTo(variableType)) // $NON-NLS-1$
     castTo = ast.newPrimitiveType(PrimitiveType.BYTE);
     if (ast.resolveWellKnownType("java.lang.Short").isEqualTo(variableType)) // $NON-NLS-1$
     castTo = ast.newPrimitiveType(PrimitiveType.SHORT);
   }
   if (ast.resolveWellKnownType("char").isEqualTo(variableType)) // $NON-NLS-1$
   castTo = ast.newPrimitiveType(PrimitiveType.CHAR);
   if (ast.resolveWellKnownType("byte").isEqualTo(variableType)) // $NON-NLS-1$
   castTo = ast.newPrimitiveType(PrimitiveType.BYTE);
   if (ast.resolveWellKnownType("short").isEqualTo(variableType)) // $NON-NLS-1$
   castTo = ast.newPrimitiveType(PrimitiveType.SHORT);
   if (castTo != null) {
     CastExpression cast = ast.newCastExpression();
     if (ASTNodes.needsParentheses(expression)) {
       ParenthesizedExpression parenthesized = ast.newParenthesizedExpression();
       parenthesized.setExpression(expression);
       cast.setExpression(parenthesized);
     } else cast.setExpression(expression);
     cast.setType(castTo);
     return cast;
   }
   return expression;
 }
    private boolean callsWritingConstructor(
        MethodDeclaration methodDeclaration,
        HashSet writingConstructorBindings,
        Set visitedMethodDeclarations) {
      Block body = methodDeclaration.getBody();
      if (body == null) return false;

      List statements = body.statements();
      if (statements.size() == 0) return false;

      Statement statement = (Statement) statements.get(0);
      if (!(statement instanceof ConstructorInvocation)) return false;

      ConstructorInvocation invocation = (ConstructorInvocation) statement;
      IMethodBinding constructorBinding = invocation.resolveConstructorBinding();
      if (constructorBinding == null) return false;

      if (writingConstructorBindings.contains(constructorBinding)) {
        return true;
      } else {
        ASTNode declaration =
            ASTNodes.findDeclaration(constructorBinding, methodDeclaration.getParent());
        if (!(declaration instanceof MethodDeclaration)) return false;

        if (visitedMethodDeclarations.contains(declaration)) {
          return false;
        }
        visitedMethodDeclarations.add(methodDeclaration);
        return callsWritingConstructor(
            (MethodDeclaration) declaration, writingConstructorBindings, visitedMethodDeclarations);
      }
    }
 private static Set<String> getPreviousExceptionNames(List<Type> list, ASTNode missingNode) {
   Set<String> previousNames = new HashSet<>();
   for (int i = 0; i < list.size() && missingNode != list.get(i); i++) {
     Type curr = list.get(i);
     previousNames.add(ASTNodes.getTypeName(curr));
   }
   return previousNames;
 }
 /**
  * Returns the type to which the new constant will be added to. It is the first non-anonymous
  * parent.
  *
  * @return the type to add the new constant to
  * @throws JavaModelException shouldn't happen
  */
 private AbstractTypeDeclaration getContainingTypeDeclarationNode() throws JavaModelException {
   AbstractTypeDeclaration result =
       (AbstractTypeDeclaration)
           ASTNodes.getParent(
               getSelectedExpression().getAssociatedNode(), AbstractTypeDeclaration.class);
   Assert.isNotNull(result);
   return result;
 }
 private boolean processCompilerError(RefactoringStatus result, ASTNode node) {
   Message[] messages = ASTNodes.getMessages(node, ASTNodes.INCLUDE_ALL_PARENTS);
   if (messages.length == 0) return false;
   result.addFatalError(
       Messages.format(
           "Compiler errors with the class to be refactored",
           new String[] {targetClass.getElementName(), messages[0].getMessage()}));
   return true;
 }
  public static void getMissingJavadocTagProposals(
      IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) {
    ASTNode node = problem.getCoveringNode(context.getASTRoot());
    if (node == null) {
      return;
    }
    node = ASTNodes.getNormalizedNode(node);

    BodyDeclaration bodyDeclaration = ASTResolving.findParentBodyDeclaration(node);
    if (bodyDeclaration == null) {
      return;
    }
    Javadoc javadoc = bodyDeclaration.getJavadoc();
    if (javadoc == null) {
      return;
    }

    String label;
    StructuralPropertyDescriptor location = node.getLocationInParent();
    if (location == SingleVariableDeclaration.NAME_PROPERTY) {
      label = CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_paramtag_description;
      if (node.getParent().getLocationInParent() != MethodDeclaration.PARAMETERS_PROPERTY) {
        return; // paranoia checks
      }
    } else if (location == TypeParameter.NAME_PROPERTY) {
      label = CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_paramtag_description;
      StructuralPropertyDescriptor parentLocation = node.getParent().getLocationInParent();
      if (parentLocation != MethodDeclaration.TYPE_PARAMETERS_PROPERTY
          && parentLocation != TypeDeclaration.TYPE_PARAMETERS_PROPERTY) {
        return; // paranoia checks
      }
    } else if (location == MethodDeclaration.RETURN_TYPE2_PROPERTY) {
      label = CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_returntag_description;
    } else if (location == MethodDeclaration.THROWN_EXCEPTION_TYPES_PROPERTY) {
      label = CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_throwstag_description;
    } else {
      return;
    }
    ASTRewriteCorrectionProposal proposal =
        new AddMissingJavadocTagProposal(
            label,
            context.getCompilationUnit(),
            bodyDeclaration,
            node,
            IProposalRelevance.ADD_MISSING_TAG);
    proposals.add(proposal);

    String label2 = CorrectionMessages.JavadocTagsSubProcessor_addjavadoc_allmissing_description;
    ASTRewriteCorrectionProposal addAllMissing =
        new AddAllMissingJavadocTagsProposal(
            label2,
            context.getCompilationUnit(),
            bodyDeclaration,
            IProposalRelevance.ADD_ALL_MISSING_TAGS);
    proposals.add(addAllMissing);
  }
 /*
  * Check if the node is in a block. We don't want to update declarations
  */
 private static boolean isNotInBlock(ASTNode parent) {
   ASTNode statement = parent.getParent();
   boolean isStatement = statement.getNodeType() != ASTNode.EXPRESSION_STATEMENT;
   ASTNode block = statement.getParent();
   boolean isBlock =
       block.getNodeType() == ASTNode.BLOCK || block.getNodeType() == ASTNode.SWITCH_STATEMENT;
   boolean isControlStatemenBody =
       ASTNodes.isControlStatementBody(statement.getLocationInParent());
   return isStatement || !(isBlock || isControlStatemenBody);
 }
Пример #14
0
  public void testPartialCU1() throws Exception {
    IPackageFragment pack1 = fSourceFolder.createPackageFragment("test1", false, null);
    StringBuffer buf = new StringBuffer();
    buf.append("package test1;\n");
    buf.append("import java.util.Vector;\n");
    buf.append("public class E {\n");
    buf.append("    private int fField1;\n");
    buf.append("    private int fField2;\n");
    buf.append("    public void foo1() {\n");
    buf.append("        fField1 = fField2;\n");
    buf.append("    }\n");
    buf.append("    public int foo1(int i) {\n");
    buf.append("        return i;\n");
    buf.append("    }\n");
    buf.append("}");
    String existing = buf.toString();
    ICompilationUnit cu = pack1.createCompilationUnit("E.java", existing, false, null);

    String statement = "fField1 = fField2;";
    int offset = existing.indexOf(statement);

    CompilationUnit astRoot = getPartialCompilationUnit(cu, offset);
    String string = ASTNodes.asFormattedString(astRoot, 0, String.valueOf('\n'), null);

    buf = new StringBuffer();
    buf.append("package test1;\n");
    buf.append("import java.util.Vector;\n");
    buf.append("public class E {\n");
    buf.append("    private int fField1;\n");
    buf.append("    private int fField2;\n");
    buf.append("    public void foo1() {\n");
    buf.append("        fField1 = fField2;\n");
    buf.append("    }\n");
    buf.append("    public int foo1(int i) {\n");
    buf.append("    }\n");
    buf.append("}");
    String expected = buf.toString();

    assertEqualString(string, expected);

    offset = expected.indexOf(statement);

    ASTNode node = NodeFinder.perform(astRoot, offset, statement.length());
    Assignment assignment = (Assignment) ((ExpressionStatement) node).getExpression();
    Expression e1 = assignment.getLeftHandSide();
    Expression e2 = assignment.getRightHandSide();
    assertNotNull(e1.resolveTypeBinding());
    assertNotNull(e2.resolveTypeBinding());

    assertTrue(((SimpleName) e1).resolveBinding() instanceof IVariableBinding);
    assertTrue(((SimpleName) e2).resolveBinding() instanceof IVariableBinding);

    assertAllBindings(astRoot);
  }
  private SingleVariableDeclaration createParameterDeclaration(
      String parameterName,
      VariableDeclarationFragment fragement,
      Expression arrayAccess,
      ForStatement statement,
      ImportRewrite importRewrite,
      ASTRewrite rewrite,
      TextEditGroup group,
      LinkedProposalPositionGroup pg,
      boolean makeFinal) {
    CompilationUnit compilationUnit = (CompilationUnit) arrayAccess.getRoot();
    AST ast = compilationUnit.getAST();

    SingleVariableDeclaration result = ast.newSingleVariableDeclaration();

    SimpleName name = ast.newSimpleName(parameterName);
    pg.addPosition(rewrite.track(name), true);
    result.setName(name);

    ITypeBinding arrayTypeBinding = arrayAccess.resolveTypeBinding();
    Type type =
        importType(arrayTypeBinding.getElementType(), statement, importRewrite, compilationUnit);
    if (arrayTypeBinding.getDimensions() != 1) {
      type = ast.newArrayType(type, arrayTypeBinding.getDimensions() - 1);
    }
    result.setType(type);

    if (fragement != null) {
      VariableDeclarationStatement declaration =
          (VariableDeclarationStatement) fragement.getParent();
      ModifierRewrite.create(rewrite, result).copyAllModifiers(declaration, group);
    }
    if (makeFinal
        && (fragement == null
            || ASTNodes.findModifierNode(Modifier.FINAL, ASTNodes.getModifiers(fragement))
                == null)) {
      ModifierRewrite.create(rewrite, result).setModifiers(Modifier.FINAL, 0, group);
    }

    return result;
  }
 public void checkInput(RefactoringStatus status, String methodName, ASTNode destination) {
   ITypeBinding[] arguments = getArgumentTypes();
   ITypeBinding type = ASTNodes.getEnclosingType(destination);
   status.merge(Checks.checkMethodInType(type, methodName, arguments));
   ITypeBinding superClass = type.getSuperclass();
   if (superClass != null) {
     status.merge(Checks.checkMethodInHierarchy(superClass, methodName, null, arguments));
   }
   for (ITypeBinding superInterface : type.getInterfaces()) {
     status.merge(Checks.checkMethodInHierarchy(superInterface, methodName, null, arguments));
   }
 }
 public static ASTNode getEnclosingNode(ASTNode firstSelectedNode) {
   ASTNode enclosingNode;
   if (firstSelectedNode instanceof MethodReference) {
     enclosingNode = firstSelectedNode;
   } else {
     enclosingNode = ASTResolving.findEnclosingLambdaExpression(firstSelectedNode);
     if (enclosingNode != null) {
       enclosingNode = ((LambdaExpression) enclosingNode).getBody();
     } else {
       enclosingNode = ASTNodes.getParent(firstSelectedNode, BodyDeclaration.class);
     }
   }
   return enclosingNode;
 }
  public static void getUnusedAndUndocumentedParameterOrExceptionProposals(
      IInvocationContext context, IProblemLocation problem, Collection<ICommandAccess> proposals) {
    ICompilationUnit cu = context.getCompilationUnit();
    IJavaProject project = cu.getJavaProject();

    if (!JavaCore.ENABLED.equals(project.getOption(JavaCore.COMPILER_DOC_COMMENT_SUPPORT, true))) {
      return;
    }

    int problemId = problem.getProblemId();
    boolean isUnusedTypeParam = problemId == IProblem.UnusedTypeParameter;
    boolean isUnusedParam = problemId == IProblem.ArgumentIsNeverUsed || isUnusedTypeParam;
    String key =
        isUnusedParam
            ? JavaCore.COMPILER_PB_UNUSED_PARAMETER_INCLUDE_DOC_COMMENT_REFERENCE
            : JavaCore.COMPILER_PB_UNUSED_DECLARED_THROWN_EXCEPTION_INCLUDE_DOC_COMMENT_REFERENCE;

    if (!JavaCore.ENABLED.equals(project.getOption(key, true))) {
      return;
    }

    ASTNode node = problem.getCoveringNode(context.getASTRoot());
    if (node == null) {
      return;
    }

    BodyDeclaration bodyDecl = ASTResolving.findParentBodyDeclaration(node);
    if (bodyDecl == null || ASTResolving.getParentMethodOrTypeBinding(bodyDecl) == null) {
      return;
    }

    String label;
    if (isUnusedTypeParam) {
      label = CorrectionMessages.JavadocTagsSubProcessor_document_type_parameter_description;
    } else if (isUnusedParam) {
      label = CorrectionMessages.JavadocTagsSubProcessor_document_parameter_description;
    } else {
      node = ASTNodes.getNormalizedNode(node);
      label = CorrectionMessages.JavadocTagsSubProcessor_document_exception_description;
    }
    ASTRewriteCorrectionProposal proposal =
        new AddMissingJavadocTagProposal(
            label,
            context.getCompilationUnit(),
            bodyDecl,
            node,
            IProposalRelevance.DOCUMENT_UNUSED_ITEM);
    proposals.add(proposal);
  }
    private MethodDeclaration getWritingConstructor(SimpleName name) {
      Assignment assignement = (Assignment) ASTNodes.getParent(name, Assignment.class);
      if (assignement == null) return null;

      ASTNode expression = assignement.getParent();
      if (!(expression instanceof ExpressionStatement)) return null;

      ASTNode block = expression.getParent();
      if (!(block instanceof Block)) return null;

      ASTNode methodDeclaration = block.getParent();
      if (!(methodDeclaration instanceof MethodDeclaration)) return null;

      return (MethodDeclaration) methodDeclaration;
    }
  @Override
  public void run(IProgressMonitor monitor) throws CoreException {
    if (monitor == null) monitor = new NullProgressMonitor();
    try {
      monitor.beginTask("", 1); // $NON-NLS-1$
      monitor.setTaskName(CodeGenerationMessages.GenerateToStringOperation_description);

      AbstractTypeDeclaration declaration =
          (AbstractTypeDeclaration)
              ASTNodes.findDeclaration(fContext.getTypeBinding(), fRewrite.getRoot());
      ListRewrite rewriter =
          fRewrite
              .getASTRewrite()
              .getListRewrite(declaration, declaration.getBodyDeclarationsProperty());
      if (fContext.getTypeBinding() != null && rewriter != null) {

        MethodDeclaration toStringMethod = fGenerator.generateToStringMethod();

        List<BodyDeclaration> list = declaration.bodyDeclarations();
        BodyDeclaration replace = findMethodToReplace(list, toStringMethod);
        if (replace == null
            || ((Boolean)
                    toStringMethod.getProperty(AbstractToStringGenerator.OVERWRITE_METHOD_PROPERTY))
                .booleanValue()) insertMethod(toStringMethod, rewriter, replace);

        List<MethodDeclaration> helperMethods = fGenerator.generateHelperMethods();
        for (Iterator<MethodDeclaration> iterator = helperMethods.iterator();
            iterator.hasNext(); ) {
          MethodDeclaration method = iterator.next();
          replace = findMethodToReplace(list, method);
          if (replace == null
              || ((Boolean) method.getProperty(AbstractToStringGenerator.OVERWRITE_METHOD_PROPERTY))
                  .booleanValue()) {
            insertMethod(method, rewriter, replace);
          }
        }

        JavaModelUtil.applyEdit(
            (ICompilationUnit) fUnit.getJavaElement(),
            fRewrite.createChange(true).getEdit(),
            false,
            monitor);
      }

    } finally {
      monitor.done();
    }
  }
 /**
  * Converts an assignment, postfix expression or prefix expression into an assignable equivalent
  * expression using the getter.
  *
  * @param node the assignment/prefix/postfix node
  * @param astRewrite the astRewrite to use
  * @param getterExpression the expression to insert for read accesses or <code>null</code> if such
  *     an expression does not exist
  * @param variableType the type of the variable that the result will be assigned to
  * @param is50OrHigher <code>true</code> if a 5.0 or higher environment can be used
  * @return an expression that can be assigned to the type variableType with node being replaced by
  *     a equivalent expression using the getter
  */
 public static Expression getAssignedValue(
     ASTNode node,
     ASTRewrite astRewrite,
     Expression getterExpression,
     ITypeBinding variableType,
     boolean is50OrHigher) {
   InfixExpression.Operator op = null;
   AST ast = astRewrite.getAST();
   if (isNotInBlock(node)) return null;
   if (node.getNodeType() == ASTNode.ASSIGNMENT) {
     Assignment assignment = ((Assignment) node);
     Expression rightHandSide = assignment.getRightHandSide();
     Expression copiedRightOp = (Expression) astRewrite.createCopyTarget(rightHandSide);
     if (assignment.getOperator() == Operator.ASSIGN) {
       ITypeBinding rightHandSideType = rightHandSide.resolveTypeBinding();
       copiedRightOp =
           createNarrowCastIfNessecary(
               copiedRightOp, rightHandSideType, ast, variableType, is50OrHigher);
       return copiedRightOp;
     }
     if (getterExpression != null) {
       InfixExpression infix = ast.newInfixExpression();
       infix.setLeftOperand(getterExpression);
       infix.setOperator(ASTNodes.convertToInfixOperator(assignment.getOperator()));
       infix.setRightOperand(copiedRightOp);
       ITypeBinding infixType = infix.resolveTypeBinding();
       return createNarrowCastIfNessecary(infix, infixType, ast, variableType, is50OrHigher);
     }
   } else if (node.getNodeType() == ASTNode.POSTFIX_EXPRESSION) {
     PostfixExpression po = (PostfixExpression) node;
     if (po.getOperator() == PostfixExpression.Operator.INCREMENT)
       op = InfixExpression.Operator.PLUS;
     if (po.getOperator() == PostfixExpression.Operator.DECREMENT)
       op = InfixExpression.Operator.MINUS;
   } else if (node.getNodeType() == ASTNode.PREFIX_EXPRESSION) {
     PrefixExpression pe = (PrefixExpression) node;
     if (pe.getOperator() == PrefixExpression.Operator.INCREMENT)
       op = InfixExpression.Operator.PLUS;
     if (pe.getOperator() == PrefixExpression.Operator.DECREMENT)
       op = InfixExpression.Operator.MINUS;
   }
   if (op != null && getterExpression != null) {
     return createInfixInvocationFromPostPrefixExpression(
         op, getterExpression, ast, variableType, is50OrHigher);
   }
   return null;
 }
 private void checkExpression(RefactoringStatus status) {
   ASTNode[] nodes = getSelectedNodes();
   if (nodes != null && nodes.length == 1) {
     ASTNode node = nodes[0];
     if (node instanceof Type) {
       status.addFatalError(
           RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_type_reference,
           JavaStatusContext.create(fCUnit, node));
     } else if (node.getLocationInParent() == SwitchCase.EXPRESSION_PROPERTY) {
       status.addFatalError(
           RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_switch_case,
           JavaStatusContext.create(fCUnit, node));
     } else if (node instanceof Annotation || ASTNodes.getParent(node, Annotation.class) != null) {
       status.addFatalError(
           RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_from_annotation,
           JavaStatusContext.create(fCUnit, node));
     }
   }
 }
 @Override
 public void endVisit(CompilationUnit node) {
   postProcessSelectedNodes(internalGetSelectedNodes());
   ASTNode enclosingNode = null;
   superCall:
   {
     if (getStatus().hasFatalError()) break superCall;
     if (!hasSelectedNodes()) {
       ASTNode coveringNode = getLastCoveringNode();
       if (coveringNode instanceof Block) {
         Block block = (Block) coveringNode;
         Message[] messages = ASTNodes.getMessages(block, ASTNodes.NODE_ONLY);
         if (messages.length > 0) {
           invalidSelection(
               RefactoringCoreMessages.SurroundWithTryCatchAnalyzer_compile_errors,
               JavaStatusContext.create(getCompilationUnit(), block));
           break superCall;
         }
       }
       invalidSelection(RefactoringCoreMessages.SurroundWithTryCatchAnalyzer_doesNotCover);
       break superCall;
     }
     enclosingNode = getEnclosingNode(getFirstSelectedNode());
     boolean isValidEnclosingNode =
         enclosingNode instanceof MethodDeclaration || enclosingNode instanceof Initializer;
     if (fSurroundWithTryCatch) {
       isValidEnclosingNode =
           isValidEnclosingNode
               || enclosingNode instanceof MethodReference
               || enclosingNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY;
     }
     if (!isValidEnclosingNode) {
       invalidSelection(RefactoringCoreMessages.SurroundWithTryCatchAnalyzer_doesNotContain);
       break superCall;
     }
     if (!validSelectedNodes()) {
       invalidSelection(RefactoringCoreMessages.SurroundWithTryCatchAnalyzer_onlyStatements);
     }
     fLocals = LocalDeclarationAnalyzer.perform(enclosingNode, getSelection());
   }
   super.endVisit(node);
 }
  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;
  }
    private void insertAllMissingMethodTags(ASTRewrite rewriter, MethodDeclaration methodDecl) {
      AST ast = methodDecl.getAST();
      Javadoc javadoc = methodDecl.getJavadoc();
      ListRewrite tagsRewriter = rewriter.getListRewrite(javadoc, Javadoc.TAGS_PROPERTY);

      List<TypeParameter> typeParams = methodDecl.typeParameters();
      ASTNode root = methodDecl.getRoot();
      if (root instanceof CompilationUnit) {
        ITypeRoot typeRoot = ((CompilationUnit) root).getTypeRoot();
        if (typeRoot != null
            && !StubUtility.shouldGenerateMethodTypeParameterTags(typeRoot.getJavaProject()))
          typeParams = Collections.emptyList();
      }
      List<String> typeParamNames = new ArrayList<>();
      for (int i = typeParams.size() - 1; i >= 0; i--) {
        TypeParameter decl = typeParams.get(i);
        String name = '<' + decl.getName().getIdentifier() + '>';
        if (findTag(javadoc, TagElement.TAG_PARAM, name) == null) {
          TagElement newTag = ast.newTagElement();
          newTag.setTagName(TagElement.TAG_PARAM);
          TextElement text = ast.newTextElement();
          text.setText(name);
          newTag.fragments().add(text);
          insertTabStop(rewriter, newTag.fragments(), "typeParam" + i); // $NON-NLS-1$
          insertTag(tagsRewriter, newTag, getPreviousTypeParamNames(typeParams, decl));
        }
        typeParamNames.add(name);
      }
      List<SingleVariableDeclaration> params = methodDecl.parameters();
      for (int i = params.size() - 1; i >= 0; i--) {
        SingleVariableDeclaration decl = params.get(i);
        String name = decl.getName().getIdentifier();
        if (findTag(javadoc, TagElement.TAG_PARAM, name) == null) {
          TagElement newTag = ast.newTagElement();
          newTag.setTagName(TagElement.TAG_PARAM);
          newTag.fragments().add(ast.newSimpleName(name));
          insertTabStop(rewriter, newTag.fragments(), "methParam" + i); // $NON-NLS-1$
          Set<String> sameKindLeadingNames = getPreviousParamNames(params, decl);
          sameKindLeadingNames.addAll(typeParamNames);
          insertTag(tagsRewriter, newTag, sameKindLeadingNames);
        }
      }
      if (!methodDecl.isConstructor()) {
        Type type = methodDecl.getReturnType2();
        if (!type.isPrimitiveType()
            || (((PrimitiveType) type).getPrimitiveTypeCode() != PrimitiveType.VOID)) {
          if (findTag(javadoc, TagElement.TAG_RETURN, null) == null) {
            TagElement newTag = ast.newTagElement();
            newTag.setTagName(TagElement.TAG_RETURN);
            insertTabStop(rewriter, newTag.fragments(), "return"); // $NON-NLS-1$
            insertTag(tagsRewriter, newTag, null);
          }
        }
      }
      List<Type> thrownExceptions = methodDecl.thrownExceptionTypes();
      for (int i = thrownExceptions.size() - 1; i >= 0; i--) {
        Type exception = thrownExceptions.get(i);
        ITypeBinding binding = exception.resolveBinding();
        if (binding != null) {
          String name = binding.getName();
          if (findThrowsTag(javadoc, name) == null) {
            TagElement newTag = ast.newTagElement();
            newTag.setTagName(TagElement.TAG_THROWS);
            TextElement excNode = ast.newTextElement();
            excNode.setText(ASTNodes.getQualifiedTypeName(exception));
            newTag.fragments().add(excNode);
            insertTabStop(rewriter, newTag.fragments(), "exception" + i); // $NON-NLS-1$
            insertTag(tagsRewriter, newTag, getPreviousExceptionNames(thrownExceptions, exception));
          }
        }
      }
    }
    private boolean fieldCanBeFinal(
        VariableDeclarationFragment fragment, IVariableBinding binding) {
      if (Modifier.isStatic(((FieldDeclaration) fragment.getParent()).getModifiers())) return false;

      if (!fWrittenVariables.containsKey(binding)) {
        // variable is not written
        if (fragment.getInitializer() == null) { // variable is not initialized
          return false;
        } else {
          return true;
        }
      }

      if (fragment.getInitializer() != null) // variable is initialized and written
      return false;

      ITypeBinding declaringClass = binding.getDeclaringClass();
      if (declaringClass == null) return false;

      ArrayList writes = (ArrayList) fWrittenVariables.get(binding);
      if (!isWrittenInTypeConstructors(writes, declaringClass)) return false;

      HashSet writingConstructorBindings = new HashSet();
      ArrayList writingConstructors = new ArrayList();
      for (int i = 0; i < writes.size(); i++) {
        SimpleName name = (SimpleName) writes.get(i);
        MethodDeclaration constructor = getWritingConstructor(name);
        if (writingConstructors.contains(
            constructor)) // variable is written twice or more in constructor
        return false;

        if (canReturn(constructor)) return false;

        writingConstructors.add(constructor);
        IMethodBinding constructorBinding = constructor.resolveBinding();
        if (constructorBinding == null) return false;

        writingConstructorBindings.add(constructorBinding);
      }

      for (int i = 0; i < writingConstructors.size(); i++) {
        MethodDeclaration constructor = (MethodDeclaration) writingConstructors.get(i);
        if (callsWritingConstructor(
            constructor,
            writingConstructorBindings)) // writing constructor calls other writing constructor
        return false;
      }

      MethodDeclaration constructor = (MethodDeclaration) writingConstructors.get(0);
      TypeDeclaration typeDecl =
          (TypeDeclaration) ASTNodes.getParent(constructor, TypeDeclaration.class);
      if (typeDecl == null) return false;

      MethodDeclaration[] methods = typeDecl.getMethods();
      for (int i = 0; i < methods.length; i++) {
        if (methods[i].isConstructor()) {
          IMethodBinding methodBinding = methods[i].resolveBinding();
          if (methodBinding == null) return false;

          if (!writingConstructorBindings.contains(methodBinding)) {
            if (!callsWritingConstructor(
                methods[i],
                writingConstructorBindings)) // non writing constructor does not call a writing
              // constructor
              return false;
          }
        }
      }

      return true;
    }
 @Override
 public void endVisit(CompilationUnit node) {
   RefactoringStatus status = getStatus();
   superCall:
   {
     if (status.hasFatalError()) break superCall;
     if (!hasSelectedNodes()) {
       ASTNode coveringNode = getLastCoveringNode();
       if (coveringNode instanceof Block
           && coveringNode.getParent() instanceof MethodDeclaration) {
         MethodDeclaration methodDecl = (MethodDeclaration) coveringNode.getParent();
         Message[] messages = ASTNodes.getMessages(methodDecl, ASTNodes.NODE_ONLY);
         if (messages.length > 0) {
           status.addFatalError(
               Messages.format(
                   RefactoringCoreMessages.ExtractMethodAnalyzer_compile_errors,
                   BasicElementLabels.getJavaElementName(methodDecl.getName().getIdentifier())),
               JavaStatusContext.create(fCUnit, methodDecl));
           break superCall;
         }
       }
       status.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_invalid_selection);
       break superCall;
     }
     fEnclosingBodyDeclaration =
         (BodyDeclaration) ASTNodes.getParent(getFirstSelectedNode(), BodyDeclaration.class);
     if (fEnclosingBodyDeclaration == null
         || (fEnclosingBodyDeclaration.getNodeType() != ASTNode.METHOD_DECLARATION
             && fEnclosingBodyDeclaration.getNodeType() != ASTNode.FIELD_DECLARATION
             && fEnclosingBodyDeclaration.getNodeType() != ASTNode.INITIALIZER)) {
       status.addFatalError(RefactoringCoreMessages.ExtractMethodAnalyzer_invalid_selection);
       break superCall;
     } else if (ASTNodes.getEnclosingType(fEnclosingBodyDeclaration) == null) {
       status.addFatalError(
           RefactoringCoreMessages.ExtractMethodAnalyzer_compile_errors_no_parent_binding);
       break superCall;
     } else if (fEnclosingBodyDeclaration.getNodeType() == ASTNode.METHOD_DECLARATION) {
       fEnclosingMethodBinding = ((MethodDeclaration) fEnclosingBodyDeclaration).resolveBinding();
     }
     if (!isSingleExpressionOrStatementSet()) {
       status.addFatalError(
           RefactoringCoreMessages.ExtractMethodAnalyzer_single_expression_or_set);
       break superCall;
     }
     if (isExpressionSelected()) {
       ASTNode expression = getFirstSelectedNode();
       if (expression instanceof Name) {
         Name name = (Name) expression;
         if (name.resolveBinding() instanceof ITypeBinding) {
           status.addFatalError(
               RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_type_reference);
           break superCall;
         }
         if (name.resolveBinding() instanceof IMethodBinding) {
           status.addFatalError(
               RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_method_name_reference);
           break superCall;
         }
         if (name.resolveBinding() instanceof IVariableBinding) {
           StructuralPropertyDescriptor locationInParent = name.getLocationInParent();
           if (locationInParent == QualifiedName.NAME_PROPERTY
               || (locationInParent == FieldAccess.NAME_PROPERTY
                   && !(((FieldAccess) name.getParent()).getExpression()
                       instanceof ThisExpression))) {
             status.addFatalError(
                 RefactoringCoreMessages
                     .ExtractMethodAnalyzer_cannot_extract_part_of_qualified_name);
             break superCall;
           }
         }
         if (name.isSimpleName() && ((SimpleName) name).isDeclaration()) {
           status.addFatalError(
               RefactoringCoreMessages.ExtractMethodAnalyzer_cannot_extract_name_in_declaration);
           break superCall;
         }
       }
       fForceStatic =
           ASTNodes.getParent(expression, ASTNode.SUPER_CONSTRUCTOR_INVOCATION) != null
               || ASTNodes.getParent(expression, ASTNode.CONSTRUCTOR_INVOCATION) != null;
     }
     status.merge(LocalTypeAnalyzer.perform(fEnclosingBodyDeclaration, getSelection()));
     computeLastStatementSelected();
   }
   super.endVisit(node);
 }
  private void computeOutput(RefactoringStatus status) {
    // First find all writes inside the selection.
    FlowContext flowContext = new FlowContext(0, fMaxVariableId + 1);
    flowContext.setConsiderAccessMode(true);
    flowContext.setComputeMode(FlowContext.RETURN_VALUES);
    FlowInfo returnInfo = new InOutFlowAnalyzer(flowContext).perform(getSelectedNodes());
    IVariableBinding[] returnValues =
        returnInfo.get(flowContext, FlowInfo.WRITE | FlowInfo.WRITE_POTENTIAL | FlowInfo.UNKNOWN);

    // Compute a selection that exactly covers the selected nodes
    IRegion region = getSelectedNodeRange();
    Selection selection = Selection.createFromStartLength(region.getOffset(), region.getLength());

    List<IVariableBinding> localReads = new ArrayList<>();
    flowContext.setComputeMode(FlowContext.ARGUMENTS);
    FlowInfo argInfo =
        new InputFlowAnalyzer(flowContext, selection, true).perform(fEnclosingBodyDeclaration);
    IVariableBinding[] reads =
        argInfo.get(flowContext, FlowInfo.READ | FlowInfo.READ_POTENTIAL | FlowInfo.UNKNOWN);
    outer:
    for (int i = 0; i < returnValues.length && localReads.size() < returnValues.length; i++) {
      IVariableBinding binding = returnValues[i];
      for (int x = 0; x < reads.length; x++) {
        if (reads[x] == binding) {
          localReads.add(binding);
          fReturnValue = binding;
          continue outer;
        }
      }
    }
    switch (localReads.size()) {
      case 0:
        fReturnValue = null;
        break;
      case 1:
        break;
      default:
        fReturnValue = null;
        StringBuffer affectedLocals = new StringBuffer();
        for (int i = 0; i < localReads.size(); i++) {
          IVariableBinding binding = localReads.get(i);
          String bindingName =
              BindingLabelProvider.getBindingLabel(
                  binding,
                  BindingLabelProvider.DEFAULT_TEXTFLAGS | JavaElementLabels.F_PRE_TYPE_SIGNATURE);
          affectedLocals.append(bindingName);
          if (i != localReads.size() - 1) {
            affectedLocals.append('\n');
          }
        }
        String message =
            MessageFormat.format(
                RefactoringCoreMessages.ExtractMethodAnalyzer_assignments_to_local,
                new Object[] {affectedLocals.toString()});
        status.addFatalError(message, JavaStatusContext.create(fCUnit, getSelection()));
        return;
    }
    List<IVariableBinding> callerLocals = new ArrayList<>(5);
    FlowInfo localInfo =
        new InputFlowAnalyzer(flowContext, selection, false).perform(fEnclosingBodyDeclaration);
    IVariableBinding[] writes =
        localInfo.get(flowContext, FlowInfo.WRITE | FlowInfo.WRITE_POTENTIAL | FlowInfo.UNKNOWN);
    for (int i = 0; i < writes.length; i++) {
      IVariableBinding write = writes[i];
      if (getSelection().covers(ASTNodes.findDeclaration(write, fEnclosingBodyDeclaration)))
        callerLocals.add(write);
    }
    fCallerLocals = callerLocals.toArray(new IVariableBinding[callerLocals.size()]);
    if (fReturnValue != null
        && getSelection().covers(ASTNodes.findDeclaration(fReturnValue, fEnclosingBodyDeclaration)))
      fReturnLocal = fReturnValue;
  }
 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 doAddField(CompilationUnit astRoot) {
    SimpleName node = fOriginalNode;
    boolean isInDifferentCU = false;

    ASTNode newTypeDecl = astRoot.findDeclaringNode(fSenderBinding);
    if (newTypeDecl == null) {
      astRoot = ASTResolving.createQuickFixAST(getCompilationUnit(), null);
      newTypeDecl = astRoot.findDeclaringNode(fSenderBinding.getKey());
      isInDifferentCU = true;
    }
    ImportRewrite imports = createImportRewrite(astRoot);
    ImportRewriteContext importRewriteContext =
        new ContextSensitiveImportRewriteContext(
            ASTResolving.findParentBodyDeclaration(node), imports);

    if (newTypeDecl != null) {
      AST ast = newTypeDecl.getAST();

      ASTRewrite rewrite = ASTRewrite.create(ast);

      VariableDeclarationFragment fragment = ast.newVariableDeclarationFragment();
      fragment.setName(ast.newSimpleName(node.getIdentifier()));

      Type type = evaluateVariableType(ast, imports, importRewriteContext, fSenderBinding);

      FieldDeclaration newDecl = ast.newFieldDeclaration(fragment);
      newDecl.setType(type);
      newDecl
          .modifiers()
          .addAll(ASTNodeFactory.newModifiers(ast, evaluateFieldModifiers(newTypeDecl)));

      if (fSenderBinding.isInterface() || fVariableKind == CONST_FIELD) {
        fragment.setInitializer(ASTNodeFactory.newDefaultExpression(ast, type, 0));
      }

      ChildListPropertyDescriptor property = ASTNodes.getBodyDeclarationsProperty(newTypeDecl);
      List<BodyDeclaration> decls =
          ASTNodes.<BodyDeclaration>getChildListProperty(newTypeDecl, property);

      int maxOffset = isInDifferentCU ? -1 : node.getStartPosition();

      int insertIndex = findFieldInsertIndex(decls, newDecl, maxOffset);

      ListRewrite listRewriter = rewrite.getListRewrite(newTypeDecl, property);
      listRewriter.insertAt(newDecl, insertIndex, null);

      ModifierCorrectionSubProcessor.installLinkedVisibilityProposals(
          getLinkedProposalModel(), rewrite, newDecl.modifiers(), fSenderBinding.isInterface());

      addLinkedPosition(rewrite.track(newDecl.getType()), false, KEY_TYPE);
      if (!isInDifferentCU) {
        addLinkedPosition(rewrite.track(node), true, KEY_NAME);
      }
      addLinkedPosition(rewrite.track(fragment.getName()), false, KEY_NAME);

      if (fragment.getInitializer() != null) {
        addLinkedPosition(rewrite.track(fragment.getInitializer()), false, KEY_INITIALIZER);
      }
      return rewrite;
    }
    return null;
  }