/** * 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); } }
/** 取得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(); }