This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

Bug 158130 - Error in rewriting of BreakTree
Summary: Error in rewriting of BreakTree
Status: RESOLVED FIXED
Alias: None
Product: java
Classification: Unclassified
Component: Source (show other bugs)
Version: 6.x
Hardware: All All
: P3 blocker (vote)
Assignee: Rastislav Komara
URL:
Keywords: NETFIX
Depends on:
Blocks:
 
Reported: 2009-02-07 18:35 UTC by tronicek
Modified: 2009-08-19 09:39 UTC (History)
1 user (show)

See Also:
Issue Type: DEFECT
Exception Reporter:


Attachments
proposed fix and test cases (5.84 KB, patch)
2009-05-10 20:00 UTC, fommil
Details | Diff
(updated) proposed fix with test cases (5.85 KB, patch)
2009-05-10 20:15 UTC, fommil
Details | Diff
Added a new (failing) test case to the patch. (6.60 KB, text/plain)
2009-05-11 14:46 UTC, Jan Lahoda
Details
(updated) proposed fix with test cases (7.63 KB, patch)
2009-05-11 20:51 UTC, fommil
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description tronicek 2009-02-07 18:35:34 UTC
When I try to rewrite a BreakTree using the following statements, I get the NullPointerException.

            modified = make.Break(null);
            System.out.println("original: " + node);
            System.out.println("modified: " + modified);
            wc.rewrite(node, modified);

Example of input:

    void m(int p) {
        loop:
        while (true) {
            if (p == 0) break loop;
        }
    }

Output:

original: break loop;
modified: break;
SEVERE [global]
java.lang.NullPointerException
        at org.netbeans.modules.java.source.save.CasualDiff.nameChanged(CasualDiff.java:1795)
        at org.netbeans.modules.java.source.save.CasualDiff.diffBreak(CasualDiff.java:1038)
        at org.netbeans.modules.java.source.save.CasualDiff.diffTreeImpl(CasualDiff.java:2635)
        at org.netbeans.modules.java.source.save.CasualDiff.diffTree(CasualDiff.java:2536)
        at org.netbeans.modules.java.source.save.CasualDiff.diffTree(CasualDiff.java:2524)
        at org.netbeans.modules.java.source.save.CasualDiff.diffTree(CasualDiff.java:3066)
        at org.netbeans.modules.java.source.save.CasualDiff.diffIf(CasualDiff.java:1007)
        at org.netbeans.modules.java.source.save.CasualDiff.diffTreeImpl(CasualDiff.java:2629)
        at org.netbeans.modules.java.source.save.CasualDiff.diffTree(CasualDiff.java:2536)
        at org.netbeans.modules.java.source.save.CasualDiff.diff(CasualDiff.java:177)
        at org.netbeans.api.java.source.WorkingCopy.processCurrentCompilationUnit(WorkingCopy.java:441)
        at org.netbeans.api.java.source.WorkingCopy.getChanges(WorkingCopy.java:502)
        at org.netbeans.api.java.source.JavaSource$1.run(JavaSource.java:645)
        at org.netbeans.modules.parsing.api.ParserManager$UserTaskAction.run(ParserManager.java:123)
        at org.netbeans.modules.parsing.api.ParserManager$UserTaskAction.run(ParserManager.java:105)
        at org.netbeans.modules.parsing.impl.TaskProcessor.runUserTask(TaskProcessor.java:191)
        at org.netbeans.modules.parsing.api.ParserManager.parse(ParserManager.java:96)
        at org.netbeans.api.java.source.JavaSource.runModificationTask(JavaSource.java:657)
        at refactoring.RNGAction$1.performActionAt(RNGAction.java:132)
        at org.openide.awt.Actions$ISubActionListener.actionPerformed(Actions.java:1150)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1995)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2318)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:387)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:242)
        at javax.swing.AbstractButton.doClick(AbstractButton.java:357)
        at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:1170)
        at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:1211)
        at java.awt.Component.processMouseEvent(Component.java:6038)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3260)
        at java.awt.Component.processEvent(Component.java:5803)
        at java.awt.Container.processEvent(Container.java:2058)
        at java.awt.Component.dispatchEventImpl(Component.java:4410)
        at java.awt.Container.dispatchEventImpl(Container.java:2116)
        at java.awt.Component.dispatchEvent(Component.java:4240)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4322)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:3986)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:3916)
        at java.awt.Container.dispatchEventImpl(Container.java:2102)
        at java.awt.Window.dispatchEventImpl(Window.java:2429)
        at java.awt.Component.dispatchEvent(Component.java:4240)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
        at org.netbeans.core.TimableEventQueue.dispatchEvent(TimableEventQueue.java:104)
