/**
   * Updates the content of <code>cu</code>, modifying the type name and/or package declaration as
   * necessary.
   *
   * @return an AST rewrite or null if no rewrite needed
   */
  private TextEdit updateContent(ICompilationUnit cu, PackageFragment dest, String newName)
      throws JavaModelException {
    String[] currPackageName = ((PackageFragment) cu.getParent()).names;
    String[] destPackageName = dest.names;
    if (Util.equalArraysOrNull(currPackageName, destPackageName) && newName == null) {
      return null; // nothing to change
    } else {
      // ensure cu is consistent (noop if already consistent)
      cu.makeConsistent(this.progressMonitor);

      // GROOVY start
      // don't use the ASTParser if not a Java compilation unit
      if (LanguageSupportFactory.isInterestingSourceFile(cu.getElementName())) {
        // ZALUUM
        // old return updateNonJavaContent(cu, destPackageName, currPackageName, newName);
        return LanguageSupportFactory.updateContent(cu, destPackageName, currPackageName, newName);
        // END ZALUUM
      }
      // GROOVY end

      this.parser.setSource(cu);
      CompilationUnit astCU = (CompilationUnit) this.parser.createAST(this.progressMonitor);
      AST ast = astCU.getAST();
      ASTRewrite rewrite = ASTRewrite.create(ast);
      updateTypeName(cu, astCU, cu.getElementName(), newName, rewrite);
      updatePackageStatement(astCU, destPackageName, rewrite, cu);
      return rewrite.rewriteAST();
    }
  }
  /*
   * (non-Javadoc)
   *
   * @see org.eclipse.andmore.android.model.java.JavaClass#addComments()
   */
  @Override
  protected void addComments() throws AndroidException {
    ASTNode todoComment;

    ASTParser parser = ASTParser.newParser(AST.JLS3);
    parser.setSource(document.get().toCharArray());

    compUnit = (CompilationUnit) parser.createAST(null);
    ast = compUnit.getAST();
    rewrite = ASTRewrite.create(ast);

    todoComment =
        rewrite.createStringPlaceholder(
            CodeUtilsNLS.MODEL_Common_ToDoPutYourCodeHere, ASTNode.EMPTY_STATEMENT);

    TypeDeclaration receiverClass = (TypeDeclaration) compUnit.types().get(0);
    MethodDeclaration method;
    Block block;

    // Adds the Override annotation and ToDo comment to all overridden
    // methods
    for (int i = 0; i < receiverClass.bodyDeclarations().size(); i++) {
      method = (MethodDeclaration) receiverClass.bodyDeclarations().get(i);

      // Adds the Override annotation
      rewrite
          .getListRewrite(method, method.getModifiersProperty())
          .insertFirst(OVERRIDE_ANNOTATION, null);

      // Adds the ToDo comment
      block = method.getBody();
      rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY).insertFirst(todoComment, null);
    }

    try {
      // Writes the modifications
      TextEdit modifications = rewrite.rewriteAST(document, null);
      modifications.apply(document);
    } catch (IllegalArgumentException e) {
      String errMsg = NLS.bind(CodeUtilsNLS.EXC_JavaClass_ErrorApplyingCommentsToCode, className);

      AndmoreLogger.error(BroadcastReceiverClass.class, errMsg, e);
      throw new AndroidException(errMsg);
    } catch (MalformedTreeException e) {
      String errMsg = NLS.bind(CodeUtilsNLS.EXC_JavaClass_ErrorApplyingCommentsToCode, className);

      AndmoreLogger.error(BroadcastReceiverClass.class, errMsg, e);
      throw new AndroidException(errMsg);
    } catch (BadLocationException e) {
      String errMsg = NLS.bind(CodeUtilsNLS.EXC_JavaClass_ErrorApplyingCommentsToCode, className);

      AndmoreLogger.error(BroadcastReceiverClass.class, errMsg, e);
      throw new AndroidException(errMsg);
    }
  }
  private void createEdits(
      ICompilationUnit unit, ASTRewrite rewriter, List<TextEditGroup> descriptions)
      throws CoreException {
    TextChange change = fChangeManager.get(unit);
    MultiTextEdit root = new MultiTextEdit();
    change.setEdit(root);

    for (TextEditGroup group : descriptions) change.addTextEditGroup(group);

    root.addChild(rewriter.rewriteAST());
  }
  /**
   * Removes the current variable declaration from the AST and inserts it into the lowest possible
   * scope where the variable is first used. Returns the modification to the AST within a Change
   * object.
   */
  private Change recordASTModifications() {
    AST ast = compilationUnit.getAST();
    ASTRewrite rewriter = ASTRewrite.create(ast);

    // duplicate the original variable declaration in lower scope before getting rid of it
    VariableDeclarationStatement oldDeclaration =
        (VariableDeclarationStatement) variableVisitor.getDeclaration();

    assert variableVisitor.getFirstAssignment() instanceof Assignment;
    Assignment variableAssignment = (Assignment) variableVisitor.getFirstAssignment();
    ASTNode newScopeParent = variableAssignment.getParent().getParent();

    String codeString = oldDeclaration.toString();
    ASTNode newDeclaration =
        rewriter.createStringPlaceholder(
            codeString.substring(0, codeString.length() - 1),
            ASTNode.VARIABLE_DECLARATION_STATEMENT);

    ListRewrite listRewrite = rewriter.getListRewrite(newScopeParent, Block.STATEMENTS_PROPERTY);
    listRewrite.insertAt(newDeclaration, 0, null);

    // get rid of the higher scope declaration
    rewriter.remove(oldDeclaration, null);

    ICompilationUnit iCompUnit = method.getCompilationUnit();

    final String description = "ReduceScopeOfVariable";
    final String comment = "ReduceScopeOfVariable does blah...";

    // record the change
    CompilationUnitChange change =
        new CompilationUnitChange("Reduce scope of variable", iCompUnit) {
          public ChangeDescriptor getDescriptor() {
            Map<Object, Object> arguments = new HashMap<Object, Object>();
            arguments.put("method", method);
            arguments.put("var", varName);
            return new RefactoringChangeDescriptor(
                new ReduceScopeOfVariableDescriptor(
                    method.getJavaProject().getElementName(), description, comment, arguments));
          }
        };
    try {
      change.setEdit(rewriter.rewriteAST());
    } catch (Exception e) {
    }

    return change;
  }
 /**
  * Updates the content of <code>cu</code>, modifying the type name and/or package declaration as
  * necessary.
  *
  * @return an AST rewrite or null if no rewrite needed
  */
 private TextEdit updateContent(ICompilationUnit cu, PackageFragment dest, String newName)
     throws JavaModelException {
   String[] currPackageName = ((PackageFragment) cu.getParent()).names;
   String[] destPackageName = dest.names;
   if (Util.equalArraysOrNull(currPackageName, destPackageName) && newName == null) {
     return null; // nothing to change
   } else {
     // ensure cu is consistent (noop if already consistent)
     cu.makeConsistent(this.progressMonitor);
     this.parser.setSource(cu);
     CompilationUnit astCU = (CompilationUnit) this.parser.createAST(this.progressMonitor);
     AST ast = astCU.getAST();
     ASTRewrite rewrite = ASTRewrite.create(ast);
     updateTypeName(cu, astCU, cu.getElementName(), newName, rewrite);
     updatePackageStatement(astCU, destPackageName, rewrite, cu);
     return rewrite.rewriteAST();
   }
 }
 private static TextChange addTextEditFromRewrite(
     TextChangeManager manager, ICompilationUnit cu, ASTRewrite rewrite) throws CoreException {
   try {
     ITextFileBuffer buffer = RefactoringFileBuffers.acquire(cu);
     TextEdit resultingEdits =
         rewrite.rewriteAST(buffer.getDocument(), cu.getJavaProject().getOptions(true));
     TextChange textChange = manager.get(cu);
     if (textChange instanceof TextFileChange) {
       TextFileChange tfc = (TextFileChange) textChange;
       tfc.setSaveMode(TextFileChange.KEEP_SAVE_STATE);
     }
     String message = RefactoringCoreMessages.DeleteChangeCreator_1;
     TextChangeCompatibility.addTextEdit(textChange, message, resultingEdits);
     return textChange;
   } finally {
     RefactoringFileBuffers.release(cu);
   }
 }
