2929import com .sun .jdi .AbsentInformationException ;
3030import com .sun .jdi .Location ;
3131import com .sun .jdi .ReferenceType ;
32+ import com .sun .jdi .VMDisconnectedException ;
3233import com .sun .jdi .request .BreakpointRequest ;
3334
3435
@@ -40,7 +41,7 @@ public class LineBreakpoint implements ClassLoadListener {
4041 protected Debugger dbg ; // the debugger
4142 protected LineID line ; // the line this breakpoint is set on
4243 protected BreakpointRequest bpr ; // the request on the VM's event request manager
43- protected ReferenceType theClass ; // the class containing this breakpoint, null when not yet loaded
44+ protected String className ;
4445
4546
4647 /**
@@ -56,9 +57,9 @@ public LineBreakpoint(LineID line, Debugger dbg) {
5657 this .line = line ;
5758 line .startTracking (dbg .getEditor ().getTab (line .fileName ()).getDocument ());
5859 this .dbg = dbg ;
59- theClass = dbg . getClass ( className ()); // try to get the class immediately, may return null if not yet loaded
60+ this . className = className ();
6061 set (); // activate the breakpoint (show highlight, attach if debugger is running)
61- Messages .log ("LBP Created " + toString () + " class: " + className () );
62+ Messages .log ("LBP Created " + toString () + " class: " + this . className );
6263 }
6364
6465
@@ -94,48 +95,61 @@ public boolean isOnLine(LineID testLine) {
9495 /**
9596 * Attach this breakpoint to the VM. Creates and enables a
9697 * {@link BreakpointRequest}. VM needs to be paused.
98+ *
99+ * @param theClass class to attach to
100+ * @return true on success
97101 */
98- protected void attach () {
99- if (!dbg .isPaused ()) {
100- log ("can't attach breakpoint, debugger not paused" );
101- return ;
102+ protected boolean attach (ReferenceType theClass ) {
103+
104+ if (theClass == null || className == null ||
105+ !className .equals (parseTopLevelClassName (theClass .name ()))) {
106+ return false ;
102107 }
103108
104- if (theClass == null ) {
105- log ("can't attach breakpoint, class not loaded: " + className ());
106- return ;
109+ log ("trying to attach: " + line .fileName + ":" + line .lineIdx + " to " + theClass .name ());
110+
111+ if (!dbg .isPaused ()) {
112+ log ("can't attach breakpoint, debugger not paused" );
113+ return false ;
107114 }
108115
109116 // find line in java space
110117 LineID javaLine = dbg .sketchToJavaLine (line );
111118 if (javaLine == null ) {
112119 log ("couldn't find line " + line + " in the java code" );
113- return ;
120+ return false ;
114121 }
115122 try {
116123 log ("BPs of class: " + theClass + ", line " + (javaLine .lineIdx () + 1 ));
117124 List <Location > locations = theClass .locationsOfLine (javaLine .lineIdx () + 1 );
118125 if (locations .isEmpty ()) {
119126 log ("no location found for line " + line + " -> " + javaLine );
120- return ;
127+ return false ;
121128 }
122129 // use first found location
123130 bpr = dbg .vm ().eventRequestManager ().createBreakpointRequest (locations .get (0 ));
124131 bpr .enable ();
125132 log ("attached breakpoint to " + line + " -> " + javaLine );
133+ return true ;
126134 } catch (AbsentInformationException ex ) {
127135 Messages .loge (null , ex );
128136 }
137+ return false ;
129138 }
130139
140+ protected boolean isAttached () {
141+ return bpr != null ;
142+ }
131143
132144 /**
133145 * Detach this breakpoint from the VM. Deletes the
134146 * {@link BreakpointRequest}.
135147 */
136- protected void detach () {
148+ public void detach () {
137149 if (bpr != null ) {
138- dbg .vm ().eventRequestManager ().deleteEventRequest (bpr );
150+ try {
151+ dbg .vm ().eventRequestManager ().deleteEventRequest (bpr );
152+ } catch (VMDisconnectedException ignore ) { }
139153 bpr = null ;
140154 }
141155 }
@@ -148,9 +162,11 @@ protected void detach() {
148162 protected void set () {
149163 dbg .addClassLoadListener (this ); // class may not yet be loaded
150164 dbg .getEditor ().addBreakpointedLine (line );
151- if (theClass != null && dbg .isPaused ()) { // class is loaded
152- // immediately activate the breakpoint
153- attach ();
165+ if (className != null && dbg .isPaused ()) { // debugging right now, try to attach
166+ for (ReferenceType rt : dbg .getClasses ()) {
167+ // try to attach to all top level or nested classes
168+ if (attach (rt )) break ;
169+ }
154170 }
155171 if (dbg .getEditor ().isInCurrentTab (line )) {
156172 dbg .getEditor ().getSketch ().setModified (true );
@@ -191,12 +207,7 @@ public String toString() {
191207 protected String className () {
192208 if (line .fileName ().endsWith (".pde" )) {
193209 // standard tab
194- ReferenceType mainClass = dbg .getMainClass ();
195- //System.out.println(dbg.getMainClass().name());
196- if (mainClass == null ) {
197- return null ;
198- }
199- return dbg .getMainClass ().name ();
210+ return dbg .getEditor ().getSketch ().getName ();
200211 }
201212
202213 if (line .fileName ().endsWith (".java" )) {
@@ -215,17 +226,18 @@ protected String className() {
215226 */
216227 @ Override
217228 public void classLoaded (ReferenceType theClass ) {
218- // check if our class is being loaded
219- Messages .log ("Class Loaded: " + theClass .name ());
220- if (theClass .name ().equals (className ())) {
221- this .theClass = theClass ;
222- attach ();
223- }
224- for (ReferenceType ct : theClass .nestedTypes ()) {
225- Messages .log ("Nested " + ct .name ());
229+ if (!isAttached ()) {
230+ // try to attach
231+ attach (theClass );
226232 }
227233 }
228234
235+ public String parseTopLevelClassName (String name ) {
236+ // Get rid of nested class name
237+ int dollar = name .indexOf ('$' );
238+ return (dollar == -1 ) ? name : name .substring (0 , dollar );
239+ }
240+
229241
230242 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
231243
0 commit comments