[catch] at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:273)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:183)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:173)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:168)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:160)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:121)

It doesn't like 'null'. These statements are performed in a right way:

            modified = make.Break("");
            System.out.println("original: " + node);
            System.out.println("modified: " + modified);
            wc.rewrite(node, modified);
Comment 1 Rastislav Komara 2009-02-16 10:34:31 UTC
.
Comment 2 tronicek 2009-03-09 22:11:48 UTC
The same holds true for ContinueTree.
Comment 3 fommil 2009-05-10 20:00:07 UTC
Created attachment 81864 [details]
proposed fix and test cases
Comment 4 fommil 2009-05-10 20:01:37 UTC
Simple fix proposed... the TreeFactory was setting the Name to null when it should have been using an empty Name.
Comment 5 fommil 2009-05-10 20:15:05 UTC
Created attachment 81865 [details]
(updated) proposed fix with test cases
Comment 6 Rastislav Komara 2009-05-11 12:33:40 UTC
Which one of proposed fixes should be used?
Comment 7 fommil 2009-05-11 12:35:21 UTC
the second one deprecates the first. There was a typo in the test case of the first (position of whitespace in the golden String).
Comment 8 Jan Lahoda 2009-05-11 14:08:59 UTC
Sorry, but I do not think that the proposed patch is correct. I think that the CasualDiff should be updated to handle
the null-valued label (either in old, new or both trees). The trees generally provide null value for "optional" features
that are missing in the source. In this case, if the break tree would be provided by the javac itself (e.g. an existing
piece of code from the source would be reused), the label would be null, IMO.
Comment 9 fommil 2009-05-11 14:13:22 UTC
@jlahoda note that the Javadoc for Name suggests that empty names should be zero-length. Using null to represent an empty (or missing) name is therefore 
non-standard. I can have a look at patching CasualDiff (this was actually my first line of investigation), but it will result in making quite a lot of code "null 
friendly", where it has safely assumed no nulls until now.
Comment 10 Jan Lahoda 2009-05-11 14:46:45 UTC
Created attachment 81899 [details]
Added a new (failing) test case to the patch.
Comment 11 Jan Lahoda 2009-05-11 14:48:23 UTC
I have attached a patch that contains an additional failing test case (testBreak158130b). I have accidentally left the
two original test cases disabled (X preprended), sorry.
Comment 12 fommil 2009-05-11 14:58:45 UTC
touché! I will investigate further. :-)
Comment 13 fommil 2009-05-11 20:51:54 UTC
Created attachment 81924 [details]
(updated) proposed fix with test cases
Comment 14 fommil 2009-05-11 20:53:58 UTC
Latest patch fixes the test case @jlahoda added. A fix was needed in VeryPretty as well as CasualDiff.

Note that the OR || I added in CasualDiff.nameChanged could just as easily be an XOR ^, but because the equality is explicitly checked in the previous logic 
test, I thought this was easier to read.
Comment 15 Jan Lahoda 2009-05-12 16:07:17 UTC
The change in the TreeFactory is not needed anymore, IMO.
Comment 16 Rastislav Komara 2009-05-22 10:24:09 UTC
ACCEPTED. 
Comment 17 Rastislav Komara 2009-05-22 15:21:01 UTC
jet-main #204b55f53241
Comment 18 Quality Engineering 2009-05-23 06:59:24 UTC
Integrated into 'main-golden', will be available in build *200905230201* on http://bits.netbeans.org/dev/nightly/ (upload may still be in progress)
Changeset: http://hg.netbeans.org/main-golden/rev/204b55f53241
User: Rastislav Komara <moonko@netbeans.org>
Log: #158130: Error in rewriting of BreakTree
Comment 19 Max Sauer 2009-08-19 09:39:18 UTC
I've removed the change in TreeFactory, it causes unnecessary spaces (break[ ];) in some cases. Covered by IntroduceHintTest.testIntroduceMethodFix10() 
and ...11().
---
http://hg.netbeans.org/jet-main/rev/aaddf888fab6