예제 #1
0
  /**
   * Inserts the provided {@code statement} after the the node this inserter was created for. Tries
   * to put the {@code statement} as close to the {@code marker} as possible.
   *
   * @param statement The statement to insert after the insertion node.
   */
  void insertAfter(final Statement statement) {
    Validate.notNull(statement);
    Validate.validState(
        this.insertionList != null,
        "Insertion is only possible after the inserter has been set up.");
    Validate.validState(
        this.insertionList.isPresent(),
        "Insertion is only possible if setting up the inserter succeeded.");

    if (this.differentAfterList) {
      this.afterList.add(0, statement);
    } else if (this.breakDetector.containsControlFlowBreakingStatement(this.markedStatement)) {
      // we are trying to insert after a control flow breaking statement. That’s
      // dangerous, better surround with try…finally

      final AST factory = this.markedStatement.getAST();
      final TryStatement tryStatement = factory.newTryStatement();
      tryStatement.setFinally(factory.newBlock());

      @SuppressWarnings("unchecked")
      final List<Statement> tryBodyStatements = tryStatement.getBody().statements();
      @SuppressWarnings("unchecked")
      final List<Statement> finallyStatements = tryStatement.getFinally().statements();
      final Statement copy = (Statement) ASTNode.copySubtree(factory, this.markedStatement);
      tryBodyStatements.add(copy);
      finallyStatements.add(statement);
      this.insertionList.get().set(this.markerIndex, tryStatement);
      this.markedStatement = tryStatement;
      this.differentAfterList = true;
      this.afterList = finallyStatements;
    } else {
      this.insertionList.get().add(this.markerIndex, statement);
    }
  }
예제 #2
0
 @SuppressWarnings("unchecked")
 public TryStatement newTryCatch(Block tryBlock, CatchClause... clauses) {
   TryStatement tryStmt = ast.newTryStatement();
   tryStmt.setBody(tryBlock);
   tryStmt.catchClauses().addAll(Arrays.asList(clauses));
   return tryStmt;
 }
 @Override
 public boolean visit(TryStatement node) {
   final List<Statement> tryStmts = asList(node.getBody());
   if (tryStmts.isEmpty()) {
     final List<Statement> finallyStmts = asList(node.getFinally());
     if (!finallyStmts.isEmpty()) {
       final ASTBuilder b = this.ctx.getASTBuilder();
       this.ctx.getRefactorings().replace(node, b.copy(node.getFinally()));
       return DO_NOT_VISIT_SUBTREE;
     } else if (node.resources().isEmpty()) {
       this.ctx.getRefactorings().remove(node);
       return DO_NOT_VISIT_SUBTREE;
     }
   }
   // }else {
   // for (CatchClause catchClause : (List<CatchClause>) node.catchClauses()) {
   // final List<Statement> finallyStmts = asList(catchClause.getBody());
   // if (finallyStmts.isEmpty()) {
   // // TODO cannot remove without checking what subsequent catch clauses are
   // catching
   // this.ctx.getRefactorings().remove(catchClause);
   // }
   // }
   //
   // final List<Statement> finallyStmts = asList(node.getFinally());
   // if (finallyStmts.isEmpty()) {
   // this.ctx.getRefactorings().remove(node.getFinally());
   // }
   // // TODO If all finally and catch clauses have been removed,
   // // then we can remove the whole try statement and replace it with a simple block
   // return DO_NOT_VISIT_SUBTREE; // TODO JNR is this correct?
   // }
   return VISIT_SUBTREE;
 }
 /*
  * @see ASTVisitor#visit(TryStatement)
  */
 public boolean visit(TryStatement node) {
   this.fBuffer.append("try "); // $NON-NLS-1$
   node.getBody().accept(this);
   this.fBuffer.append(" "); // $NON-NLS-1$
   for (Iterator it = node.catchClauses().iterator(); it.hasNext(); ) {
     CatchClause cc = (CatchClause) it.next();
     cc.accept(this);
   }
   if (node.getFinally() != null) {
     this.fBuffer.append("finally "); // $NON-NLS-1$
     node.getFinally().accept(this);
   }
   return false;
 }
 /*
  * @see ASTVisitor#visit(TryStatement)
  */
 @Override
 public boolean visit(TryStatement node) {
   this.fBuffer.append("try "); // $NON-NLS-1$
   if (node.getAST().apiLevel() >= JLS4) {
     if (!node.resources().isEmpty()) {
       this.fBuffer.append("("); // $NON-NLS-1$
       for (Iterator<VariableDeclarationExpression> it = node.resources().iterator();
           it.hasNext(); ) {
         VariableDeclarationExpression var = it.next();
         var.accept(this);
         if (it.hasNext()) {
           this.fBuffer.append(","); // $NON-NLS-1$
         }
       }
       this.fBuffer.append(") "); // $NON-NLS-1$
     }
   }
   node.getBody().accept(this);
   this.fBuffer.append(" "); // $NON-NLS-1$
   for (Iterator<CatchClause> it = node.catchClauses().iterator(); it.hasNext(); ) {
     CatchClause cc = it.next();
     cc.accept(this);
   }
   if (node.getFinally() != null) {
     this.fBuffer.append("finally "); // $NON-NLS-1$
     node.getFinally().accept(this);
   }
   return false;
 }
  @Override
  public void indexTryCatchBlock(
      final Document document, final TryStatement tryStatement, final CatchClause catchClause) {

    final ASTVisitor visitor =
        new MethodCallVisitor() {
          @Override
          protected void handleMethodCall(final IMethodBinding methodBinding) {
            final Optional<String> opt = BindingHelper.getIdentifier(methodBinding);
            if (opt.isPresent()) {
              CodeIndexer.addFieldToDocument(document, Fields.USED_METHODS_IN_FINALLY, opt.get());
            }
          };
        };

    if (tryStatement.getFinally() != null) {
      tryStatement.getFinally().accept(visitor);
    }
  }