Example #7
0
  /** 取得Quick Fix後改變的程式碼 */
  private Change getChange(CompilationUnit actRoot, ASTRewrite rewrite) {
    try {
      ICompilationUnit cu = (ICompilationUnit) actOpenable;
      Document document = new Document(cu.getBuffer().getContents());

      TextEdit edits = null;
      if (rewrite != null) edits = rewrite.rewriteAST(document, null);
      else edits = actRoot.rewrite(document, cu.getJavaProject().getOptions(true));

      TextFileChange textFileChange =
          new TextFileChange(cu.getElementName(), (IFile) cu.getResource());
      textFileChange.setEdit(edits);

      return textFileChange;
    } catch (JavaModelException e) {
      logger.error("[Apply Change Rethrow Unchecked Exception] EXCEPTION ", e);
    }
    return null;
  }
  /* non Java-doc
   * @see IRefactoring#createChange(IProgressMonitor)
   */
  @Override
  public Change createChange(IProgressMonitor pm) throws CoreException {
    final String NN = ""; // $NON-NLS-1$
    if (pm == null) pm = new NullProgressMonitor();
    pm.beginTask(NN, 2);
    try {
      final CompilationUnitChange result = new CompilationUnitChange(getName(), fCUnit);
      if (fLeaveDirty) result.setSaveMode(TextFileChange.LEAVE_DIRTY);
      MultiTextEdit root = new MultiTextEdit();
      result.setEdit(root);
      fRewriter = ASTRewrite.create(fAnalyzer.getEnclosingBodyDeclaration().getAST());
      fRewriter.setTargetSourceRangeComputer(
          new SelectionAwareSourceRangeComputer(
              fAnalyzer.getSelectedNodes(),
              fCUnit.getBuffer(),
              fSelection.getOffset(),
              fSelection.getLength()));
      fImportRewrite = StubUtility.createImportRewrite(fRootNode, true);

      fLinkedProposalModel = new LinkedProposalModel();

      fScope =
          CodeScopeBuilder.perform(fAnalyzer.getEnclosingBodyDeclaration(), fSelection)
              .findScope(fSelection.getOffset(), fSelection.getLength());
      fScope.setCursor(fSelection.getOffset());

      fSelectedNodes = fAnalyzer.getSelectedNodes();

      createTryCatchStatement(fCUnit.getBuffer(), fCUnit.findRecommendedLineSeparator());

      if (fImportRewrite.hasRecordedChanges()) {
        TextEdit edit = fImportRewrite.rewriteImports(null);
        root.addChild(edit);
        result.addTextEditGroup(new TextEditGroup(NN, new TextEdit[] {edit}));
      }
      TextEdit change = fRewriter.rewriteAST();
      root.addChild(change);
      result.addTextEditGroup(new TextEditGroup(NN, new TextEdit[] {change}));
      return result;
    } finally {
      pm.done();
    }
  }
 /**
  * Adds the specified tag to the source member defined by the member name and signature
  *
  * @param unit
  * @param membername
  * @param signature
  * @param tagname
  * @param remove
  * @throws CoreException
  * @throws MalformedTreeException
  * @throws BadLocationException
  */
 private void updateTagInSource(
     ICompilationUnit unit, String membername, String signature, String tagname, boolean remove)
     throws CoreException, MalformedTreeException, BadLocationException {
   ASTParser parser = ASTParser.newParser(AST.JLS4);
   parser.setSource(unit);
   CompilationUnit cunit = (CompilationUnit) parser.createAST(new NullProgressMonitor());
   assertNotNull("the ast compilation unit cannot be null", cunit);
   cunit.recordModifications();
   ASTRewrite rewrite = ASTRewrite.create(cunit.getAST());
   cunit.accept(new SourceChangeVisitor(membername, signature, tagname, remove, rewrite));
   ITextFileBufferManager bm = FileBuffers.getTextFileBufferManager();
   IPath path = cunit.getJavaElement().getPath();
   try {
     bm.connect(path, LocationKind.IFILE, null);
     ITextFileBuffer tfb = bm.getTextFileBuffer(path, LocationKind.IFILE);
     IDocument document = tfb.getDocument();
     TextEdit edits = rewrite.rewriteAST(document, null);
     edits.apply(document);
     tfb.commit(new NullProgressMonitor(), true);
   } finally {
     bm.disconnect(path, LocationKind.IFILE, null);
   }
 }
  public void testASTRewriteExample() throws Exception {
    // create a new project
    IProject project = ResourcesPlugin.getWorkspace().getRoot().getProject("Test");
    project.create(null);
    project.open(null);
    try {
      // set the Java nature and Java build path
      IProjectDescription description = project.getDescription();
      description.setNatureIds(new String[] {JavaCore.NATURE_ID});
      project.setDescription(description, null);

      IJavaProject javaProject = JavaCore.create(project);

      // build path is: project as source folder and JRE container
      IClasspathEntry[] cpentry =
          new IClasspathEntry[] {
            JavaCore.newSourceEntry(javaProject.getPath()),
            JavaRuntime.getDefaultJREContainerEntry()
          };
      javaProject.setRawClasspath(cpentry, javaProject.getPath(), null);
      Map<String, String> options = new HashMap<>();
      options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE);
      options.put(DefaultCodeFormatterConstants.FORMATTER_TAB_SIZE, "4");
      javaProject.setOptions(options);

      // create a test file
      IPackageFragmentRoot root = javaProject.getPackageFragmentRoot(project);
      IPackageFragment pack1 = root.createPackageFragment("test1", false, null);
      StringBuffer buf = new StringBuffer();
      buf.append("package test1;\n");
      buf.append("public class E {\n");
      buf.append("    public void foo(int i) {\n");
      buf.append("        while (--i > 0) {\n");
      buf.append("            System.beep();\n");
      buf.append("        }\n");
      buf.append("    }\n");
      buf.append("}\n");
      ICompilationUnit cu = pack1.createCompilationUnit("E.java", buf.toString(), false, null);

      // create an AST
      ASTParser parser = ASTParser.newParser(IASTSharedValues.SHARED_AST_LEVEL);
      parser.setSource(cu);
      parser.setResolveBindings(false);
      CompilationUnit astRoot = (CompilationUnit) parser.createAST(null);
      AST ast = astRoot.getAST();

      // create the descriptive ast rewriter
      ASTRewrite rewrite = ASTRewrite.create(ast);

      // get the block node that contains the statements in the method body
      TypeDeclaration typeDecl = (TypeDeclaration) astRoot.types().get(0);
      MethodDeclaration methodDecl = typeDecl.getMethods()[0];
      Block block = methodDecl.getBody();

      // create new statements to insert
      MethodInvocation newInv1 = ast.newMethodInvocation();
      newInv1.setName(ast.newSimpleName("bar1"));
      Statement newStatement1 = ast.newExpressionStatement(newInv1);

      MethodInvocation newInv2 = ast.newMethodInvocation();
      newInv2.setName(ast.newSimpleName("bar2"));
      Statement newStatement2 = ast.newExpressionStatement(newInv2);

      // describe that the first node is inserted as first statement in block, the other one as last
      // statement
      // note: AST is not modified by this
      ListRewrite listRewrite = rewrite.getListRewrite(block, Block.STATEMENTS_PROPERTY);
      listRewrite.insertFirst(newStatement1, null);
      listRewrite.insertLast(newStatement2, null);

      // evaluate the text edits corresponding to the described changes. AST and CU still
      // unmodified.
      TextEdit res = rewrite.rewriteAST();

      // apply the text edits to the compilation unit
      Document document = new Document(cu.getSource());
      res.apply(document);
      cu.getBuffer().setContents(document.get());

      // test result
      String preview = cu.getSource();

      buf = new StringBuffer();
      buf.append("package test1;\n");
      buf.append("public class E {\n");
      buf.append("    public void foo(int i) {\n");
      buf.append("        bar1();\n");
      buf.append("        while (--i > 0) {\n");
      buf.append("            System.beep();\n");
      buf.append("        }\n");
      buf.append("        bar2();\n");
      buf.append("    }\n");
      buf.append("}\n");
      assertEquals(preview, buf.toString());
    } finally {
      project.delete(true, null);
    }
  }
  /**
   * Copies/moves a package fragment with the name <code>newName</code> to the destination package.
   * <br>
   *
   * @exception JavaModelException if the operation is unable to complete
   */
  private void processPackageFragmentResource(
      PackageFragment source, PackageFragmentRoot root, String newName) throws JavaModelException {
    try {
      String[] newFragName = (newName == null) ? source.names : Util.getTrimmedSimpleNames(newName);
      PackageFragment newFrag = root.getPackageFragment(newFragName);
      IResource[] resources = collectResourcesOfInterest(source);

      // if isMove() can we move the folder itself ? (see
      // http://bugs.eclipse.org/bugs/show_bug.cgi?id=22458)
      boolean shouldMoveFolder =
          isMove() && !newFrag.resource().exists(); // if new pkg fragment exists, it is an override
      IFolder srcFolder = (IFolder) source.resource();
      IPath destPath = newFrag.getPath();
      if (shouldMoveFolder) {
        // check if destination is not included in source
        if (srcFolder.getFullPath().isPrefixOf(destPath)) {
          shouldMoveFolder = false;
        } else {
          // check if there are no sub-packages
          IResource[] members = srcFolder.members();
          for (int i = 0; i < members.length; i++) {
            if (members[i] instanceof IFolder) {
              shouldMoveFolder = false;
              break;
            }
          }
        }
      }
      boolean containsReadOnlySubPackageFragments =
          createNeededPackageFragments(
              (IContainer) source.parent.resource(), root, newFragName, shouldMoveFolder);
      boolean sourceIsReadOnly = Util.isReadOnly(srcFolder);

      // Process resources
      if (shouldMoveFolder) {
        // move underlying resource
        // TODO Revisit once bug 43044 is fixed
        if (sourceIsReadOnly) {
          Util.setReadOnly(srcFolder, false);
        }
        srcFolder.move(destPath, this.force, true /* keep history */, getSubProgressMonitor(1));
        if (sourceIsReadOnly) {
          Util.setReadOnly(srcFolder, true);
        }
        setAttribute(HAS_MODIFIED_RESOURCE_ATTR, TRUE);
      } else {
        // process the leaf resources
        if (resources.length > 0) {
          if (isRename()) {
            if (!destPath.equals(source.getPath())) {
              moveResources(resources, destPath);
            }
          } else if (isMove()) {
            // we need to delete this resource if this operation wants to override existing
            // resources
            for (int i = 0, max = resources.length; i < max; i++) {
              IResource destinationResource =
                  ResourcesPlugin.getWorkspace()
                      .getRoot()
                      .findMember(destPath.append(resources[i].getName()));
              if (destinationResource != null) {
                if (this.force) {
                  deleteResource(destinationResource, IResource.KEEP_HISTORY);
                } else {
                  throw new JavaModelException(
                      new JavaModelStatus(
                          IJavaModelStatusConstants.NAME_COLLISION,
                          Messages.bind(
                              Messages.status_nameCollision,
                              destinationResource.getFullPath().toString())));
                }
              }
            }
            moveResources(resources, destPath);
          } else {
            // we need to delete this resource if this operation wants to override existing
            // resources
            for (int i = 0, max = resources.length; i < max; i++) {
              IResource destinationResource =
                  ResourcesPlugin.getWorkspace()
                      .getRoot()
                      .findMember(destPath.append(resources[i].getName()));
              if (destinationResource != null) {
                if (this.force) {
                  // we need to delete this resource if this operation wants to override existing
                  // resources
                  deleteResource(destinationResource, IResource.KEEP_HISTORY);
                } else {
                  throw new JavaModelException(
                      new JavaModelStatus(
                          IJavaModelStatusConstants.NAME_COLLISION,
                          Messages.bind(
                              Messages.status_nameCollision,
                              destinationResource.getFullPath().toString())));
                }
              }
            }
            copyResources(resources, destPath);
          }
        }
      }

      // Update package statement in compilation unit if needed
      if (!Util.equalArraysOrNull(
          newFragName, source.names)) { // if package has been renamed, update the compilation units
        char[][] inclusionPatterns = root.fullInclusionPatternChars();
        char[][] exclusionPatterns = root.fullExclusionPatternChars();
        for (int i = 0; i < resources.length; i++) {
          String resourceName = resources[i].getName();
          if (Util.isJavaLikeFileName(resourceName)) {
            // we only consider potential compilation units
            ICompilationUnit cu = newFrag.getCompilationUnit(resourceName);
            if (Util.isExcluded(
                cu.getPath(), inclusionPatterns, exclusionPatterns, false /*not a folder*/))
              continue;
            this.parser.setSource(cu);
            CompilationUnit astCU = (CompilationUnit) this.parser.createAST(this.progressMonitor);
            AST ast = astCU.getAST();
            ASTRewrite rewrite = ASTRewrite.create(ast);
            updatePackageStatement(astCU, newFragName, rewrite, cu);
            TextEdit edits = rewrite.rewriteAST();
            applyTextEdit(cu, edits);
            cu.save(null, false);
          }
        }
      }

      // Discard empty old package (if still empty after the rename)
      boolean isEmpty = true;
      if (isMove()) {
        // delete remaining files in this package (.class file in the case where Proj=src=bin)
        // in case of a copy
        updateReadOnlyPackageFragmentsForMove(
            (IContainer) source.parent.resource(), root, newFragName, sourceIsReadOnly);
        if (srcFolder.exists()) {
          IResource[] remaining = srcFolder.members();
          for (int i = 0, length = remaining.length; i < length; i++) {
            IResource file = remaining[i];
            if (file instanceof IFile) {
              if (Util.isReadOnly(file)) {
                Util.setReadOnly(file, false);
              }
              deleteResource(file, IResource.FORCE | IResource.KEEP_HISTORY);
            } else {
              isEmpty = false;
            }
          }
        }
        if (isEmpty) {
          IResource rootResource;
          // check if source is included in destination
          if (destPath.isPrefixOf(srcFolder.getFullPath())) {
            rootResource = newFrag.resource();
          } else {
            rootResource = source.parent.resource();
          }

          // delete recursively empty folders
          deleteEmptyPackageFragment(source, false, rootResource);
        }
      } else if (containsReadOnlySubPackageFragments) {
        // in case of a copy
        updateReadOnlyPackageFragmentsForCopy(
            (IContainer) source.parent.resource(), root, newFragName);
      }
      // workaround for bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=24505
      if (isEmpty && isMove() && !(Util.isExcluded(source) || Util.isExcluded(newFrag))) {
        IJavaProject sourceProject = source.getJavaProject();
        getDeltaFor(sourceProject).movedFrom(source, newFrag);
        IJavaProject destProject = newFrag.getJavaProject();
        getDeltaFor(destProject).movedTo(newFrag, source);
      }
    } catch (JavaModelException e) {
      throw e;
    } catch (CoreException ce) {
      throw new JavaModelException(ce);
    }
  }
 public TextEdit rewriteAST() throws CoreException, IllegalArgumentException {
   return _rewrite.rewriteAST();
 }