Tools__BreakpointService.st
changeset 14509 763bb2f56f2f
parent 14456 218e0f00e309
child 14510 5e9448af6e4f
equal deleted inserted replaced
14508:268012bb76c1 14509:763bb2f56f2f
    81     ^ self == Tools::BreakpointService
    81     ^ self == Tools::BreakpointService
    82 
    82 
    83     "Created: / 22-07-2013 / 14:01:17 / cg"
    83     "Created: / 22-07-2013 / 14:01:17 / cg"
    84 ! !
    84 ! !
    85 
    85 
       
    86 !BreakpointService methodsFor:'accessing'!
       
    87 
       
    88 breakpointAtLine:line
       
    89     |pos|
       
    90 
       
    91     breakpoints isNil ifTrue:[^ nil].
       
    92 
       
    93     pos := textView characterPositionOfLine:line col:1.
       
    94     ^ breakpoints 
       
    95         detect:[:each | each position = pos ] 
       
    96         ifNone:[ 
       
    97             breakpoints 
       
    98                 detect:[:each | each line == line and:[each position isNil ]] 
       
    99                 ifNone:[ nil ]
       
   100         ]
       
   101 
       
   102     "Modified: / 17-06-2011 / 13:59:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   103     "Modified (format): / 05-07-2011 / 21:33:23 / cg"
       
   104 !
       
   105 
       
   106 breakpoints
       
   107     "/ Fixup breakpoint positions
       
   108     self fixupBreakpointPositions.
       
   109     ^ breakpoints
       
   110 
       
   111     "Modified: / 08-05-2014 / 14:02:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   112 !
       
   113 
       
   114 removeAllBreakpoints
       
   115     breakpoints := OrderedCollection new.
       
   116 !
       
   117 
       
   118 setOrToggleBreakpointAtLine:line
       
   119     |pos bpnt prepareFullBreakSupport mClass ok|
       
   120 
       
   121     "/ if true, setting a single breakpoint in a method will create
       
   122     "/ a whole set of invisible (and disabled) breakpoints in that method,
       
   123     "/ one for each line.
       
   124     "/ These can later be enabled in the debugger
       
   125     "/ (otherwise, the debugger's behavior is stupid, as it cannot recompile a method
       
   126     "/ to set additional breakpoints).
       
   127     "/ We accept the additional overhead, as we are in debug mode anyway.
       
   128     "/ prepareFullBreakSupport := false.
       
   129     prepareFullBreakSupport := true.
       
   130 
       
   131     codeView method isNil ifTrue:[
       
   132         ^ self
       
   133     ].
       
   134 
       
   135     textView reallyModified ifTrue:[
       
   136         "/ leads to ugly behavior (method no longer found), if we allow
       
   137         "/ this...
       
   138         Dialog warn:'Please accept first (cannot set breakpoint while text is modified)'.
       
   139         ^ self
       
   140     ].
       
   141 
       
   142     bpnt := self breakpointAtLine:line.
       
   143     bpnt isNil ifTrue:[
       
   144         "/ no breakpoint there - create a new one as required (i.e. recompile)
       
   145         ok := (self canCreateOrToggleBreakpointAtLine:line).
       
   146         ok ifFalse:[
       
   147             (currentMethod isMethodWithBreakpoints and:[ prepareFullBreakSupport ]) ifFalse:[
       
   148                 codeView topView class == DebugView ifTrue:[
       
   149                     (Dialog 
       
   150                         confirm:'Sorry, in an active method, I can only add new breakpoints in an already breakpointed method.
       
   151 (i.e. a method stopped at a method breakpoint or one which already has statement breakpoints)
       
   152 The reason is that the method needs to be recompiled for the breakpoint, which would not affect the method being currently executed.
       
   153 
       
   154 You can proceed to set the breakpoint, but it will only affect the next call into this method, not the current invocation.'
       
   155                         yesLabel:'Set Breakpoint for Next Call' noLabel:'Ok') ifTrue:[
       
   156 self halt.
       
   157                             ok := true.
       
   158                         ]
       
   159                 ] ifFalse:[
       
   160                     Dialog warn:'Sorry, cannot add a new breakpoint here.'.
       
   161                 ].
       
   162             ]
       
   163         ].
       
   164         ok ifTrue:[
       
   165             prepareFullBreakSupport ifTrue:[
       
   166                 "/ add a (disabled) breakpoint for every source line. This
       
   167                 "/ allows for breakpoints to be enabled/disabled in the debugger...
       
   168                 1 to:textView numberOfLines do:[:eachLine |
       
   169                     |oldBPnt eachPos otherBpnt|
       
   170 
       
   171                     oldBPnt := self breakpointAtLine:eachLine.
       
   172                     oldBPnt isNil ifTrue:[
       
   173                         eachPos := textView characterPositionOfLine:eachLine col:1.
       
   174                         breakpoints isNil ifTrue:[ breakpoints := OrderedCollection new].
       
   175                         breakpoints add:((otherBpnt := Breakpoint new) position:eachPos line:eachLine).
       
   176                         eachLine == line ifTrue:[
       
   177                             bpnt := otherBpnt.
       
   178                         ] ifFalse:[
       
   179                             otherBpnt beInvisible.
       
   180                         ]
       
   181                     ].
       
   182                 ].
       
   183             ] ifFalse:[
       
   184                 pos := textView characterPositionOfLine:line col:1.
       
   185                 breakpoints add:((bpnt := Breakpoint new) position:pos line:line).
       
   186             ].
       
   187             Screen current shiftDown ifTrue:[
       
   188                 "/ trace
       
   189                 bpnt beTracepoint
       
   190             ].
       
   191             self assert: breakpoints notEmptyOrNil.
       
   192 
       
   193             "/ recompile the method with breakpoints
       
   194             self recompile.
       
   195         ]
       
   196     ] ifFalse:[
       
   197         "/ breakpoint already there - just enable/disable
       
   198         Screen current shiftDown ifTrue:[
       
   199             bpnt toggleTracing
       
   200         ] ifFalse:[
       
   201             bpnt toggle.
       
   202         ].
       
   203         (mClass := currentMethod mclass) isNil ifTrue:[
       
   204             "/ hack: ouch - was wrapped in the meantime;
       
   205             "/ hurry up and update. Should be done elsewhere (in codeView)
       
   206             self updateCurrentMethod.
       
   207             currentMethod notNil ifTrue:[ mClass := currentMethod mclass ].
       
   208         ].
       
   209         mClass notNil ifTrue:[
       
   210             Smalltalk changed:#methodTrap with:(MethodTrapChangeNotificationParameter changeClass:mClass changeSelector:currentMethod selector).
       
   211         ].
       
   212     ].
       
   213 
       
   214     (bpnt notNil and:[bpnt isReached not]) ifTrue:[
       
   215         | app |    
       
   216 
       
   217         app := codeView application.
       
   218         (app respondsTo: #showInfo:) ifTrue:[
       
   219             app showInfo: 'Cannot set breakpoint here, try another line...'.
       
   220         ].
       
   221         codeView flash.
       
   222     ] ifFalse:[
       
   223         gutterView redrawLine:line.
       
   224     ].
       
   225 
       
   226     "Created: / 17-06-2011 / 13:45:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   227     "Modified: / 28-08-2013 / 14:45:36 / cg"
       
   228     "Modified: / 21-02-2014 / 17:36:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   229 ! !
       
   230 
    86 !BreakpointService methodsFor:'change & update'!
   231 !BreakpointService methodsFor:'change & update'!
    87 
   232 
    88 update: aspect with: param from: sender
   233 update: aspect with: param from: sender
    89     aspect == #visibility ifTrue:[^ self].
   234     aspect == #visibility ifTrue:[^ self].
    90     aspect == #sizeOfView ifTrue:[^ self].
   235     aspect == #sizeOfView ifTrue:[^ self].
   270 
   415 
   271     "Created: / 17-06-2011 / 13:49:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   416     "Created: / 17-06-2011 / 13:49:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   272 ! !
   417 ! !
   273 
   418 
   274 !BreakpointService methodsFor:'private'!
   419 !BreakpointService methodsFor:'private'!
   275 
       
   276 breakpointAtLine:line
       
   277     |pos|
       
   278 
       
   279     breakpoints isNil ifTrue:[^ nil].
       
   280 
       
   281     pos := textView characterPositionOfLine:line col:1.
       
   282     ^ breakpoints 
       
   283         detect:[:each | each position = pos ] 
       
   284         ifNone:[ 
       
   285             breakpoints 
       
   286                 detect:[:each | each line == line and:[each position isNil ]] 
       
   287                 ifNone:[ nil ]
       
   288         ]
       
   289 
       
   290     "Modified: / 17-06-2011 / 13:59:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   291     "Modified (format): / 05-07-2011 / 21:33:23 / cg"
       
   292 !
       
   293 
       
   294 breakpoints
       
   295     "/ Fixup breakpoint positions
       
   296     self fixupBreakpointPositions.
       
   297     ^ breakpoints
       
   298 
       
   299     "Modified: / 08-05-2014 / 14:02:25 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   300 !
       
   301 
   420 
   302 fixupBreakpointPositions
   421 fixupBreakpointPositions
   303     breakpoints notEmptyOrNil ifTrue:[ 
   422     breakpoints notEmptyOrNil ifTrue:[ 
   304         breakpoints do:[:each |  
   423         breakpoints do:[:each |  
   305             | pos |
   424             | pos |
   428     ]
   547     ]
   429 
   548 
   430     "Created: / 05-07-2011 / 21:33:13 / cg"
   549     "Created: / 05-07-2011 / 21:33:13 / cg"
   431     "Modified: / 22-07-2013 / 16:00:13 / cg"
   550     "Modified: / 22-07-2013 / 16:00:13 / cg"
   432     "Modified: / 08-05-2014 / 14:03:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   551     "Modified: / 08-05-2014 / 14:03:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   433 !
       
   434 
       
   435 setOrToggleBreakpointAtLine:line
       
   436     |pos bpnt prepareFullBreakSupport mClass ok|
       
   437 
       
   438     "/ if true, setting a single breakpoint in a method will create
       
   439     "/ a whole set of invisible (and disabled) breakpoints in that method,
       
   440     "/ one for each line.
       
   441     "/ These can later be enabled in the debugger
       
   442     "/ (otherwise, the debugger's behavior is stupid, as it cannot recompile a method
       
   443     "/ to set additional breakpoints).
       
   444     "/ We accept the additional overhead, as we are in debug mode anyway.
       
   445     "/ prepareFullBreakSupport := false.
       
   446     prepareFullBreakSupport := true.
       
   447 
       
   448     codeView method isNil ifTrue:[
       
   449         ^ self
       
   450     ].
       
   451 
       
   452     textView reallyModified ifTrue:[
       
   453         "/ leads to ugly behavior (method no longer found), if we allow
       
   454         "/ this...
       
   455         Dialog warn:'Please accept first (cannot set breakpoint while text is modified)'.
       
   456         ^ self
       
   457     ].
       
   458 
       
   459     bpnt := self breakpointAtLine:line.
       
   460     bpnt isNil ifTrue:[
       
   461         "/ no breakpoint there - create a new one as required (i.e. recompile)
       
   462         ok := (self canCreateOrToggleBreakpointAtLine:line).
       
   463         ok ifFalse:[
       
   464             (currentMethod isMethodWithBreakpoints and:[ prepareFullBreakSupport ]) ifFalse:[
       
   465                 codeView topView class == DebugView ifTrue:[
       
   466                     (Dialog 
       
   467                         confirm:'Sorry, in an active method, I can only add new breakpoints in an already breakpointed method.
       
   468 (i.e. a method stopped at a method breakpoint or one which already has statement breakpoints)
       
   469 The reason is that the method needs to be recompiled for the breakpoint, which would not affect the method being currently executed.
       
   470 
       
   471 You can proceed to set the breakpoint, but it will only affect the next call into this method, not the current invocation.'
       
   472                         yesLabel:'Set Breakpoint for Next Call' noLabel:'Ok') ifTrue:[
       
   473 self halt.
       
   474                             ok := true.
       
   475                         ]
       
   476                 ] ifFalse:[
       
   477                     Dialog warn:'Sorry, cannot add a new breakpoint here.'.
       
   478                 ].
       
   479             ]
       
   480         ].
       
   481         ok ifTrue:[
       
   482             prepareFullBreakSupport ifTrue:[
       
   483                 "/ add a (disabled) breakpoint for every source line. This
       
   484                 "/ allows for breakpoints to be enabled/disabled in the debugger...
       
   485                 1 to:textView numberOfLines do:[:eachLine |
       
   486                     |oldBPnt eachPos otherBpnt|
       
   487 
       
   488                     oldBPnt := self breakpointAtLine:eachLine.
       
   489                     oldBPnt isNil ifTrue:[
       
   490                         eachPos := textView characterPositionOfLine:eachLine col:1.
       
   491                         breakpoints isNil ifTrue:[ breakpoints := OrderedCollection new].
       
   492                         breakpoints add:((otherBpnt := Breakpoint new) position:eachPos line:eachLine).
       
   493                         eachLine == line ifTrue:[
       
   494                             bpnt := otherBpnt.
       
   495                         ] ifFalse:[
       
   496                             otherBpnt beInvisible.
       
   497                         ]
       
   498                     ].
       
   499                 ].
       
   500             ] ifFalse:[
       
   501                 pos := textView characterPositionOfLine:line col:1.
       
   502                 breakpoints add:((bpnt := Breakpoint new) position:pos line:line).
       
   503             ].
       
   504             Screen current shiftDown ifTrue:[
       
   505                 "/ trace
       
   506                 bpnt beTracepoint
       
   507             ].
       
   508             self assert: breakpoints notEmptyOrNil.
       
   509 
       
   510             "/ recompile the method with breakpoints
       
   511             self recompile.
       
   512         ]
       
   513     ] ifFalse:[
       
   514         "/ breakpoint already there - just enable/disable
       
   515         Screen current shiftDown ifTrue:[
       
   516             bpnt toggleTracing
       
   517         ] ifFalse:[
       
   518             bpnt toggle.
       
   519         ].
       
   520         (mClass := currentMethod mclass) isNil ifTrue:[
       
   521             "/ hack: ouch - was wrapped in the meantime;
       
   522             "/ hurry up and update. Should be done elsewhere (in codeView)
       
   523             self updateCurrentMethod.
       
   524             currentMethod notNil ifTrue:[ mClass := currentMethod mclass ].
       
   525         ].
       
   526         mClass notNil ifTrue:[
       
   527             Smalltalk changed:#methodTrap with:(MethodTrapChangeNotificationParameter changeClass:mClass changeSelector:currentMethod selector).
       
   528         ].
       
   529     ].
       
   530 
       
   531     (bpnt notNil and:[bpnt isReached not]) ifTrue:[
       
   532         | app |    
       
   533 
       
   534         app := codeView application.
       
   535         (app respondsTo: #showInfo:) ifTrue:[
       
   536             app showInfo: 'Cannot set breakpoint here, try another line...'.
       
   537         ].
       
   538         codeView flash.
       
   539     ] ifFalse:[
       
   540         gutterView redrawLine:line.
       
   541     ].
       
   542 
       
   543     "Created: / 17-06-2011 / 13:45:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   544     "Modified: / 28-08-2013 / 14:45:36 / cg"
       
   545     "Modified: / 21-02-2014 / 17:36:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
       
   546 ! !
   552 ! !
   547 
   553 
   548 !BreakpointService methodsFor:'queries'!
   554 !BreakpointService methodsFor:'queries'!
   549 
   555 
   550 canCreateOrToggleBreakpointAtLine:lineOrNilForAnywhere
   556 canCreateOrToggleBreakpointAtLine:lineOrNilForAnywhere
   662 ! !
   668 ! !
   663 
   669 
   664 !BreakpointService class methodsFor:'documentation'!
   670 !BreakpointService class methodsFor:'documentation'!
   665 
   671 
   666 version
   672 version
   667     ^ '$Header: /cvs/stx/stx/libtool/Tools__BreakpointService.st,v 1.50 2014-06-05 13:56:42 vrany Exp $'
   673     ^ '$Header: /cvs/stx/stx/libtool/Tools__BreakpointService.st,v 1.51 2014-06-15 13:05:46 cg Exp $'
   668 !
   674 !
   669 
   675 
   670 version_CVS
   676 version_CVS
   671     ^ '$Header: /cvs/stx/stx/libtool/Tools__BreakpointService.st,v 1.50 2014-06-05 13:56:42 vrany Exp $'
   677     ^ '$Header: /cvs/stx/stx/libtool/Tools__BreakpointService.st,v 1.51 2014-06-15 13:05:46 cg Exp $'
   672 !
   678 !
   673 
   679 
   674 version_SVN
   680 version_SVN
   675     ^ '$Id: Tools__BreakpointService.st,v 1.50 2014-06-05 13:56:42 vrany Exp $'
   681     ^ '$Id: Tools__BreakpointService.st,v 1.51 2014-06-15 13:05:46 cg Exp $'
   676 ! !
   682 ! !
   677 
   683