예제 #7
0
  @Test
  public void testIsThrowStatementInCatchClause() {
    TryStatement tryStatement;
    CatchClause catchStatement;

    // 測試 符合的例子 是否會抓出
    MethodDeclaration md = null;
    md = ASTNodeFinder.getMethodDeclarationNodeByName(compilationUnit, "false_throwAndPrint");
    tryStatement = (TryStatement) md.getBody().statements().get(0);
    catchStatement = (CatchClause) tryStatement.catchClauses().get(0);
    assertTrue(dummyHandlerVisitor.isThrowStatementInCatchClause(catchStatement));

    // 測試 不符合例子 是否會抓出
    md =
        ASTNodeFinder.getMethodDeclarationNodeByName(
            compilationUnit, "true_DummyHandlerTryNestedTry");
    tryStatement = (TryStatement) md.getBody().statements().get(1);
    catchStatement = (CatchClause) tryStatement.catchClauses().get(0);
    assertFalse(dummyHandlerVisitor.isThrowStatementInCatchClause(catchStatement));
  }
 @Override
 public boolean visit(EmptyStatement node) {
   ASTNode parent = node.getParent();
   if (parent instanceof Block) {
     this.ctx.getRefactorings().remove(node);
     return DO_NOT_VISIT_SUBTREE;
   }
   parent = getParentIgnoring(node, Block.class);
   if (parent instanceof IfStatement) {
     IfStatement is = (IfStatement) parent;
     List<Statement> thenStmts = asList(is.getThenStatement());
     List<Statement> elseStmts = asList(is.getElseStatement());
     boolean thenIsEmptyStmt = thenStmts.size() == 1 && is(thenStmts.get(0), EmptyStatement.class);
     boolean elseIsEmptyStmt = elseStmts.size() == 1 && is(elseStmts.get(0), EmptyStatement.class);
     if (thenIsEmptyStmt && elseIsEmptyStmt) {
       this.ctx.getRefactorings().remove(parent);
       return DO_NOT_VISIT_SUBTREE;
     } else if (thenIsEmptyStmt && is.getElseStatement() == null) {
       this.ctx.getRefactorings().remove(is);
       return DO_NOT_VISIT_SUBTREE;
     } else if (elseIsEmptyStmt) {
       this.ctx.getRefactorings().remove(is.getElseStatement());
       return DO_NOT_VISIT_SUBTREE;
     }
   } else if (parent instanceof TryStatement) {
     TryStatement ts = (TryStatement) parent;
     return removeEmptyStmtBody(node, ts, ts.getBody());
   } else if (parent instanceof EnhancedForStatement) {
     EnhancedForStatement efs = (EnhancedForStatement) parent;
     return removeEmptyStmtBody(node, efs, efs.getBody());
   } else if (parent instanceof ForStatement) {
     ForStatement fs = (ForStatement) parent;
     return removeEmptyStmtBody(node, fs, fs.getBody());
   } else if (parent instanceof WhileStatement) {
     WhileStatement ws = (WhileStatement) parent;
     return removeEmptyStmtBody(node, ws, ws.getBody());
   }
   return VISIT_SUBTREE;
 }
