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 @@ -98,7 +98,7 @@ private boolean committed; Map> diffs = new HashMap>(); Map tag2Span = new IdentityHashMap(); - + /** Creates a new instance of ModificationResult */ ModificationResult(final JavaSource js) { this.sources = js != null ? JavaSourceAccessor.getINSTANCE().getSources(js) : null; @@ -164,15 +164,15 @@ }); return result; } - + public @NonNull Set getModifiedFileObjects() { return diffs.keySet(); } - + public List getDifferences(@NonNull FileObject fo) { return diffs.get(fo); } - + public @NonNull Set getNewFiles() { Set newFiles = new HashSet(); for (List ds:diffs.values()) { @@ -184,7 +184,7 @@ } return newFiles; } - + /** * Once all of the changes have been collected, this method can be used * to commit the changes to the source files @@ -224,12 +224,12 @@ this.sources = null; } } - + static void commit (final FileObject fo, final List differences, final Writer out) throws IOException { DataObject dObj = DataObject.find(fo); EditorCookie ec = dObj != null ? dObj.getCookie(org.openide.cookies.EditorCookie.class) : null; // if editor cookie was found and user does not provided his own - // writer where he wants to see changes, commit the changes to + // writer where he wants to see changes, commit the changes to // found document. if (ec != null && out == null) { final StyledDocument doc = ec.getDocument(); @@ -272,7 +272,7 @@ } out2 = new FilteringWriter(out2, hasReturnChar); } - int offset = 0; + int offset = 0; for (Difference diff : differences) { if (diff.isExcluded()) continue; @@ -308,7 +308,7 @@ out2.write(diff.getNewText()); break; } - } + } char[] buff = new char[1024]; int n; while ((n = in.read(buff)) > 0) { @@ -319,7 +319,7 @@ in.close(); if (out2 != null) out2.close(); - } + } } private static void commit2 (final StyledDocument doc, final List differences, Writer out) throws IOException { @@ -338,7 +338,7 @@ } } } - + private static void processDocument(final StyledDocument doc, final Difference diff) throws IOException { final BadLocationException[] blex = new BadLocationException[1]; Runnable task = new Runnable() { @@ -393,7 +393,7 @@ throw ioe; } } - + private static void processDocumentLocked(Document doc, Difference diff) throws BadLocationException { switch (diff.getKind()) { case INSERT: @@ -403,8 +403,14 @@ 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); + try { + doc.remove(diff.getStartPosition().getOffset(), diff.getEndPosition().getOffset() - diff.getStartPosition().getOffset()); + doc.insertString(diff.getStartPosition().getOffset(), diff.getNewText(), null); + } catch (BadLocationException e) { + // do nothing because it won't accomplish those two + // statements anyway. bug #177824 + Logger.getLogger(WorkingCopy.class.getName()).log(Level.WARNING, e.getMessage()); + } break; } } @@ -430,11 +436,11 @@ } } } - + /** * Returned string represents preview of resulting source. No difference * really is applied. Respects {@code isExcluded()} flag of difference. - * + * * @param there can be more resulting source, user has to specify * which wants to preview. * @return if changes are applied source looks like return string @@ -447,10 +453,10 @@ if (!getModifiedFileObjects().contains(fileObject)) { throw new IllegalArgumentException("File: " + FileUtil.getFileDisplayName(fileObject) + " is not modified in this ModificationResult"); } - + StringWriter writer = new StringWriter(); commit(fileObject, diffs.get(fileObject), writer); - + return writer.toString(); } @@ -463,7 +469,7 @@ public @NullUnknown int[] getSpan(@NonNull Object tag) { return tag2Span.get(tag); } - + public static class Difference { Kind kind; final PositionRef startPos; @@ -483,35 +489,35 @@ this.description = description; this.excluded = false; } - + Difference(Kind kind, PositionRef startPos, PositionRef endPos, String oldText, String newText) { this(kind, startPos, endPos, oldText, newText, null); } - + public @NonNull Kind getKind() { return kind; } - + public @NonNull PositionRef getStartPosition() { return startPos; } - + public @NonNull PositionRef getEndPosition() { return endPos; } - + public @NonNull String getOldText() { return oldText; } - + public @NonNull String getNewText() { return newText; } - + public boolean isExcluded() { return excluded; } - + public void exclude(boolean b) { excluded = b; } @@ -526,7 +532,7 @@ public boolean isCommitToGuards() { 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 @@ -543,7 +549,7 @@ public String getDescription() { return description; } - + public static enum Kind { INSERT, REMOVE, @@ -551,10 +557,10 @@ CREATE; } } - + static class CreateChange extends Difference { JavaFileObject fileObject; - + CreateChange(JavaFileObject fileObject, String text) { super(Kind.CREATE, null, null, null, text, "Create file " + fileObject.getName()); this.fileObject = fileObject; @@ -569,9 +575,9 @@ return kind + "Create File: " + fileObject.getName() + "; contents = \"\n" + newText + "\""; } } - + private static final class FilteringReader extends Reader { - + private final Reader delegate; private final boolean[] hasReturnChar; private boolean beforeFirstLine = true; @@ -585,7 +591,7 @@ public int read(char[] cbuf, int off, int len) throws IOException { int read; int j; - + do { read = delegate.read(cbuf, off, len); j = 0; @@ -602,7 +608,7 @@ } } } while (j == 0 && read > 0); - + return j; } @@ -611,7 +617,7 @@ delegate.close(); } } - + private static final class FilteringWriter extends Writer { private final boolean[] hasReturnChar; private final Writer delegate; @@ -626,7 +632,7 @@ if (hasReturnChar[0]) { char[] buf = new char[len * 2]; int j = 0; - + for (int i = off; i < off + len; i++) { if (cbuf[i] == '\n') { buf[j++] = '\r'; @@ -635,7 +641,7 @@ buf[j++] = cbuf[i]; } } - + delegate.write(buf, 0, j); } else { delegate.write(cbuf, off, len); @@ -651,6 +657,6 @@ public void close() throws IOException { delegate.close(); } - + } } diff --git a/java.source/test/unit/src/org/netbeans/api/java/source/gen/GuardedBlockTest.java b/java.source/test/unit/src/org/netbeans/api/java/source/gen/GuardedBlockTest.java --- a/java.source/test/unit/src/org/netbeans/api/java/source/gen/GuardedBlockTest.java +++ b/java.source/test/unit/src/org/netbeans/api/java/source/gen/GuardedBlockTest.java @@ -107,7 +107,7 @@ /** * Regression tests for guarded exceptions. - * + * * @author Pavel Flaska */ public class GuardedBlockTest extends GeneratorTestMDRCompat { @@ -120,6 +120,7 @@ NbTestSuite suite = new NbTestSuite(); // suite.addTestSuite(GuardedBlockTest.class); suite.addTest(new GuardedBlockTest("testAddMethodAfterVariables")); + suite.addTest(new GuardedBlockTest("testInsertMethodBeforeVariablesBug177824")); suite.addTest(new GuardedBlockTest("test119048")); suite.addTest(new GuardedBlockTest("test119962")); suite.addTest(new GuardedBlockTest("testRenameTypeParameter125385")); @@ -127,7 +128,7 @@ suite.addTest(new GuardedBlockTest("testComplex186754")); return suite; } - + /** * We need our own data loader to use guarded blocks. */ @@ -156,13 +157,87 @@ cacheFolder.mkdirs(); IndexUtil.setCacheFolder(cacheFolder); } - + + /** + * #177824: Guarded Exception + */ + public void testInsertMethodBeforeVariablesBug177824() throws Exception { + + String source = + "package javaapplication5;\n" + + "\n" + + "import java.awt.event.ActionEvent;\n" + + "import java.awt.event.ActionListener;\n" + + "\n" + + "public class Guarded1 implements ActionListener {\n" + + " \n" + + " private void rbInvoiceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rbInvoiceActionPerformed\n" + + " }//GEN-LAST:event_rbInvoiceActionPerformed\n" + + "\n" + + " // Variables declaration - do not modify//GEN-BEGIN:variables\n" + + " private javax.swing.JButton jButton1;\n" + + " // End of variables declaration//GEN-END:variables\n" + + "}\n"; + + testFile = new File(getWorkDir(), "Test.java"); + TestUtilities.copyStringToFile(testFile, source); + DataObject dataObject = DataObject.find(FileUtil.toFileObject(testFile)); + EditorCookie editorCookie = ((GuardedDataObject) dataObject).getCookie(EditorCookie.class); + Document doc = editorCookie.openDocument(); + String golden = + "package javaapplication5;\n" + + "\n" + + "import java.awt.event.ActionEvent;\n" + + "import java.awt.event.ActionListener;\n" + + "\n" + + "public class Guarded1 implements ActionListener {\n" + + " \n" + + " private void rbInvoiceActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_rbInvoiceActionPerformed\n" + + " }//GEN-LAST:event_rbInvoiceActionPerformed\n" + + "\n" + + " public String toString() {\n" + + " }\n" + + "\n" + + " // Variables declaration - do not modify//GEN-BEGIN:variables\n" + + " private javax.swing.JButton jButton1;\n" + + " // End of variables declaration//GEN-END:variables\n" + + "}\n"; + + JavaSource src = getJavaSource(testFile); + Task task = new Task() { + + public void run(WorkingCopy workingCopy) throws IOException { + workingCopy.toPhase(RESOLVED); + CompilationUnitTree cut = workingCopy.getCompilationUnit(); + TreeMaker make = workingCopy.getTreeMaker(); + ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0); + MethodTree newMethod = make.Method( + make.Modifiers(Collections.singleton(Modifier.PUBLIC)), + "toString", + make.Type("java.lang.String"), + Collections.emptyList(), + Collections.emptyList(), + Collections.emptyList(), + make.Block(Collections.emptyList(), false), + null // default value - not applicable + ); + ClassTree copy = make.insertClassMember(clazz, 2, newMethod); + workingCopy.rewrite(clazz, copy); + } + }; + src.runModificationTask(task).commit(); + editorCookie.saveDocument(); + String res = TestUtilities.copyFileToString(testFile); + + assertEquals(golden, res); + } + /** * #90424: Guarded Exception */ public void testAddMethodAfterVariables() throws Exception { testFile = new File(getWorkDir(), "Test.java"); - TestUtilities.copyStringToFile(testFile, + TestUtilities.copyStringToFile(testFile, "package javaapplication5;\n" + "\n" + "import java.awt.event.ActionEvent;\n" + @@ -181,7 +256,7 @@ DataObject dataObject = DataObject.find(FileUtil.toFileObject(testFile)); EditorCookie editorCookie = ((GuardedDataObject) dataObject).getCookie(EditorCookie.class); Document doc = editorCookie.openDocument(); - String golden = + String golden = "package javaapplication5;\n" + "\n" + "import java.awt.event.ActionEvent;\n" + @@ -199,7 +274,7 @@ " public void actionPerformed(ActionEvent e) {\n" + " }\n" + "}\n"; - + JavaSource src = getJavaSource(testFile); Task task = new Task() { @@ -216,14 +291,14 @@ Collections.singletonList( make.Variable( make.Modifiers(Collections.emptySet()), - "e", - make.Identifier("ActionEvent"), + "e", + make.Identifier("ActionEvent"), null) ), Collections.emptyList(), make.Block(Collections.emptyList(), false), null // default value - not applicable - ); + ); ClassTree copy = make.addClassMember(clazz, newMethod); workingCopy.rewrite(clazz, copy); } @@ -240,7 +315,7 @@ */ public void test119048() throws Exception { testFile = new File(getWorkDir(), "Test.java"); - TestUtilities.copyStringToFile(testFile, + TestUtilities.copyStringToFile(testFile, "package javaapplication5;\n" + "\n" + "public class NewJFrame extends javax.swing.JFrame {\n" + @@ -255,7 +330,7 @@ DataObject dataObject = DataObject.find(FileUtil.toFileObject(testFile)); EditorCookie editorCookie = ((GuardedDataObject) dataObject).getCookie(EditorCookie.class); Document doc = editorCookie.openDocument(); - String golden = + String golden = "package javaapplication5;\n" + "\n" + "public class NewJFrame extends javax.swing.JFrame {\n" + @@ -267,7 +342,7 @@ " }//GEN-LAST:event_jButton1ActionPerformed\n" + "\n" + "}"; - + JavaSource src = getJavaSource(testFile); Task task = new Task() { @@ -293,13 +368,13 @@ System.err.println(res); assertEquals(golden, res); } - + /** * #119962: Guarded Exception */ public void test119962() throws Exception { testFile = new File(getWorkDir(), "Test.java"); - TestUtilities.copyStringToFile(testFile, + TestUtilities.copyStringToFile(testFile, "package test;\n" + "\n" + "public class NewJFrame extends javax.swing.JFrame {\n" + @@ -330,7 +405,7 @@ DataObject dataObject = DataObject.find(FileUtil.toFileObject(testFile)); EditorCookie editorCookie = ((GuardedDataObject) dataObject).getCookie(EditorCookie.class); Document doc = editorCookie.openDocument(); - String golden = + String golden = "package test;\n" + "\n" + "public class NewJFrame extends javax.swing.JFrame {\n" + @@ -360,7 +435,7 @@ " public void actionPerformed(ActionEvent e) {\n" + " }\n" + "}"; - + JavaSource src = getJavaSource(testFile); Task task = new Task() { @@ -377,14 +452,14 @@ Collections.singletonList( make.Variable( make.Modifiers(Collections.emptySet()), - "e", - make.Identifier("ActionEvent"), + "e", + make.Identifier("ActionEvent"), null) ), Collections.emptyList(), make.Block(Collections.emptyList(), false), null // default value - not applicable - ); + ); workingCopy.rewrite(clazz, make.addClassMember(clazz, newMethod)); } }; @@ -394,7 +469,7 @@ System.err.println(res); assertEquals(golden, res); } - + /** * #119345: Duplicated initComponents() when trying to rename in * the guarded. @@ -539,7 +614,7 @@ DataObject dataObject = DataObject.find(FileUtil.toFileObject(testFile)); EditorCookie editorCookie = ((GuardedDataObject) dataObject).getCookie(EditorCookie.class); Document doc = editorCookie.openDocument(); - String golden = + String golden = "package crystalball;\n" + "\n" + "import org.jdesktop.application.Action;\n" + @@ -673,7 +748,7 @@ " // End of variables declaration//GEN-END:variables\n" + " \n" + "}\n"; - + JavaSource src = getJavaSource(testFile); Task task = new Task() { @@ -694,7 +769,7 @@ mst = (MemberSelectTree) invocation.getArguments().get(0); mst = (MemberSelectTree) mst.getExpression(); workingCopy.rewrite(mst.getExpression(), make.Identifier("crystalball")); - + var = (VariableTree) stmts.get(16); invocation = (MethodInvocationTree) var.getInitializer(); mst = (MemberSelectTree) invocation.getArguments().get(0); @@ -713,10 +788,10 @@ System.err.println(res); assertEquals(golden, res); } - + public void testRenameTypeParameter125385() throws Exception { testFile = new File(getWorkDir(), "Test.java"); - TestUtilities.copyStringToFile(testFile, + TestUtilities.copyStringToFile(testFile, "package hierbas.del.litoral;\n" + "\n" + "public class MyList {\n" + @@ -733,12 +808,12 @@ " return null;\n" + " }\n" + "}\n"; - + DataObject dataObject = DataObject.find(FileUtil.toFileObject(testFile)); EditorCookie editorCookie = ((GuardedDataObject) dataObject).getCookie(EditorCookie.class); Document doc = editorCookie.openDocument(); JavaSource src = getJavaSource(testFile); - + Task task = new Task() { public void run(final WorkingCopy workingCopy) throws IOException { @@ -1008,7 +1083,7 @@ ((Environment) this.env).removeSaveCookie(); } - @Override + @Override protected CloneableEditor createCloneableEditor() { return new CloneableEditor(this); }