/*
  * @see ASTVisitor#visit(Block)
  */
 public boolean visit(Block node) {
   this.fBuffer.append("{"); // $NON-NLS-1$
   for (Iterator it = node.statements().iterator(); it.hasNext(); ) {
     Statement s = (Statement) it.next();
     s.accept(this);
   }
   this.fBuffer.append("}"); // $NON-NLS-1$
   return false;
 }
  private void convertBody(
      Statement body,
      final IBinding indexBinding,
      final IBinding arrayBinding,
      final String parameterName,
      final ASTRewrite rewrite,
      final TextEditGroup editGroup,
      final LinkedProposalPositionGroup pg) {
    final AST ast = body.getAST();

    body.accept(
        new GenericVisitor() {
          @Override
          public boolean visit(ArrayAccess node) {
            IBinding binding = getBinding(node.getArray());
            if (arrayBinding.equals(binding)) {
              IBinding index = getBinding(node.getIndex());
              if (indexBinding.equals(index)) {
                replaceAccess(node);
              }
            }

            return super.visit(node);
          }

          private void replaceAccess(ASTNode node) {
            if (fElementDeclaration != null
                && node.getLocationInParent() == VariableDeclarationFragment.INITIALIZER_PROPERTY) {
              VariableDeclarationFragment fragment = (VariableDeclarationFragment) node.getParent();
              IBinding targetBinding = fragment.getName().resolveBinding();
              if (targetBinding != null) {
                VariableDeclarationStatement statement =
                    (VariableDeclarationStatement) fragment.getParent();

                if (statement.fragments().size() == 1) {
                  rewrite.remove(statement, editGroup);
                } else {
                  ListRewrite listRewrite =
                      rewrite.getListRewrite(
                          statement, VariableDeclarationStatement.FRAGMENTS_PROPERTY);
                  listRewrite.remove(fragment, editGroup);
                }

              } else {
                SimpleName name = ast.newSimpleName(parameterName);
                rewrite.replace(node, name, editGroup);
                pg.addPosition(rewrite.track(name), true);
              }
            } else {
              SimpleName name = ast.newSimpleName(parameterName);
              rewrite.replace(node, name, editGroup);
              pg.addPosition(rewrite.track(name), true);
            }
          }
        });
  }
 private List<Statement> getNextSiblings(Statement node) {
   if (node.getParent() instanceof Block) {
     final List<Statement> stmts = asList((Statement) node.getParent());
     final int indexOfNode = stmts.indexOf(node);
     final int siblingIndex = indexOfNode + 1;
     if (0 <= siblingIndex && siblingIndex < stmts.size()) {
       return stmts.subList(siblingIndex, stmts.size());
     }
   }
   return Collections.emptyList();
 }
 /*
  * @see ASTVisitor#visit(SwitchStatement)
  */
 public boolean visit(SwitchStatement node) {
   this.fBuffer.append("switch ("); // $NON-NLS-1$
   node.getExpression().accept(this);
   this.fBuffer.append(") "); // $NON-NLS-1$
   this.fBuffer.append("{"); // $NON-NLS-1$
   for (Iterator it = node.statements().iterator(); it.hasNext(); ) {
     Statement s = (Statement) it.next();
     s.accept(this);
   }
   this.fBuffer.append("}"); // $NON-NLS-1$
   return false;
 }
  private boolean lastStmtIsThrowOrReturn(Statement stmt) {
    final List<Statement> stmts = asList(stmt);
    if (stmts.isEmpty()) {
      return false;
    }

    final Statement lastStmt = stmts.get(stmts.size() - 1);
    switch (lastStmt.getNodeType()) {
      case RETURN_STATEMENT:
      case THROW_STATEMENT:
        return true;

      case IF_STATEMENT:
        final IfStatement ifStmt = (IfStatement) lastStmt;
        final Statement thenStmt = ifStmt.getThenStatement();
        final Statement elseStmt = ifStmt.getElseStatement();
        return lastStmtIsThrowOrReturn(thenStmt)
            && (elseStmt == null || lastStmtIsThrowOrReturn(elseStmt));

      default:
        return false;
    }
  }
  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;
  }
