issue #129949: permit modifications of guarded JavaSource diff --git a/java.source/apichanges.xml b/java.source/apichanges.xml --- a/java.source/apichanges.xml +++ b/java.source/apichanges.xml @@ -105,6 +105,18 @@ is the proper place. + + + Added ModificationResult.Difference.guards(boolean) and isGuarded() methods permitting to write modifications even to guarded sections + + + + + + Added methods to allow ModificationResult to write changes into guarded sections of a document in case the API client + is aware of what he does. + + Added CompilationInfo.getChangedTree method returning the reparsed subtree diff --git a/java.source/src/org/netbeans/api/java/source/ModificationResult.java b/java.source/src/org/netbeans/api/java/source/ModificationResult.java --- a/java.source/src/org/netbeans/api/java/source/ModificationResult.java +++ b/java.source/src/org/netbeans/api/java/source/ModificationResult.java @@ -141,26 +141,15 @@ public final class ModificationResult { for (Difference diff : differences) { if (diff.isExcluded()) continue; - try { - switch (diff.getKind()) { - case INSERT: - doc.insertString(diff.getStartPosition().getOffset(), diff.getNewText(), null); - break; - case REMOVE: - doc.remove(diff.getStartPosition().getOffset(), diff.getEndPosition().getOffset() - diff.getStartPosition().getOffset()); - break; - case CHANGE: - doc.remove(diff.getStartPosition().getOffset(), diff.getEndPosition().getOffset() - diff.getStartPosition().getOffset()); - doc.insertString(diff.getStartPosition().getOffset(), diff.getNewText(), null); - break; - case CREATE: - createUnit(diff, out); - break; - } - } catch (BadLocationException ex) { - IOException ioe = new IOException(); - ioe.initCause(ex); - throw ioe; + switch (diff.getKind()) { + case INSERT: + case REMOVE: + case CHANGE: + processDocument(doc, diff); + break; + case CREATE: + createUnit(diff, out); + break; } } success = true; @@ -250,6 +239,49 @@ public final class ModificationResult { out.close(); } } + + private void processDocument(final Document doc, final Difference diff) throws IOException { + final BadLocationException[] blex = new BadLocationException[1]; + Runnable task = new Runnable() { + + public void run() { + try { + processDocumentLocked(doc, diff); + } catch (BadLocationException ex) { + blex[0] = ex; + } + } + }; + if (doc instanceof BaseDocument) { + if (diff.isGuarded()) { + ((BaseDocument) doc).runAtomic(task); + } else { + ((BaseDocument) doc).runAtomicAsUser(task); + } + } else { + task.run(); + } + if (blex[0] != null) { + IOException ioe = new IOException(); + ioe.initCause(blex[0]); + throw ioe; + } + } + + private void processDocumentLocked(Document doc, Difference diff) throws BadLocationException { + switch (diff.getKind()) { + case INSERT: + doc.insertString(diff.getStartPosition().getOffset(), diff.getNewText(), null); + break; + case REMOVE: + doc.remove(diff.getStartPosition().getOffset(), diff.getEndPosition().getOffset() - diff.getStartPosition().getOffset()); + break; + case CHANGE: + doc.remove(diff.getStartPosition().getOffset(), diff.getEndPosition().getOffset() - diff.getStartPosition().getOffset()); + doc.insertString(diff.getStartPosition().getOffset(), diff.getNewText(), null); + break; + } + } private void createUnit(Difference diff, Writer out) { CreateChange change = (CreateChange) diff; @@ -307,6 +339,7 @@ public final class ModificationResult { String newText; String description; private boolean excluded; + private boolean ignoreGuards = false; Difference(Kind kind, PositionRef startPos, PositionRef endPos, String oldText, String newText, String description) { this.kind = kind; @@ -350,6 +383,24 @@ public final class ModificationResult { excluded = b; } + /** + * Gets flag if it is possible to write to guarded sections. + * @return {@code true} in case the difference may be written even into + * guarded sections. + * @see #guards(boolean) + */ + public boolean isGuarded() { + return ignoreGuards; + } + + /** + * Sets flag if it is possible to write to guarded sections. + * @param b flag if it is possible to write to guarded sections + */ + public void guards(boolean b) { + ignoreGuards = b; + } + @Override public String toString() { return kind + "<" + startPos.getOffset() + ", " + endPos.getOffset() + ">: " + oldText + " -> " + newText; diff --git a/java.source/test/unit/data/goldenfiles/org/netbeans/api/java/source/ModificationResultTest/testInsertToGuardedDocument.pass b/java.source/test/unit/data/goldenfiles/org/netbeans/api/java/source/ModificationResultTest/testInsertToGuardedDocument.pass new file mode 100644 --- /dev/null +++ b/java.source/test/unit/data/goldenfiles/org/netbeans/api/java/source/ModificationResultTest/testInsertToGuardedDocument.pass @@ -0,0 +1,6 @@ +test +new-test1 +test +new-test2 +test + diff --git a/java.source/test/unit/src/org/netbeans/api/java/source/ModificationResultTest.java b/java.source/test/unit/src/org/netbeans/api/java/source/ModificationResultTest.java --- a/java.source/test/unit/src/org/netbeans/api/java/source/ModificationResultTest.java +++ b/java.source/test/unit/src/org/netbeans/api/java/source/ModificationResultTest.java @@ -48,6 +48,7 @@ import java.util.List; import java.util.List; import javax.swing.text.Document; import javax.swing.text.Position.Bias; +import javax.swing.text.StyledDocument; import org.netbeans.junit.NbTestCase; import org.openide.cookies.EditorCookie; import org.openide.filesystems.FileLock; @@ -56,6 +57,7 @@ import org.openide.filesystems.FileUtil; import org.openide.filesystems.FileUtil; import org.openide.loaders.DataObject; import org.openide.text.CloneableEditorSupport; +import org.openide.text.NbDocument; import org.openide.text.PositionRef; /** @@ -142,6 +144,31 @@ public class ModificationResultTest exte compareReferenceFiles(); } + private void performTestToGuardedDocument(String creator) throws Exception { + prepareTest(); + + StyledDocument doc = ces.openDocument(); + + NbDocument.markGuarded(doc, 4, 6); + + Method m = ModificationResultTest.class.getDeclaredMethod(creator, new Class[0]); + + ModificationResult result = (ModificationResult) m.invoke(this, new Object[0]); + + for (FileObject fo : result.getModifiedFileObjects()) { + for (ModificationResult.Difference diff : result.getDifferences(fo)) { + diff.guards(true); + } + } + + + result.commit(); + + ref(doc.getText(0, doc.getLength())); + + compareReferenceFiles(); + } + private ModificationResult prepareRemoveResult() throws Exception { PositionRef start1 = ces.createPositionRef(5, Bias.Forward); PositionRef end1 = ces.createPositionRef(9, Bias.Forward); @@ -198,6 +225,10 @@ public class ModificationResultTest exte performTestToDocument("prepareInsertResult"); } + public void testInsertToGuardedDocument() throws Exception { + performTestToGuardedDocument("prepareInsertResult"); + } + public void testRemoveFromFile() throws Exception { performTestToFile("prepareRemoveResult"); }