private boolean rangeAdded(TextEdit edit) { unchangedUntil(edit.getOffset()); buf.append("<b>"); // $NON-NLS-1$ appendContent(previewContent, edit.getOffset(), edit.getExclusiveEnd(), buf, false); buf.append("</b>"); // $NON-NLS-1$ fWrittenToPos = edit.getExclusiveEnd(); return false; }
private void handleReplace(IASTNode node) { List<ASTModification> modifications = getModifications(node, ModificationKind.REPLACE); String source = node.getTranslationUnit().getRawSignature(); TextEdit edit; ChangeGeneratorWriterVisitor writer = new ChangeGeneratorWriterVisitor(modificationStore, commentMap); IASTFileLocation fileLocation = node.getFileLocation(); Integer val = sourceOffsets.get(fileLocation.getFileName()); int processedOffset = val != null ? val.intValue() : 0; if (modifications.size() == 1 && modifications.get(0).getNewNode() == null) { int offset = getOffsetIncludingComments(node); int endOffset = getEndOffsetIncludingComments(node); offset = Math.max(skipPrecedingBlankLines(source, offset), processedOffset); endOffset = skipTrailingBlankLines(source, endOffset); IASTNode[] siblingsList = getContainingNodeList(node); if (siblingsList != null) { if (siblingsList.length > 1) { if (node == siblingsList[0]) { endOffset = skipToTrailingDelimiter(source, ',', endOffset); } else { offset = skipToPrecedingDelimiter(source, ',', offset); } } else if (node.getPropertyInParent() == ICPPASTFunctionDefinition.MEMBER_INITIALIZER) { offset = skipToPrecedingDelimiter(source, ':', offset); } } IASTNode prevNode = getPreviousSiblingOrPreprocessorNode(node); IASTNode nextNode = getNextSiblingOrPreprocessorNode(node); if (prevNode != null && nextNode != null) { if (ASTWriter.requireBlankLineInBetween(prevNode, nextNode)) { writer.newLine(); } } else if (node.getParent() instanceof ICPPASTNamespaceDefinition) { writer.newLine(); } String code = writer.toString(); edit = new ReplaceEdit(offset, endOffset - offset, code); } else { node.accept(writer); String code = writer.toString(); int offset = fileLocation.getNodeOffset(); int endOffset = offset + fileLocation.getNodeLength(); if (node instanceof IASTStatement || node instanceof IASTDeclaration) { // Include trailing comments in the area to be replaced. endOffset = Math.max(endOffset, getEndOffsetIncludingTrailingComments(node)); } String lineSeparator = writer.getScribe().getLineSeparator(); if (code.endsWith(lineSeparator)) { code = code.substring(0, code.length() - lineSeparator.length()); } edit = new ReplaceEdit(offset, endOffset - offset, code); } IFile file = FileHelper.getFileFromNode(node); MultiTextEdit parentEdit = getEdit(node, file); parentEdit.addChild(edit); sourceOffsets.put(fileLocation.getFileName(), edit.getExclusiveEnd()); }
private void formatAndAssertEquals( String beforePath, String afterPath, XMLFormattingPreferences prefs) throws UnsupportedEncodingException, IOException, CoreException { IStructuredModel beforeModel = null, afterModel = null; try { beforeModel = getModelForEdit(beforePath); assertNotNull("could not retrieve structured model for : " + beforePath, beforeModel); afterModel = getModelForEdit(afterPath); assertNotNull("could not retrieve structured model for : " + afterPath, afterModel); IStructuredDocument document = beforeModel.getStructuredDocument(); String normalizedContents = document.get(); normalizedContents = StringUtils.replace(normalizedContents, "\r\n", "\n"); normalizedContents = StringUtils.replace(normalizedContents, "\r", "\n"); document.set(normalizedContents); if (prefs == null) prefs = new XMLFormattingPreferences(); TextEdit edit = partitionFormatter.format(beforeModel, 0, document.getLength(), prefs); try { edit.apply(document); } catch (MalformedTreeException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (BadLocationException e) { // TODO Auto-generated catch block e.printStackTrace(); } ByteArrayOutputStream formattedBytes = new ByteArrayOutputStream(); beforeModel.save(formattedBytes); // "beforeModel" should now be // after the formatter ByteArrayOutputStream afterBytes = new ByteArrayOutputStream(); afterModel.save(afterBytes); String expectedContents = new String(afterBytes.toByteArray(), UTF_8); String actualContents = new String(formattedBytes.toByteArray(), UTF_8); /* Make some adjustments to ignore cross platform line delimiter issues */ expectedContents = StringUtils.replace(expectedContents, "\r\n", "\n"); expectedContents = StringUtils.replace(expectedContents, "\r", "\n"); actualContents = StringUtils.replace(actualContents, "\r\n", "\n"); actualContents = StringUtils.replace(actualContents, "\r", "\n"); assertTrue( "Formatted document differs from the expected.\nExpected Contents:\n" + expectedContents + "\nActual Contents:\n" + actualContents, fStringCompareUtil.equalsIgnoreLineSeperator(expectedContents, actualContents)); } finally { if (beforeModel != null) beforeModel.releaseFromEdit(); if (afterModel != null) afterModel.releaseFromEdit(); } }
/* * (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); } }
/** Return this {@link JavaSource} file as a String */ @Override public String toString() { Document document = new Document(this.document.get()); try { TextEdit edit = unit.rewrite(document, null); edit.apply(document); } catch (Exception e) { throw new ParserException("Could not modify source: " + unit.toString(), e); } return Formatter.format(document.get()); }
/** * It is OK to apply more than one insert {@link Edit} with the same offset. * * <p>For example Quick Fix "Implement Missing Overrides" inserts several method declarations. */ public void test_toLTK_SourceChange_twoInserts() throws Exception { Source source = createTestFileSource(); // fill SourceChange SourceChange sourceChange = new SourceChange("My change", source); sourceChange.addEdit(new Edit(2, 0, "a")); sourceChange.addEdit(new Edit(2, 0, "b")); // toLTK TextFileChange ltkChange = ServiceUtils.toLTK(sourceChange); TextEdit textEdit = ltkChange.getEdit(); // apply Document document = new Document("01234"); textEdit.apply(document); assertEquals("01ab234", document.get()); }
public String format(String text, int startOffset, int endOffset, int kJavascriptUnit) throws FileDoesNotExistsException { IDocument doc = new Document(); try { // format the file (the meat and potatoes) doc.set(text); /** * Format <code>source</code>, and returns a text edit that correspond to the difference * between the given string and the formatted string. * * <p>It returns null if the given string cannot be formatted. * * <p>If the offset position is matching a whitespace, the result can include whitespaces. It * would be up to the caller to get rid of preceeding whitespaces. * * @param kind Use to specify the kind of the code snippet to format. It can be any of these: * K_EXPRESSION, K_STATEMENTS, K_CLASS_BODY_DECLARATIONS, K_JAVASCRIPT_UNIT, K_UNKNOWN, * K_SINGLE_LINE_COMMENT, K_MULTI_LINE_COMMENT, K_JAVA_DOC * @param source the source to format * @param offset the given offset to start recording the edits (inclusive). * @param length the given length to stop recording the edits (exclusive). * @param indentationLevel the initial indentation level, used to shift left/right the entire * source fragment. An initial indentation level of zero or below has no effect. * @param lineSeparator the line separator to use in formatted source, if set to <code>null * </code>, then the platform default one will be used. * @return the text edit * @throws IllegalArgumentException if offset is lower than 0, length is lower than 0 or * length is greater than source length. */ TextEdit edit = getCodeFormatter() .format( kJavascriptUnit, text, startOffset, endOffset - startOffset, 0, Settings.LINE_SEPARATOR); if (edit != null) { edit.apply(doc); } else { throw new FormattingFailedException(); } return doc.get(); } catch (BadLocationException e) { throw new RuntimeException(e); } }
public String format(final String input) throws BadLocationException { final IDocument doc = new Document(); doc.set(input); final TextEdit edit = formatter.format( CodeFormatter.K_COMPILATION_UNIT | CodeFormatter.F_INCLUDE_COMMENTS, input, 0, input.length(), 0, "\n"); if (edit == null) throw new RuntimeException("formatting failed"); edit.apply(doc); return doc.get(); }
public String format(String source) { TextEdit edit = codeFormatter.format(0, source, 0, source.length(), 0, null); IDocument document = new Document(source); String formattedSource; try { edit.apply(document); formattedSource = document.get(); } catch (MalformedTreeException e) { formattedSource = source; } catch (BadLocationException e) { formattedSource = source; } return formattedSource; }
protected void applyTextEdit(CompilationUnit cu, TextEdit edits) throws DartModelException { try { edits.apply(getDocument(cu)); } catch (BadLocationException e) { // content changed under us throw new DartModelException(e, DartModelStatusConstants.INVALID_CONTENTS); } }
@Test public void testName() throws Exception { HashMap<String, String> javaFormattingPrefs = TestUtils.getJavaProperties(); int i = INPUT.indexOf("/*-"); int i2 = INPUT.indexOf("-*/"); TypedPosition partition = new TypedPosition(i, i2 - i + 3, ""); HashMap<String, String> jsMap = TestUtils.getJSProperties(); IDocument document = new Document(INPUT); TextEdit format1 = JsniFormattingUtil.format(document, partition, javaFormattingPrefs, jsMap, null); // TextEdit format1 = JsniFormattingUtil.format(document,javaFormattingPrefs, jsMap, null); format1.apply(document); Assert.assertEquals(FORMATTED, document.get()); System.err.println(FORMATTED); }
/** * Formats the specified compilation unit. * * @param unit the compilation unit to format * @param monitor the monitor for the operation * @throws JavaModelException */ public static void formatUnitSourceCode(ICompilationUnit unit, IProgressMonitor monitor) throws JavaModelException { CodeFormatter formatter = ToolFactory.createCodeFormatter(null); ISourceRange range = unit.getSourceRange(); TextEdit formatEdit = formatter.format( CodeFormatter.K_COMPILATION_UNIT, unit.getSource(), range.getOffset(), range.getLength(), 0, null); if (formatEdit != null && formatEdit.hasChildren()) { unit.applyTextEdit(formatEdit, monitor); } else { monitor.done(); } }
public void run(IStructuredSelection selection) { final ModuleCollector collector = new ModuleCollector(); // Add by Oliver. Fill the source model into collector.modules. initSelectedVjoType(selection, collector); if (!collector.modules.isEmpty()) { for (Iterator i = collector.modules.iterator(); i.hasNext(); ) { final ISourceModule module = (ISourceModule) i.next(); final IResource resource = module.getResource(); if (resource != null && resource.getType() == IResource.FILE && resource.exists()) { final IScriptProject project = module.getScriptProject(); final IScriptFormatterFactory formatterFactory = ScriptFormatterManager.getSelected(project); if (formatterFactory != null) { try { final String source = module.getSource(); final Document document = new Document(source); final String lineDelimiter = TextUtilities.getDefaultLineDelimiter(document); final Map preferences = formatterFactory.retrievePreferences(new PreferencesLookupDelegate(project)); final IScriptFormatter formatter = formatterFactory.createFormatter(lineDelimiter, preferences); final TextEdit edit = formatter.format(source, 0, source.length(), 0); if (edit != null) { edit.apply(document); final String newSource = document.get(); if (!source.equals(newSource)) { module.becomeWorkingCopy(null, null); module.getBuffer().setContents(newSource); module.commitWorkingCopy(true, null); } } } catch (Exception e) { DLTKUIPlugin.log(e); break; } } } } } }
@Override public int getStartPosition() { if (this.group.isEmpty()) { return this.node.getOffset(); } IRegion coverage = TextEdit.getCoverage(this.group.getTextEdits()); if (coverage == null) { return this.node.getOffset(); } return coverage.getOffset(); }
@Override public int getLength() { if (this.group.isEmpty()) { return this.node.getLength(); } IRegion coverage = TextEdit.getCoverage(this.group.getTextEdits()); if (coverage == null) { return this.node.getLength(); } return coverage.getLength(); }
@Override protected void addEdits(IDocument document, TextEdit rootEdit) throws CoreException { try { String lineDelimiter = TextUtilities.getDefaultLineDelimiter(document); final IJavaProject project = getCompilationUnit().getJavaProject(); IRegion region = document.getLineInformationOfOffset(fInsertPosition); String lineContent = document.get(region.getOffset(), region.getLength()); String indentString = Strings.getIndentString(lineContent, project); String str = Strings.changeIndent(fComment, 0, project, indentString, lineDelimiter); InsertEdit edit = new InsertEdit(fInsertPosition, str); rootEdit.addChild(edit); if (fComment.charAt(fComment.length() - 1) != '\n') { rootEdit.addChild(new InsertEdit(fInsertPosition, lineDelimiter)); rootEdit.addChild(new InsertEdit(fInsertPosition, indentString)); } } catch (BadLocationException e) { throw new CoreException(JavaUIStatus.createError(IStatus.ERROR, e)); } }
@Override protected void doFormatPreview() { if (fSnippets.isEmpty()) { fPreviewDocument.set(""); // $NON-NLS-1$ return; } // This delimiter looks best for invisible characters final String delimiter = "\n"; // $NON-NLS-1$ final StringBuilder buffer = new StringBuilder(); for (PreviewSnippet snippet : fSnippets) { String formattedSource; try { TextEdit edit = CodeFormatterUtil.format(snippet.kind, snippet.source, 0, delimiter, fWorkingValues); if (edit == null) { formattedSource = snippet.source; } else { Document document = new Document(snippet.source); edit.apply(document, TextEdit.NONE); formattedSource = document.get(); } } catch (Exception e) { final IStatus status = new Status( IStatus.ERROR, CUIPlugin.getPluginId(), ICStatusConstants.INTERNAL_ERROR, FormatterMessages.CPreview_formatter_exception, e); CUIPlugin.log(status); continue; } buffer.append(delimiter); buffer.append(formattedSource); buffer.append(delimiter); buffer.append(delimiter); } fPreviewDocument.set(buffer.toString()); }
/** * 格式化源码 * * @param code * @return */ @SuppressWarnings({"rawtypes", "unchecked"}) private static String formatBodyCode(String code) { try { // 此处可以修改格式化配置 Map m = DefaultCodeFormatterConstants.getEclipseDefaultSettings(); m.put(DefaultCodeFormatterConstants.FORMATTER_LINE_SPLIT, "100"); m.put(DefaultCodeFormatterConstants.FORMATTER_ALIGN_TYPE_MEMBERS_ON_COLUMNS, "true"); m.put(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, JavaCore.SPACE); CodeFormatter codeFormatter = ToolFactory.createCodeFormatter(m); TextEdit textEdit = codeFormatter.format(CodeFormatter.K_UNKNOWN, code, 0, code.length(), 0, null); if (textEdit != null) { IDocument doc = new Document(code); textEdit.apply(doc); return doc.get(); } } catch (BadLocationException e) { LOG.error("格式化源代码失败", e); } return code; }
private static IRegion getCorrespondingEditChangeRange( SearchMatch searchResult, TextChangeManager manager) { TextChange change = getTextChange(searchResult, manager); if (change == null) return null; IRegion oldMatchRange = createTextRange(searchResult); TextEditChangeGroup[] editChanges = change.getTextEditChangeGroups(); for (int i = 0; i < editChanges.length; i++) { if (oldMatchRange.equals(editChanges[i].getRegion())) return TextEdit.getCoverage(change.getPreviewEdits(editChanges[i].getTextEdits())); } return null; }
/** * 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); } }
/** * @param change * @return Map <Integer oldOffset, Integer updatedOffset> */ private static Map<Integer, Integer> getEditChangeOffsetUpdates(TextChange change) { TextEditChangeGroup[] editChanges = change.getTextEditChangeGroups(); Map<Integer, Integer> offsetUpdates = new HashMap<>(editChanges.length); for (int i = 0; i < editChanges.length; i++) { TextEditChangeGroup editChange = editChanges[i]; IRegion oldRegion = editChange.getRegion(); if (oldRegion == null) continue; IRegion updatedRegion = TextEdit.getCoverage(change.getPreviewEdits(editChange.getTextEdits())); if (updatedRegion == null) continue; offsetUpdates.put(new Integer(oldRegion.getOffset()), new Integer(updatedRegion.getOffset())); } return offsetUpdates; }
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); } }
/** * Applies the C++ code formatter to the code affected by refactoring. * * @param multiEdit The text edit produced by refactoring. * @param code The code being modified. * @param project The project containing the code. * @return The text edit containing formatted refactoring changes, or the original text edit in * case of errors. */ private MultiTextEdit formatChangedCode(MultiTextEdit multiEdit, String code, IProject project) { IDocument document = new Document(code); try { // Apply refactoring changes to a temporary document. TextEdit edit = multiEdit.copy(); edit.apply(document, TextEdit.UPDATE_REGIONS); // Expand regions affected by the changes to cover complete lines. We calculate two // sets of regions, reflecting the state of the document before and after // the refactoring changes. TextEdit[] edits = edit.getChildren(); TextEdit[] originalEdits = multiEdit.getChildren(); IRegion[] regionsAfter = new IRegion[edits.length]; IRegion[] regionsBefore = new IRegion[edits.length]; int numRegions = 0; int prevEnd = -1; for (int i = 0; i < edits.length; i++) { edit = edits[i]; int offset = edit.getOffset(); int end = offset + edit.getLength(); int newOffset = document.getLineInformationOfOffset(offset).getOffset(); int newEnd = endOffset(document.getLineInformationOfOffset(end)); edit = originalEdits[i]; int offsetBefore = edit.getOffset(); int newOffsetBefore = newOffset + offsetBefore - offset; int newEndBefore = newEnd + offsetBefore + edit.getLength() - end; if (newOffset <= prevEnd) { numRegions--; newOffset = regionsAfter[numRegions].getOffset(); newOffsetBefore = regionsBefore[numRegions].getOffset(); } prevEnd = newEnd; regionsAfter[numRegions] = new Region(newOffset, newEnd - newOffset); regionsBefore[numRegions] = new Region(newOffsetBefore, newEndBefore - newOffsetBefore); numRegions++; } if (numRegions < regionsAfter.length) { regionsAfter = Arrays.copyOf(regionsAfter, numRegions); regionsBefore = Arrays.copyOf(regionsBefore, numRegions); } // Calculate formatting changes for the regions after the refactoring changes. ICProject proj = CCorePlugin.getDefault().getCoreModel().create(project); Map<String, String> options = proj.getOptions(true); // Allow all comments to be indented. options.put( DefaultCodeFormatterConstants .FORMATTER_COMMENT_NEVER_INDENT_LINE_COMMENTS_ON_FIRST_COLUMN, DefaultCodeFormatterConstants.FALSE); CodeFormatter formatter = ToolFactory.createCodeFormatter(options); code = document.get(); TextEdit[] formatEdits = formatter.format( CodeFormatter.K_TRANSLATION_UNIT, code, regionsAfter, TextUtilities.getDefaultLineDelimiter(document)); // For each of the regions we apply formatting changes and create a ReplaceEdit using // the region before the refactoring changes and the text after the formatting changes. MultiTextEdit resultEdit = new MultiTextEdit(); for (int i = 0; i < regionsAfter.length; i++) { IRegion region = regionsAfter[i]; int offset = region.getOffset(); edit = formatEdits[i]; edit.moveTree(-offset); document = new Document(code.substring(offset, offset + region.getLength())); edit.apply(document, TextEdit.NONE); region = regionsBefore[i]; edit = new ReplaceEdit(region.getOffset(), region.getLength(), document.get()); resultEdit.addChild(edit); } return resultEdit; } catch (MalformedTreeException e) { CCorePlugin.log(e); return multiEdit; } catch (BadLocationException e) { CCorePlugin.log(e); return multiEdit; } }
private boolean rangeRemoved(TextEdit edit) { unchangedUntil(edit.getOffset()); return false; }
@Override public String getAdditionalProposalInfo() { final StringBuilder buf = new StringBuilder(); try { final TextChange change = getTextChange(); change.setKeepPreviewEdits(true); final IDocument previewContent = change.getPreviewDocument(new NullProgressMonitor()); final TextEdit rootEdit = change.getPreviewEdit(change.getEdit()); class EditAnnotator extends TextEditVisitor { private int fWrittenToPos = 0; public void unchangedUntil(int pos) { if (pos > fWrittenToPos) { appendContent(previewContent, fWrittenToPos, pos, buf, true); fWrittenToPos = pos; } } @Override public boolean visit(MoveTargetEdit edit) { return true; // rangeAdded(edit); } @Override public boolean visit(CopyTargetEdit edit) { return true; // return rangeAdded(edit); } @Override public boolean visit(InsertEdit edit) { return rangeAdded(edit); } @Override public boolean visit(ReplaceEdit edit) { if (edit.getLength() > 0) return rangeAdded(edit); return rangeRemoved(edit); } @Override public boolean visit(MoveSourceEdit edit) { return rangeRemoved(edit); } @Override public boolean visit(DeleteEdit edit) { return rangeRemoved(edit); } private boolean rangeRemoved(TextEdit edit) { unchangedUntil(edit.getOffset()); return false; } private boolean rangeAdded(TextEdit edit) { unchangedUntil(edit.getOffset()); buf.append("<b>"); // $NON-NLS-1$ appendContent(previewContent, edit.getOffset(), edit.getExclusiveEnd(), buf, false); buf.append("</b>"); // $NON-NLS-1$ fWrittenToPos = edit.getExclusiveEnd(); return false; } } EditAnnotator ea = new EditAnnotator(); rootEdit.accept(ea); // Final pre-existing region ea.unchangedUntil(previewContent.getLength()); } catch (CoreException e) { CUIPlugin.log(e); } return buf.toString(); }