private static void addCreateProposal( Collection<ICompletionProposal> proposals, boolean local, DefinitionGenerator dg, PhasedUnit unit, Tree.Statement statement) { IFile file = getFile(unit); TextFileChange change = new TextFileChange(local ? "Create Local" : "Create Toplevel", file); change.setEdit(new MultiTextEdit()); IDocument doc = EditorUtil.getDocument(change); String indent = getIndent(statement, doc); int offset = statement.getStartIndex(); String delim = getDefaultLineDelimiter(doc); Tree.CompilationUnit cu = unit.getCompilationUnit(); int il = applyImports(change, dg.getImports(), cu, doc); String def = dg.generate(indent, delim) + delim + indent; if (!local) def += delim; change.addEdit(new InsertEdit(offset, def)); String desc = (local ? "Create local " : "Create toplevel ") + dg.getDescription(); final Scope scope = local ? statement.getScope() : cu.getUnit().getPackage(); int exitPos = dg.getNode().getStopIndex() + 1; proposals.add( new CreateProposal( def, desc, scope, cu.getUnit(), dg.getReturnType(), dg.getImage(), offset + il, change, exitPos, dg instanceof ObjectClassDefinitionGenerator)); }
public static void refactorProjectImportsAndDocLinks( Tree.Declaration node, IFile originalFile, IFile targetFile, CompositeChange change, String originalPackage, String targetPackage) { if (!originalPackage.equals(targetPackage)) { for (PhasedUnit pu : getAllUnits(originalFile.getProject())) { // if (!node.getUnit().equals(pu.getUnit())) { IFile file = ((IFileVirtualFile) pu.getUnitFile()).getFile(); if (!file.equals(originalFile) && !file.equals(targetFile)) { TextFileChange tfc = new TextFileChange("Fix Import", file); tfc.setEdit(new MultiTextEdit()); CompilationUnit rootNode = pu.getCompilationUnit(); refactorImports(node, originalPackage, targetPackage, rootNode, tfc); refactorDocLinks(node, targetPackage, rootNode, tfc); if (tfc.getEdit().hasChildren()) { change.add(tfc); } } // } } } }
static void addCreateProposal( Collection<ICompletionProposal> proposals, String def, boolean local, String desc, Image image, PhasedUnit unit, Tree.Statement statement, ProducedType t) { IFile file = CeylonBuilder.getFile(unit); TextFileChange change = new TextFileChange(local ? "Create Local" : "Create Toplevel", file); change.setEdit(new MultiTextEdit()); IDocument doc = CreateProposal.getDocument(change); String indent = CeylonQuickFixAssistant.getIndent(statement, doc); int offset = statement.getStartIndex(); def = def.replace("$indent", indent); int il = importType(change, t, unit.getCompilationUnit()); change.addEdit(new InsertEdit(offset, def + "\n" + indent)); proposals.add( new CreateProposal( def, (local ? "Create local " : "Create toplevel ") + desc, image, 0, offset + il, file, change)); }
static void addCreateParameterProposal( Collection<ICompletionProposal> proposals, String def, String desc, Image image, Declaration dec, PhasedUnit unit, Tree.Declaration decNode, Tree.ParameterList paramList, ProducedType t) { IFile file = CeylonBuilder.getFile(unit); TextFileChange change = new TextFileChange("Add Parameter", file); change.setEdit(new MultiTextEdit()); int offset = paramList.getStopIndex(); int il = importType(change, t, unit.getCompilationUnit()); change.addEdit(new InsertEdit(offset, def)); proposals.add( new CreateProposal( def, "Add " + desc + " to '" + dec.getName() + "'", image, 0, offset + il, file, change)); }
public void test_toLTK_Change_SourceChange() throws Exception { Source source = createTestFileSource(); // fill SourceChange SourceChange sourceChange = new SourceChange("My change", source); sourceChange.addEdit(new Edit(10, 1, "a")); sourceChange.addEdit(new Edit(20, 2, "b")); // toLTK TextFileChange ltkChange = (TextFileChange) ServiceUtils.toLTK((Change) sourceChange); assertEquals("My change", ltkChange.getName()); }
@Override protected TextChange createTextChange() throws CoreException { init(fRefactoring); fRefactoringStatus = fRefactoring.checkFinalConditions(new NullProgressMonitor()); if (fRefactoringStatus.hasFatalError()) { TextFileChange dummyChange = new TextFileChange( "fatal error", (IFile) getCompilationUnit().getResource()); // $NON-NLS-1$ dummyChange.setEdit(new InsertEdit(0, "")); // $NON-NLS-1$ return dummyChange; } return (TextChange) fRefactoring.createChange(new NullProgressMonitor()); }
/** * 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 void generateChange(IASTNode rootNode, ASTVisitor pathProvider) throws ProblemRuntimeException { change = new CompositeChange(ChangeGeneratorMessages.ChangeGenerator_compositeChange); classifyModifications(); rootNode.accept(pathProvider); for (IFile currentFile : changes.keySet()) { MultiTextEdit edit = changes.get(currentFile); edit = formatChangedCode( edit, rootNode.getTranslationUnit().getRawSignature(), currentFile.getProject()); TextFileChange subchange = ASTRewriteAnalyzer.createCTextFileChange(currentFile); subchange.setEdit(edit); change.add(subchange); } }
private boolean addXmlFileChanges(IFile file, CompositeChange changes, boolean isManifest) { IModelManager modelManager = StructuredModelManager.getModelManager(); IStructuredModel model = null; try { model = modelManager.getExistingModelForRead(file); if (model == null) { model = modelManager.getModelForRead(file); } if (model != null) { IStructuredDocument document = model.getStructuredDocument(); if (model instanceof IDOMModel) { IDOMModel domModel = (IDOMModel) model; Element root = domModel.getDocument().getDocumentElement(); if (root != null) { List<TextEdit> edits = new ArrayList<TextEdit>(); if (isManifest) { addManifestReplacements(edits, root, document); } else { addLayoutReplacements(edits, root, document); } if (!edits.isEmpty()) { MultiTextEdit rootEdit = new MultiTextEdit(); rootEdit.addChildren(edits.toArray(new TextEdit[edits.size()])); TextFileChange change = new TextFileChange(file.getName(), file); change.setTextType(EXT_XML); change.setEdit(rootEdit); changes.add(change); } } } else { return false; } } return true; } catch (IOException e) { AdtPlugin.log(e, null); } catch (CoreException e) { AdtPlugin.log(e, null); } finally { if (model != null) { model.releaseFromRead(); } } return false; }
private static void addProposal( Identifier identifier, Collection<ICompletionProposal> proposals, IFile file) { String oldIdentifier = identifier.getText(); int first = oldIdentifier.codePointAt(0); int newFirst = isUpperCase(first) ? toLowerCase(first) : toUpperCase(first); String newFirstLetter = new String(toChars(newFirst)); String newIdentifier = newFirstLetter + oldIdentifier.substring(charCount(first)); TextFileChange change = new TextFileChange("Change initial case of identifier", file); change.setEdit(new ReplaceEdit(identifier.getStartIndex(), 1, newFirstLetter)); ChangeInitialCaseOfIdentifierInDeclaration proposal = new ChangeInitialCaseOfIdentifierInDeclaration(newIdentifier, change); if (!proposals.contains(proposal)) { proposals.add(proposal); } }
private void addRemoval(Tree.Identifier id, Declaration d) { if (id != null && d != null && dec.equals(getAbstraction(d)) && id.getText().equals(aid.getText())) { change.addEdit(new ReplaceEdit(id.getStartIndex(), id.getDistance(), dec.getName())); } }
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); } }
static IDocument getDocument(TextFileChange change) { IDocument doc; try { doc = change.getCurrentDocument(null); } catch (CoreException e) { throw new RuntimeException(e); } return doc; }
protected void createRootChange() { rootChange = new CompositeChange(getLabel()); change = FileChangeFactory.getFileChange(file); MultiTextEdit root = new MultiTextEdit(); change.setEdit(root); rootChange.add(change); // rootChange.markAsSynthetic(); }
static void addCreateParameterAndAttributeProposal( Collection<ICompletionProposal> proposals, String pdef, String adef, String desc, Image image, Declaration dec, PhasedUnit unit, Tree.Declaration decNode, Tree.ParameterList paramList, Tree.Body body, ProducedType t) { IFile file = CeylonBuilder.getFile(unit); TextFileChange change = new TextFileChange("Add Attribute", file); change.setEdit(new MultiTextEdit()); int offset = paramList.getStopIndex(); IDocument doc = CreateProposal.getDocument(change); String indent; String indentAfter; int offset2; List<Tree.Statement> statements = body.getStatements(); if (statements.isEmpty()) { indentAfter = "\n" + CeylonQuickFixAssistant.getIndent(decNode, doc); indent = indentAfter + getDefaultIndent(); offset2 = body.getStartIndex() + 1; } else { Tree.Statement statement = statements.get(statements.size() - 1); indent = "\n" + CeylonQuickFixAssistant.getIndent(statement, doc); offset2 = statement.getStopIndex() + 1; indentAfter = ""; } int il = importType(change, t, unit.getCompilationUnit()); change.addEdit(new InsertEdit(offset, pdef)); change.addEdit(new InsertEdit(offset2, indent + adef + indentAfter)); proposals.add( new CreateProposal( pdef, "Add " + desc + " to '" + dec.getName() + "'", image, 0, offset + il, file, change)); }
/** 取得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; }
@Override public Object execute(ExecutionEvent event) throws ExecutionException { IEditorPart editor = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage().getActiveEditor(); final boolean enableRiskyRefactoring = Platform.getPreferencesService() .getBoolean( ProductConstants.PRODUCT_ID_DESIGNER, PreferenceConstants.ENABLERISKYREFACTORING, false, null); if (!enableRiskyRefactoring) { ErrorReporter.logError("Risky refactoring is not enabled!"); return null; } if (editor == null || !(editor instanceof TTCN3Editor || (editor instanceof TTCNPPEditor && enableRiskyRefactoring))) { ErrorReporter.logError("The editor is not found or not a Titan TTCN-3 editor"); return null; } IFile file = (IFile) editor.getEditorInput().getAdapter(IFile.class); TextFileChange change = null; try { change = OrganizeImports.organizeImportsChange(file); } catch (CoreException e) { ErrorReporter.logExceptionStackTrace("Error while creating the needed import changes", e); return null; } try { change.perform(new NullProgressMonitor()); } catch (CoreException e) { ErrorReporter.logExceptionStackTrace("Error while performing the needed import changes", e); } IProject project = file.getProject(); GlobalParser.getProjectSourceParser(project).reportOutdating(file); GlobalParser.getProjectSourceParser(project).analyzeAll(); return null; }
public void test_toLTK_SourceChange_noGroups() throws Exception { Source source = createTestFileSource(); // fill SourceChange SourceChange sourceChange = new SourceChange("My change", source); sourceChange.addEdit(new Edit(10, 1, "a")); sourceChange.addEdit(new Edit(20, 2, "b")); // toLTK TextFileChange ltkChange = ServiceUtils.toLTK(sourceChange); assertEquals("My change", ltkChange.getName()); // no groups TextEditBasedChangeGroup[] changeGroups = ltkChange.getChangeGroups(); assertThat(changeGroups).isEmpty(); // check edits MultiTextEdit multiTextEdit = (MultiTextEdit) ltkChange.getEdit(); TextEdit[] textEdits = multiTextEdit.getChildren(); assertThat(textEdits).hasSize(2); assertEquals("a", ((ReplaceEdit) textEdits[0]).getText()); assertEquals("b", ((ReplaceEdit) textEdits[1]).getText()); }
@Override public void visit(Tree.DocLink that) { super.visit(that); // TODO: copy/paste from EnterAliasRefactoring Declaration base = that.getBase(); if (base != null && dec.equals(base)) { Region region = DocLinks.nameRegion(that, 0); change.addEdit(new ReplaceEdit(region.getOffset(), region.getLength(), dec.getName())); } }
static void addRemoveAliasProposal( Tree.ImportMemberOrType imt, Collection<ICompletionProposal> proposals, IFile file, CeylonEditor editor) { if (imt != null) { Declaration dec = imt.getDeclarationModel(); Tree.CompilationUnit upToDateAndTypechecked = editor.getParseController().getTypecheckedRootNode(); if (dec != null && imt.getAlias() != null && upToDateAndTypechecked != null) { TextFileChange change = new TextFileChange("Remove Alias", file); change.setEdit(new MultiTextEdit()); Tree.Identifier aid = imt.getAlias().getIdentifier(); change.addEdit( new DeleteEdit( aid.getStartIndex(), imt.getIdentifier().getStartIndex() - aid.getStartIndex())); upToDateAndTypechecked.visit(new AliasRemovalVisitor(dec, change, aid)); proposals.add(new RemoveAliasProposal(file, dec, change)); } } }
public void test_toLTK_SourceChange_withGroups() throws Exception { Source source = createTestFileSource(); // fill SourceChange SourceChange sourceChange = new SourceChange("My change", source); sourceChange.addEdit(new Edit(10, 1, "a1"), "groupA"); sourceChange.addEdit(new Edit(20, 2, "a2"), "groupA"); sourceChange.addEdit(new Edit(30, 3, "b"), "groupB"); // toLTK TextFileChange ltkChange = ServiceUtils.toLTK(sourceChange); assertEquals("My change", ltkChange.getName()); TextEditBasedChangeGroup[] changeGroups = ltkChange.getChangeGroups(); assertThat(changeGroups).hasSize(2); { TextEditBasedChangeGroup group = changeGroups[0]; assertEquals("groupA", group.getName()); TextEdit[] textEdits = group.getTextEdits(); assertThat(textEdits).hasSize(2); assertEquals("a1", ((ReplaceEdit) textEdits[0]).getText()); assertEquals("a2", ((ReplaceEdit) textEdits[1]).getText()); } }
static void addCreateEnumProposal( Collection<ICompletionProposal> proposals, String def, String desc, Image image, PhasedUnit unit, Tree.Statement statement) { IFile file = CeylonBuilder.getFile(unit); TextFileChange change = new TextFileChange("Create Enumerated", file); IDocument doc = CreateProposal.getDocument(change); String indent = CeylonQuickFixAssistant.getIndent(statement, doc); String s = indent + def + "\n"; int offset = statement.getStopIndex() + 2; if (offset > doc.getLength()) { offset = doc.getLength(); s = "\n" + s; } // def = def.replace("$indent", indent); change.setEdit(new InsertEdit(offset, s)); proposals.add( new CreateProposal(def, "Create enumerated " + desc, image, 0, offset, file, change)); }
@Override public Change createChange(final IProgressMonitor monitor) throws CoreException { try { final SubMonitor progress = SubMonitor.convert(monitor, RefactoringMessages.Common_CreateChanges_label, 3); final TextFileChange textFileChange = new SourceUnitChange(fSourceUnit); if (fSourceUnit.getWorkingContext() == LTK.EDITOR_CONTEXT) { textFileChange.setSaveMode(TextFileChange.LEAVE_DIRTY); } createChanges(textFileChange, progress.newChild(1)); final Map<String, String> arguments = new HashMap<String, String>(); final String description = NLS.bind( Messages.FunctionToS4Method_Descriptor_description, RRefactoringAdapter.getQuotedIdentifier(fFunctionName)); final IProject resource = fElementSet.getSingleProject(); final String project = (resource != null) ? resource.getName() : null; final String source = (project != null) ? NLS.bind(RefactoringMessages.Common_Source_Project_label, project) : RefactoringMessages.Common_Source_Workspace_label; final int flags = 0; final String comment = ""; // $NON-NLS-1$ final CommonRefactoringDescriptor descriptor = new CommonRefactoringDescriptor( getIdentifier(), project, description, comment, arguments, flags); return new RefactoringChange( descriptor, Messages.FunctionToS4Method_label, new Change[] {textFileChange}); } catch (final BadLocationException e) { throw new CoreException( new Status(IStatus.ERROR, RCore.PLUGIN_ID, "Unexpected error (concurrent change?)", e)); } finally { monitor.done(); } }
private void collectEdits( String newName, String oldName, List<Change> changes, PhasedUnit phasedUnit, Map<Declaration, String> imports) { try { Tree.CompilationUnit cu = phasedUnit.getCompilationUnit(); if (!imports.isEmpty()) { IFileVirtualFile virtualFile = (IFileVirtualFile) phasedUnit.getUnitFile(); IFile file = virtualFile.getFile(); String path = file.getProjectRelativePath().toPortableString(); TextFileChange change = fileChanges.get(path); if (change == null) { change = new TextFileChange(file.getName(), file); change.setEdit(new MultiTextEdit()); changes.add(change); fileChanges.put(path, change); } List<TextEdit> edits = importEditForMove( cu, imports.keySet(), imports.values(), newName, oldName, EditorUtil.getDocument(change)); if (!edits.isEmpty()) { for (TextEdit edit : edits) { change.addEdit(edit); } } } } catch (Exception e) { e.printStackTrace(); } }
@Override public Object execute(ExecutionEvent event) throws ExecutionException { CeylonEditor editor = (CeylonEditor) getCurrentEditor(); Tree.CompilationUnit cu = editor.getParseController().getRootNode(); if (cu != null) { String imports = imports(cu); if (imports != null) { TextFileChange tfc = new TextFileChange( "Clean Imports", ((IFileEditorInput) editor.getEditorInput()).getFile()); tfc.setEdit(new MultiTextEdit()); ImportList il = cu.getImportList(); int start; int length; String extra; if (il == null || il.getImports().isEmpty()) { start = 0; length = 0; extra = "\n"; } else { start = il.getStartIndex(); length = il.getStopIndex() - il.getStartIndex() + 1; extra = ""; } // if (!imports.trim().isEmpty()) { tfc.addEdit(new ReplaceEdit(start, length, imports + extra)); tfc.initializeValidationData(null); try { getWorkspace().run(new PerformChangeOperation(tfc), new NullProgressMonitor()); } catch (CoreException ce) { throw new ExecutionException("Error cleaning imports", ce); } // } } } return null; }
private void collectEditsToMovedFile( String newName, String oldName, List<Change> changes, PhasedUnit movedPhasedUnit, Map<Declaration, String> imports) { try { IFileVirtualFile virtualFile = (IFileVirtualFile) movedPhasedUnit.getUnitFile(); IFile file = virtualFile.getFile(); String path = file.getProjectRelativePath().toPortableString(); TextFileChange change = fileChanges.get(path); if (change == null) { change = new TextFileChange(file.getName(), file); change.setEdit(new MultiTextEdit()); changes.add(change); fileChanges.put(path, change); } Tree.CompilationUnit cu = movedPhasedUnit.getCompilationUnit(); if (!imports.isEmpty()) { List<InsertEdit> edits = importEdits( cu, imports.keySet(), imports.values(), null, EditorUtil.getDocument(change)); for (TextEdit edit : edits) { change.addEdit(edit); } } Tree.Import toDelete = findImportNode(cu, newName); if (toDelete != null) { change.addEdit( new DeleteEdit( toDelete.getStartIndex(), toDelete.getStopIndex() - toDelete.getStartIndex() + 1)); } } catch (Exception e) { e.printStackTrace(); } }
public static void setChangeTextType(TextFileChange change, IFile file) { // null guard in case a folder gets passed for whatever reason String name = file.getName(); if (name == null) return; // mark a plugin.xml or a fragment.xml as PLUGIN2 type so they will be compared // with the PluginContentMergeViewer String textType = name.equals(ICoreConstants.PLUGIN_FILENAME_DESCRIPTOR) || name.equals(ICoreConstants.FRAGMENT_FILENAME_DESCRIPTOR) ? "PLUGIN2" //$NON-NLS-1$ : file.getFileExtension(); // if the file extension is null, the setTextType method will use type "txt", so no null guard // needed change.setTextType(textType); }
@Override public void run(IMarker marker) { IFile file = (IFile) marker.getResource(); TextFileChange textFileChange = new TextFileChange(file.getName(), file); MultiTextEdit fileChangeRootEdit = new MultiTextEdit(); // a file change contains a tree of edits, first add the root of them textFileChange.setEdit(fileChangeRootEdit); int offset; try { offset = marker.getAttribute(IMarker.CHAR_START, -1); if (offset == -1) { int line = marker.getAttribute(IMarker.LINE_NUMBER, -1); if (line == -1) { return; } offset = UIUtils.getDocument(file).getLineOffset(line - 1); } InsertEdit quickfix = new InsertEdit(offset, marker.getAttribute(PDTMarker.QUICKFIX_ACTION).toString()); fileChangeRootEdit.addChild(quickfix); if (showWizard) { final TextFileChange fChange = textFileChange; Refactoring ref = new Refactoring() { @Override public String getName() { return "PDT Refactoring"; } @Override public Change createChange(IProgressMonitor pm) throws CoreException, OperationCanceledException { return fChange; } @Override public RefactoringStatus checkInitialConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { return new RefactoringStatus(); } @Override public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException, OperationCanceledException { return new RefactoringStatus(); } }; RefactoringWizard wizard = new RefactoringWizard(ref, RefactoringWizard.WIZARD_BASED_USER_INTERFACE) { @Override protected void addUserInputPages() {} }; Shell shell = UIUtils.getActiveShell(); RefactoringWizardOpenOperation op = new RefactoringWizardOpenOperation(wizard); try { if (op.run(shell, "") != IDialogConstants.CANCEL_ID) { // changes are already performed by the dialog file.refreshLocal(IResource.DEPTH_INFINITE, null); PrologRuntimeUIPlugin.getDefault().getPrologInterfaceService().consultFile(file); // PLMarkerUtils.updateFileMarkers(file); } } catch (InterruptedException e) { } } else { textFileChange.perform(new NullProgressMonitor()); file.refreshLocal(IResource.DEPTH_INFINITE, null); PrologRuntimeUIPlugin.getDefault().getPrologInterfaceService().consultFile(file); // PLMarkerUtils.updateFileMarkers(file); } } catch (NumberFormatException e1) { Debug.report(e1); } catch (CoreException e1) { Debug.report(e1); } catch (BadLocationException e) { Debug.report(e); } }
private static TextFileChange[] generateModelEdits( final ModelModification modification, final IProgressMonitor monitor, boolean performEdits) { ArrayList edits = new ArrayList(); // create own model, attach listeners and grab text edits ITextFileBufferManager manager = FileBuffers.getTextFileBufferManager(); IFile[] files; if (modification.isFullBundleModification()) { files = new IFile[2]; files[F_Bi] = modification.getManifestFile(); files[F_Xi] = modification.getXMLFile(); } else { files = new IFile[] {modification.getFile()}; } // need to monitor number of successful buffer connections for disconnection purposes // @see } finally { statement int sc = 0; try { ITextFileBuffer[] buffers = new ITextFileBuffer[files.length]; IDocument[] documents = new IDocument[files.length]; for (int i = 0; i < files.length; i++) { if (files[i] == null || !files[i].exists()) continue; manager.connect(files[i].getFullPath(), LocationKind.NORMALIZE, monitor); sc++; buffers[i] = manager.getTextFileBuffer(files[i].getFullPath(), LocationKind.NORMALIZE); if (performEdits && buffers[i].isDirty()) buffers[i].commit(monitor, true); documents[i] = buffers[i].getDocument(); } IBaseModel editModel; if (modification.isFullBundleModification()) editModel = prepareBundlePluginModel(files, documents, !performEdits); else editModel = prepareAbstractEditingModel(files[0], documents[0], !performEdits); modification.modifyModel(editModel, monitor); IModelTextChangeListener[] listeners = gatherListeners(editModel); for (int i = 0; i < listeners.length; i++) { if (listeners[i] == null) continue; TextEdit[] currentEdits = listeners[i].getTextOperations(); if (currentEdits.length > 0) { MultiTextEdit multi = new MultiTextEdit(); multi.addChildren(currentEdits); if (performEdits) { multi.apply(documents[i]); buffers[i].commit(monitor, true); } TextFileChange change = new TextFileChange(files[i].getName(), files[i]); change.setEdit(multi); // If the edits were performed right away (performEdits == true) then // all the names are null and we don't need the granular detail anyway. if (!performEdits) { for (int j = 0; j < currentEdits.length; j++) { String name = listeners[i].getReadableName(currentEdits[j]); if (name != null) change.addTextEditGroup(new TextEditGroup(name, currentEdits[j])); } } // save the file after the change applied change.setSaveMode(TextFileChange.FORCE_SAVE); setChangeTextType(change, files[i]); edits.add(change); } } } catch (CoreException e) { PDEPlugin.log(e); } catch (MalformedTreeException e) { PDEPlugin.log(e); } catch (BadLocationException e) { PDEPlugin.log(e); } finally { // don't want to over-disconnect in case we ran into an exception during connections // dc <= sc stops this from happening int dc = 0; for (int i = 0; i < files.length && dc <= sc; i++) { if (files[i] == null || !files[i].exists()) continue; try { manager.disconnect(files[i].getFullPath(), LocationKind.NORMALIZE, monitor); dc++; } catch (CoreException e) { PDEPlugin.log(e); } } } return (TextFileChange[]) edits.toArray(new TextFileChange[edits.size()]); }
@Override protected List<Change> computeChanges(IProgressMonitor monitor) { String name = getViewClass(mTypeFqcn); IFile file = mDelegate.getEditor().getInputFile(); List<Change> changes = new ArrayList<Change>(); if (file == null) { return changes; } TextFileChange change = new TextFileChange(file.getName(), file); MultiTextEdit rootEdit = new MultiTextEdit(); change.setEdit(rootEdit); change.setTextType(EXT_XML); changes.add(change); for (Element element : getElements()) { IndexedRegion region = getRegion(element); String text = getText(region.getStartOffset(), region.getEndOffset()); String oldName = element.getNodeName(); int open = text.indexOf(oldName); int close = text.lastIndexOf(oldName); if (element instanceof ElementImpl && ((ElementImpl) element).isEmptyTag()) { close = -1; } if (open != -1) { int oldLength = oldName.length(); rootEdit.addChild(new ReplaceEdit(region.getStartOffset() + open, oldLength, name)); } if (close != -1 && close != open) { int oldLength = oldName.length(); rootEdit.addChild(new ReplaceEdit(region.getStartOffset() + close, oldLength, name)); } // Change tag type String oldId = getId(element); String newId = ensureIdMatchesType(element, mTypeFqcn, rootEdit); // Update any layout references to the old id with the new id if (oldId != null && newId != null) { IStructuredModel model = mDelegate.getEditor().getModelForRead(); try { IStructuredDocument doc = model.getStructuredDocument(); if (doc != null) { IndexedRegion range = getRegion(element); int skipStart = range.getStartOffset(); int skipEnd = range.getEndOffset(); List<TextEdit> replaceIds = replaceIds(getAndroidNamespacePrefix(), doc, skipStart, skipEnd, oldId, newId); for (TextEdit edit : replaceIds) { rootEdit.addChild(edit); } } } finally { model.releaseFromRead(); } } // Strip out attributes that no longer make sense removeUndefinedAttrs(rootEdit, element); } return changes; }