예제 #7
0
 /**
  * Copies the leading comment from the given statement.
  *
  * @param source the statement that supplies the leading comment
  * @since 2.1
  */
 void copyLeadingComment(Statement source) {
   setLeadingComment(source.getLeadingComment());
 }
  /*
   * returns false iff
   * <ul>
   * <li><code>indexBinding</code> is used for anything else then accessing
   * an element of <code>arrayBinding</code></li>
   * <li><code>arrayBinding</code> is assigned</li>
   * <li>an element of <code>arrayBinding</code> is assigned</li>
   * <li><code>lengthBinding</code> is referenced</li>
   * </ul>
   * within <code>body</code>
   */
  private boolean validateBody(ForStatement statement) {
    Statement body = statement.getBody();
    try {
      body.accept(
          new GenericVisitor() {
            /** {@inheritDoc} */
            @Override
            protected boolean visitNode(ASTNode node) {
              if (node instanceof Name) {
                Name name = (Name) node;
                IBinding nameBinding = name.resolveBinding();
                if (nameBinding == null) throw new InvalidBodyError();

                if (nameBinding.equals(fIndexBinding)) {
                  if (node.getLocationInParent() != ArrayAccess.INDEX_PROPERTY)
                    throw new InvalidBodyError();

                  ArrayAccess arrayAccess = (ArrayAccess) node.getParent();
                  Expression array = arrayAccess.getArray();
                  if (array instanceof QualifiedName) {
                    if (!(fArrayAccess instanceof QualifiedName)) throw new InvalidBodyError();

                    IBinding varBinding1 = ((QualifiedName) array).getQualifier().resolveBinding();
                    if (varBinding1 == null) throw new InvalidBodyError();

                    IBinding varBinding2 =
                        ((QualifiedName) fArrayAccess).getQualifier().resolveBinding();
                    if (!varBinding1.equals(varBinding2)) throw new InvalidBodyError();
                  } else if (array instanceof FieldAccess) {
                    Expression arrayExpression = ((FieldAccess) array).getExpression();
                    if (arrayExpression instanceof ThisExpression) {
                      if (fArrayAccess instanceof FieldAccess) {
                        Expression arrayAccessExpression =
                            ((FieldAccess) fArrayAccess).getExpression();
                        if (!(arrayAccessExpression instanceof ThisExpression))
                          throw new InvalidBodyError();
                      } else if (fArrayAccess instanceof QualifiedName) {
                        throw new InvalidBodyError();
                      }
                    } else {
                      if (!(fArrayAccess instanceof FieldAccess)) throw new InvalidBodyError();

                      Expression arrayAccessExpression =
                          ((FieldAccess) fArrayAccess).getExpression();
                      if (!arrayExpression.subtreeMatch(
                          new JdtASTMatcher(), arrayAccessExpression)) {
                        throw new InvalidBodyError();
                      }
                    }
                  } else {
                    if (fArrayAccess instanceof QualifiedName) {
                      throw new InvalidBodyError();
                    }
                    if (fArrayAccess instanceof FieldAccess) {
                      Expression arrayAccessExpression =
                          ((FieldAccess) fArrayAccess).getExpression();
                      if (!(arrayAccessExpression instanceof ThisExpression))
                        throw new InvalidBodyError();
                    }
                  }

                  IBinding binding = getBinding(array);
                  if (binding == null) throw new InvalidBodyError();

                  if (!fArrayBinding.equals(binding)) throw new InvalidBodyError();

                } else if (nameBinding.equals(fArrayBinding)) {
                  if (isAssigned(node)) throw new InvalidBodyError();
                } else if (nameBinding.equals(fLengthBinding)) {
                  throw new InvalidBodyError();
                } else if (fElementDeclaration != null
                    && nameBinding.equals(fElementDeclaration.getName().resolveBinding())) {
                  if (isAssigned(node)) fElementDeclaration = null;
                }
              }

              return true;
            }

            private boolean isAssigned(ASTNode current) {
              while (current != null && !(current instanceof Statement)) {
                if (current.getLocationInParent() == Assignment.LEFT_HAND_SIDE_PROPERTY)
                  return true;

                if (current instanceof PrefixExpression) return true;

                if (current instanceof PostfixExpression) return true;

                current = current.getParent();
              }

              return false;
            }

            @Override
            public boolean visit(ArrayAccess node) {
              if (fElementDeclaration != null) return super.visit(node);

              IBinding binding = getBinding(node.getArray());
              if (fArrayBinding.equals(binding)) {
                IBinding index = getBinding(node.getIndex());
                if (fIndexBinding.equals(index)) {
                  if (node.getLocationInParent()
                      == VariableDeclarationFragment.INITIALIZER_PROPERTY) {
                    fElementDeclaration = (VariableDeclarationFragment) node.getParent();
                  }
                }
              }
              return super.visit(node);
            }
          });
    } catch (InvalidBodyError e) {
      return false;
    }

    return true;
  }