예제 #9
0
 /* (omit javadoc for this method)
  * Method declared on ASTNode.
  */
 ASTNode clone0(AST target) {
   TryStatement result = new TryStatement(target);
   result.setSourceRange(this.getStartPosition(), this.getLength());
   result.copyLeadingComment(this);
   result.setBody((Block) getBody().clone(target));
   result.catchClauses().addAll(ASTNode.copySubtrees(target, catchClauses()));
   result.setFinally((Block) ASTNode.copySubtree(target, getFinally()));
   return result;
 }
예제 #10
0
 /**
  * Builds a new {@link TryStatement} instance.
  *
  * @param body the try body
  * @param catchClauses the catch clauses for the try
  * @return a new try statement
  */
 public TryStatement try0(final Block body, CatchClause... catchClauses) {
   final TryStatement tryS = ast.newTryStatement();
   tryS.setBody(body);
   addAll(catchClauses(tryS), catchClauses);
   return tryS;
 }
  private void createTryCatchStatement(org.eclipse.jdt.core.IBuffer buffer, String lineDelimiter)
      throws CoreException {
    List<Statement> result = new ArrayList<>(1);
    TryStatement tryStatement = getAST().newTryStatement();
    ITypeBinding[] exceptions = fAnalyzer.getExceptions();
    ImportRewriteContext context =
        new ContextSensitiveImportRewriteContext(
            fAnalyzer.getEnclosingBodyDeclaration(), fImportRewrite);

    if (!fIsMultiCatch) {
      for (int i = 0; i < exceptions.length; i++) {
        ITypeBinding exception = exceptions[i];
        CatchClause catchClause = getAST().newCatchClause();
        tryStatement.catchClauses().add(catchClause);
        SingleVariableDeclaration decl = getAST().newSingleVariableDeclaration();
        String varName = StubUtility.getExceptionVariableName(fCUnit.getJavaProject());

        String name = fScope.createName(varName, false);
        decl.setName(getAST().newSimpleName(name));
        Type type = fImportRewrite.addImport(exception, getAST(), context);
        decl.setType(type);
        catchClause.setException(decl);
        Statement st = getCatchBody(ASTNodes.getQualifiedTypeName(type), name, lineDelimiter);
        if (st != null) {
          catchClause.getBody().statements().add(st);
        }
        fLinkedProposalModel
            .getPositionGroup(GROUP_EXC_TYPE + i, true)
            .addPosition(fRewriter.track(decl.getType()), i == 0);
        fLinkedProposalModel
            .getPositionGroup(GROUP_EXC_NAME + i, true)
            .addPosition(fRewriter.track(decl.getName()), false);
      }
    } else {
      List<ITypeBinding> filteredExceptions = filterSubtypeExceptions(exceptions);
      CatchClause catchClause = getAST().newCatchClause();
      SingleVariableDeclaration decl = getAST().newSingleVariableDeclaration();
      String varName = StubUtility.getExceptionVariableName(fCUnit.getJavaProject());
      String name = fScope.createName(varName, false);
      decl.setName(getAST().newSimpleName(name));

      UnionType unionType = getAST().newUnionType();
      List<Type> types = unionType.types();
      int i = 0;
      for (ITypeBinding exception : filteredExceptions) {
        Type type = fImportRewrite.addImport(exception, getAST(), context);
        types.add(type);
        fLinkedProposalModel
            .getPositionGroup(GROUP_EXC_TYPE + i, true)
            .addPosition(fRewriter.track(type), i == 0);
        i++;
      }

      decl.setType(unionType);
      catchClause.setException(decl);
      fLinkedProposalModel
          .getPositionGroup(GROUP_EXC_NAME + 0, true)
          .addPosition(fRewriter.track(decl.getName()), false);
      Statement st = getCatchBody("Exception", name, lineDelimiter); // $NON-NLS-1$
      if (st != null) {
        catchClause.getBody().statements().add(st);
      }
      tryStatement.catchClauses().add(catchClause);
    }
    List<ASTNode> variableDeclarations = getSpecialVariableDeclarationStatements();
    ListRewrite statements =
        fRewriter.getListRewrite(tryStatement.getBody(), Block.STATEMENTS_PROPERTY);
    boolean selectedNodeRemoved = false;
    ASTNode expressionStatement = null;
    for (int i = 0; i < fSelectedNodes.length; i++) {
      ASTNode node = fSelectedNodes[i];
      if (node instanceof VariableDeclarationStatement && variableDeclarations.contains(node)) {
        AST ast = getAST();
        VariableDeclarationStatement statement = (VariableDeclarationStatement) node;
        // Create a copy and remove the initializer
        VariableDeclarationStatement copy =
            (VariableDeclarationStatement) ASTNode.copySubtree(ast, statement);
        List<IExtendedModifier> modifiers = copy.modifiers();
        for (Iterator<IExtendedModifier> iter = modifiers.iterator(); iter.hasNext(); ) {
          IExtendedModifier modifier = iter.next();
          if (modifier.isModifier()
              && Modifier.isFinal(((Modifier) modifier).getKeyword().toFlagValue())) {
            iter.remove();
          }
        }
        List<VariableDeclarationFragment> fragments = copy.fragments();
        for (Iterator<VariableDeclarationFragment> iter = fragments.iterator(); iter.hasNext(); ) {
          VariableDeclarationFragment fragment = iter.next();
          fragment.setInitializer(null);
        }
        CompilationUnit root = (CompilationUnit) statement.getRoot();
        int extendedStart = root.getExtendedStartPosition(statement);
        // we have a leading comment and the comment is covered by the selection
        if (extendedStart != statement.getStartPosition()
            && extendedStart >= fSelection.getOffset()) {
          String commentToken =
              buffer.getText(extendedStart, statement.getStartPosition() - extendedStart);
          commentToken = Strings.trimTrailingTabsAndSpaces(commentToken);
          Type type = statement.getType();
          String typeName = buffer.getText(type.getStartPosition(), type.getLength());
          copy.setType(
              (Type)
                  fRewriter.createStringPlaceholder(commentToken + typeName, type.getNodeType()));
        }
        result.add(copy);
        // convert the fragments into expression statements
        fragments = statement.fragments();
        if (!fragments.isEmpty()) {
          List<ExpressionStatement> newExpressionStatements = new ArrayList<>();
          for (Iterator<VariableDeclarationFragment> iter = fragments.iterator();
              iter.hasNext(); ) {
            VariableDeclarationFragment fragment = iter.next();
            Expression initializer = fragment.getInitializer();
            if (initializer != null) {
              Assignment assignment = ast.newAssignment();
              assignment.setLeftHandSide(
                  (Expression) fRewriter.createCopyTarget(fragment.getName()));
              assignment.setRightHandSide((Expression) fRewriter.createCopyTarget(initializer));
              newExpressionStatements.add(ast.newExpressionStatement(assignment));
            }
          }
          if (!newExpressionStatements.isEmpty()) {
            if (fSelectedNodes.length == 1) {
              expressionStatement =
                  fRewriter.createGroupNode(
                      newExpressionStatements.toArray(new ASTNode[newExpressionStatements.size()]));
            } else {
              fRewriter.replace(
                  statement,
                  fRewriter.createGroupNode(
                      newExpressionStatements.toArray(new ASTNode[newExpressionStatements.size()])),
                  null);
            }
          } else {
            fRewriter.remove(statement, null);
            selectedNodeRemoved = true;
          }
        } else {
          fRewriter.remove(statement, null);
          selectedNodeRemoved = true;
        }
      }
    }
    result.add(tryStatement);
    ASTNode replacementNode;
    if (result.size() == 1) {
      replacementNode = result.get(0);
    } else {
      replacementNode = fRewriter.createGroupNode(result.toArray(new ASTNode[result.size()]));
    }
    if (fSelectedNodes.length == 1) {
      ASTNode selectedNode = fSelectedNodes[0];

      if (selectedNode instanceof MethodReference) {
        MethodReference methodReference = (MethodReference) selectedNode;
        IMethodBinding functionalMethod =
            QuickAssistProcessor.getFunctionalMethodForMethodReference(methodReference);
        // functionalMethod is non-null and non-generic. See
        // ExceptionAnalyzer.handleMethodReference(MethodReference node).
        Assert.isTrue(functionalMethod != null && !functionalMethod.isGenericMethod());
        LambdaExpression lambda =
            QuickAssistProcessor.convertMethodRefernceToLambda(
                methodReference, functionalMethod, fRootNode, fRewriter, null, true);
        ASTNode statementInBlock = (ASTNode) ((Block) lambda.getBody()).statements().get(0);
        fRewriter.replace(statementInBlock, replacementNode, null);
        statements.insertLast(statementInBlock, null);
        return;
      }

      LambdaExpression enclosingLambda = ASTResolving.findEnclosingLambdaExpression(selectedNode);
      if (enclosingLambda != null
          && selectedNode.getLocationInParent() == LambdaExpression.BODY_PROPERTY
          && enclosingLambda.resolveMethodBinding() != null) {
        QuickAssistProcessor.changeLambdaBodyToBlock(enclosingLambda, getAST(), fRewriter);
        Block blockBody = (Block) fRewriter.get(enclosingLambda, LambdaExpression.BODY_PROPERTY);
        ASTNode statementInBlock = (ASTNode) blockBody.statements().get(0);
        fRewriter.replace(statementInBlock, replacementNode, null);
        statements.insertLast(statementInBlock, null);
        return;
      }

      if (expressionStatement != null) {
        statements.insertLast(expressionStatement, null);
      } else {
        if (!selectedNodeRemoved)
          statements.insertLast(fRewriter.createMoveTarget(selectedNode), null);
      }
      fRewriter.replace(selectedNode, replacementNode, null);
    } else {
      ListRewrite source =
          fRewriter.getListRewrite(
              fSelectedNodes[0].getParent(),
              (ChildListPropertyDescriptor) fSelectedNodes[0].getLocationInParent());
      ASTNode toMove =
          source.createMoveTarget(
              fSelectedNodes[0], fSelectedNodes[fSelectedNodes.length - 1], replacementNode, null);
      statements.insertLast(toMove, null);
    }
  }