示例#1
0
 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 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));
 }
 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));
 }
 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));
 }
  protected void createRootChange() {
    rootChange = new CompositeChange(getLabel());
    change = FileChangeFactory.getFileChange(file);

    MultiTextEdit root = new MultiTextEdit();
    change.setEdit(root);
    rootChange.add(change);
    // rootChange.markAsSynthetic();
  }
 @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());
 }
示例#7
0
 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);
    }
  }
 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));
 }
示例#11
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;
  }
 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));
     }
   }
 }
 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 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 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();
   }
 }
 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();
   }
 }
 static void addCreateMemberProposal(
     Collection<ICompletionProposal> proposals,
     DefinitionGenerator dg,
     Declaration typeDec,
     PhasedUnit unit,
     Tree.Declaration decNode,
     Tree.Body body,
     Tree.Statement statement) {
   IFile file = getFile(unit);
   TextFileChange change = new TextFileChange("Create Member", file);
   change.setEdit(new MultiTextEdit());
   IDocument doc = EditorUtil.getDocument(change);
   String indentBefore;
   String indentAfter;
   String indent;
   int offset;
   List<Tree.Statement> statements = body.getStatements();
   String delim = getDefaultLineDelimiter(doc);
   if (statements.isEmpty()) {
     String bodyIndent = getIndent(decNode, doc);
     indent = bodyIndent + getDefaultIndent();
     indentBefore = delim + indent;
     try {
       boolean singleLineBody =
           doc.getLineOfOffset(body.getStartIndex()) == doc.getLineOfOffset(body.getStopIndex());
       if (singleLineBody) {
         indentAfter = delim + bodyIndent;
       } else {
         indentAfter = "";
       }
     } catch (BadLocationException e) {
       e.printStackTrace();
       indentAfter = delim;
     }
     offset = body.getStartIndex() + 1;
   } else {
     Tree.Statement st;
     if (statement != null
         && statement.getUnit().equals(body.getUnit())
         && statement.getStartIndex() >= body.getStartIndex()
         && statement.getStopIndex() <= body.getStopIndex()) {
       st = statements.get(0);
       for (Tree.Statement s : statements) {
         if (statement.getStartIndex() >= s.getStartIndex()
             && statement.getStopIndex() <= s.getStopIndex()) {
           st = s;
         }
       }
       indent = getIndent(st, doc);
       indentBefore = "";
       indentAfter = delim + indent;
       offset = st.getStartIndex();
     } else {
       st = statements.get(statements.size() - 1);
       indent = getIndent(st, doc);
       indentBefore = delim + indent;
       indentAfter = "";
       offset = st.getStopIndex() + 1;
     }
   }
   String generated =
       typeDec instanceof Interface
           ? dg.generateSharedFormal(indent, delim)
           : dg.generateShared(indent, delim);
   String def = indentBefore + generated + indentAfter;
   int il = applyImports(change, dg.getImports(), unit.getCompilationUnit(), doc);
   change.addEdit(new InsertEdit(offset, def));
   String desc = "Create " + memberKind(dg) + " in '" + typeDec.getName() + "'";
   int exitPos = dg.getNode().getStopIndex() + 1;
   proposals.add(
       new CreateProposal(
           def,
           desc,
           body.getScope(),
           body.getUnit(),
           dg.getReturnType(),
           dg.getImage(),
           offset + il,
           change,
           exitPos,
           dg instanceof ObjectClassDefinitionGenerator));
 }
示例#18
0
  @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);
    }
  }
示例#19
0
  @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;
  }
  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()]);
  }