Tools__BreakpointService.st
branchjv
changeset 13175 64da878033cc
parent 13173 e9da2324940d
parent 12976 d8aec7edf3d5
child 13180 64a4186ddfce
equal deleted inserted replaced
13174:45662685c220 13175:64da878033cc
   193 !BreakpointService methodsFor:'private'!
   193 !BreakpointService methodsFor:'private'!
   194 
   194 
   195 breakpointAtLine:line
   195 breakpointAtLine:line
   196     |pos|
   196     |pos|
   197 
   197 
       
   198     breakpoints isNil ifTrue:[^ nil].
       
   199 
   198     pos := textView characterPositionOfLine:line col:1.
   200     pos := textView characterPositionOfLine:line col:1.
   199     ^ breakpoints ? #() detect:[:each | each position = pos ] ifNone:[ nil ]
   201     ^ breakpoints detect:[:each | each position = pos ] ifNone:[ nil ]
   200 
   202 
   201     "Modified: / 17-06-2011 / 13:59:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   203     "Modified: / 17-06-2011 / 13:59:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   202     "Modified (format): / 05-07-2011 / 21:33:23 / cg"
   204     "Modified (format): / 05-07-2011 / 21:33:23 / cg"
   203 !
   205 !
   204 
   206 
   224 
   226 
   225     |oldMethod newMethod compiler class selector|
   227     |oldMethod newMethod compiler class selector|
   226 
   228 
   227     oldMethod := codeView methodHolder value.
   229     oldMethod := codeView methodHolder value.
   228     (oldMethod notNil and:[oldMethod hasPrimitiveCode not]) ifTrue:[
   230     (oldMethod notNil and:[oldMethod hasPrimitiveCode not]) ifTrue:[
   229 	"/ be careful: if the text has been edited/modified, do not compile
   231         "/ be careful: if the text has been edited/modified, do not compile
   230 	textView modified ifTrue:[
   232         textView modified ifTrue:[
   231 	    self breakPoint: #cg.
   233             self breakPoint: #cg.
   232 	    self breakPoint: #jv.
   234             self breakPoint: #jv.
   233 	    ^self.
   235             ^self.
   234 	] ifFalse:[
   236         ] ifFalse:[
   235 	    "/ prepare to get reachable bpts
   237             "/ prepare to get reachable bpts
   236 	    breakpoints do:[:bp | bp isReached:false].
   238             breakpoints do:[:bp | bp isReached:false].
   237 
   239 
   238 	    class := oldMethod mclass.
   240             class := oldMethod mclass.
   239 	    class isNil ifTrue:[
   241             class isNil ifTrue:[
   240 		class := codeView classHolder value.
   242                 class := codeView classHolder value.
   241 		class isNil ifTrue:[
   243                 class isNil ifTrue:[
   242 		    self breakPoint:#jv.
   244                     self breakPoint:#jv.
   243 		    Dialog warn:'oops - lost the methods''s class'.
   245                     Dialog warn:'oops - lost the methods''s class'.
   244 		    ^ self.
   246                     ^ self.
   245 		]
   247                 ]
   246 	    ].
   248             ].
   247 	    selector := oldMethod selector.
   249             selector := oldMethod selector.
   248 
   250 
   249 	    Class withoutUpdatingChangesDo:[
   251             Class withoutUpdatingChangesDo:[
   250 		compiler := ByteCodeCompilerWithBreakpointSupport new.
   252                 compiler := ByteCodeCompilerWithBreakpointSupport new.
   251 		compiler breakpoints:breakpoints.
   253                 compiler breakpoints:breakpoints.
   252 		compiler methodClass:MethodWithBreakpoints.
   254                 compiler methodClass:MethodWithBreakpoints.
   253 		newMethod := compiler
   255                 newMethod := compiler
   254 			    compile:oldMethod source
   256                             compile:oldMethod source
   255 			    forClass:class
   257                             forClass:class
   256 			    inCategory:oldMethod category
   258                             inCategory:oldMethod category
   257 			    notifying:nil
   259                             notifying:nil
   258 			    install:false
   260                             install:false
   259 			    skipIfSame:false
   261                             skipIfSame:false
   260 			    silent:true
   262                             silent:true
   261 			    foldConstants:true
   263                             foldConstants:true
   262 			    ifFail:[ Transcript showCR:'BreakpointService: failed to recompile for breakpoint' ].
   264                             ifFail:[ Transcript showCR:'BreakpointService: failed to recompile for breakpoint' ].
   263 
   265 
   264 		selector isNil ifTrue:[
   266                 selector isNil ifTrue:[
   265 		    "/ May happen as the selector is not stored in the method but
   267                     "/ May happen as the selector is not stored in the method but
   266 		    "/ searches through method's mclass methodDictionary.
   268                     "/ searches through method's mclass methodDictionary.
   267 		    "/ Following should be save as breakpoint is not installed when
   269                     "/ Following should be save as breakpoint is not installed when
   268 		    "/ the code is modified...
   270                     "/ the code is modified...
   269 		    selector := compiler selector.
   271                     selector := compiler selector.
   270 		].
   272                 ].
   271 
   273 
   272 		oldMethod isWrapped ifTrue:[
   274                 oldMethod isWrapped ifTrue:[
   273 		    "/ update the wrapped method - do not install
   275                     "/ update the wrapped method - do not install
   274 		    newMethod originalMethod: oldMethod originalMethod.
   276                     newMethod originalMethod: oldMethod originalMethod.
   275 		    oldMethod replaceOriginalMethodWith:newMethod.
   277                     oldMethod replaceOriginalMethodWith:newMethod.
   276 		] ifFalse:[
   278                 ] ifFalse:[
   277 		    "/ install
   279                     "/ install
   278 		    newMethod originalMethod: oldMethod.
   280                     newMethod originalMethod: oldMethod.
   279 		    (class primAddSelector: selector withMethod:newMethod) ifFalse:[
   281                     (class primAddSelector: selector withMethod:newMethod) ifFalse:[
   280 			oldMethod mclass:class.
   282                         oldMethod mclass:class.
   281 			self breakPoint: #cg.
   283                         self breakPoint: #cg.
   282 			self breakPoint: #jv.
   284                         self breakPoint: #jv.
   283 			^ self
   285                         ^ self
   284 		    ].
   286                     ].
   285 		].
   287                 ].
   286 		"/ must come indirectly!!
   288 
   287 		codeView methodHolder value:newMethod.
   289                 breakpoints := breakpoints
   288 		oldMethod mclass isNil ifTrue:[
   290                                 select:[:bp |
   289 		    "/ although this is not strictly true, not doing this
   291 "/                                    bp isReached ifFalse:[ 
   290 		    "/ would confuse a lot of other tools (such as the browser)
   292 "/                                        "/ Transcript show:'remove unreached:'; showCR:bp 
   291 		    oldMethod mclass:class.
   293 "/                                    ].
   292 		].
   294                                     bp isReached
   293 		class changed:#methodTrap with:selector. "/ tell browsers
   295                                 ].
   294 		Smalltalk changed:#methodTrap with:(MethodTrapChangeNotificationParameter changeClass:class changeSelector:selector).
   296 
   295 	    ].
   297                 "/ must update breakpoints BEFORE the following, because it leads to a change
   296 
   298                 "/ notification, which may clear the breakpoints collection!!
   297 	    breakpoints := breakpoints
   299                 codeView methodHolder value:newMethod.
   298 			    select:[:bp |
   300                 oldMethod mclass isNil ifTrue:[
   299 "/                                bp isReached ifFalse:[
   301                     "/ although this is not strictly true, not doing this
   300 "/                                    "/ Transcript show:'remove unreached:'; showCR:bp
   302                     "/ would confuse a lot of other tools (such as the browser)
   301 "/                                ].
   303                     oldMethod mclass:class.
   302 				bp isReached
   304                 ].
   303 			    ]
   305                 class changed:#methodTrap with:selector. "/ tell browsers
   304 	]
   306                 Smalltalk changed:#methodTrap with:(MethodTrapChangeNotificationParameter changeClass:class changeSelector:selector).
       
   307             ].
       
   308         ]
   305     ]
   309     ]
   306 
   310 
   307     "Created: / 05-07-2011 / 21:33:13 / cg"
   311     "Created: / 05-07-2011 / 21:33:13 / cg"
   308     "Modified: / 18-07-2012 / 10:53:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   312     "Modified: / 18-07-2012 / 10:53:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   309     "Modified: / 02-08-2012 / 09:35:41 / cg"
   313     "Modified: / 02-08-2012 / 09:35:41 / cg"
   336     "/ We accept the additional overhead, as we are in debug mode anyway.
   340     "/ We accept the additional overhead, as we are in debug mode anyway.
   337     "/ prepareFullBreakSupport := false.
   341     "/ prepareFullBreakSupport := false.
   338     prepareFullBreakSupport := true.
   342     prepareFullBreakSupport := true.
   339 
   343 
   340     textView reallyModified ifTrue:[
   344     textView reallyModified ifTrue:[
   341 	"/ leads to ugly behavior (method no longer found), if we allow
   345         "/ leads to ugly behavior (method no longer found), if we allow
   342 	"/ this...
   346         "/ this...
   343 	  Dialog warn:'Please accept first (cannot set breakpoint while text is modified)'.
   347           Dialog warn:'Please accept first (cannot set breakpoint while text is modified)'.
   344 	^ self
   348         ^ self
   345     ].
   349     ].
   346 
   350 
   347     pos := textView characterPositionOfLine:line col:1.
   351     pos := textView characterPositionOfLine:line col:1.
   348     bpnt := self breakpointAtLine:line.
   352     bpnt := self breakpointAtLine:line.
   349     bpnt isNil ifTrue:[
   353     bpnt isNil ifTrue:[
   350 	"/ no breakpoint there - add as required
   354         "/ no breakpoint there - add as required
   351 	(self canCreateOrToggleBreakpointAtLine:line) ifTrue:[
   355         (self canCreateOrToggleBreakpointAtLine:line) ifTrue:[
   352 	    prepareFullBreakSupport ifTrue:[
   356             prepareFullBreakSupport ifTrue:[
   353 		"/ add a (disabled) breakpoint for every source line. This
   357                 "/ add a (disabled) breakpoint for every source line. This
   354 		"/ allows for breakpoints to be enabled/disabled in the debugger...
   358                 "/ allows for breakpoints to be enabled/disabled in the debugger...
   355 		1 to:textView numberOfLines do:[:eachLine |
   359                 1 to:textView numberOfLines do:[:eachLine |
   356 		    |oldBPnt eachPos otherBpnt|
   360                     |oldBPnt eachPos otherBpnt|
   357 
   361 
   358 		    oldBPnt := self breakpointAtLine:eachLine.
   362                     oldBPnt := self breakpointAtLine:eachLine.
   359 		    oldBPnt isNil ifTrue:[
   363                     oldBPnt isNil ifTrue:[
   360 			eachPos := textView characterPositionOfLine:eachLine col:1.
   364                         eachPos := textView characterPositionOfLine:eachLine col:1.
   361 			breakpoints isNil ifTrue:[ breakpoints := OrderedCollection new].
   365                         breakpoints isNil ifTrue:[ breakpoints := OrderedCollection new].
   362 			breakpoints add:((otherBpnt := Breakpoint new) position:eachPos line:eachLine).
   366                         breakpoints add:((otherBpnt := Breakpoint new) position:eachPos line:eachLine).
   363 			eachLine == line ifTrue:[
   367                         eachLine == line ifTrue:[
   364 			    bpnt := otherBpnt.
   368                             bpnt := otherBpnt.
   365 			] ifFalse:[
   369                         ] ifFalse:[
   366 			    otherBpnt beInvisible.
   370                             otherBpnt beInvisible.
   367 			]
   371                         ]
   368 		    ].
   372                     ].
   369 		].
   373                 ].
   370 	    ] ifFalse:[
   374             ] ifFalse:[
   371 		breakpoints add:((bpnt := Breakpoint new) position:pos line:line).
   375                 breakpoints add:((bpnt := Breakpoint new) position:pos line:line).
   372 	    ].
   376             ].
   373 	    Display shiftDown ifTrue:[
   377             Display shiftDown ifTrue:[
   374 		"/ trace
   378                 "/ trace
   375 		bpnt beTracepoint
   379                 bpnt beTracepoint
   376 	    ].
   380             ].
   377 	    self recompile.
   381             self assert: breakpoints notEmptyOrNil.
   378 	] ifFalse:[
   382             self recompile.
   379 	    codeView topView class == DebugView ifTrue:[
   383         ] ifFalse:[
   380 		Dialog warn:'Sorry, can only add a new breakpoint in an already breakpointed method.'.
   384             codeView topView class == DebugView ifTrue:[
   381 		"/ Dialog warn:'Sorry, can only add a new breakpoint in a wrapped method which has not yet started.'.
   385                 Dialog warn:'Sorry, in an active method, I can only add new breakpoints in an already breakpointed method.
   382 	    ] ifFalse:[
   386 (i.e. a method stopped at a method breakpoint or one which already has statement breakpoints)
   383 		Dialog warn:'Sorry, cannot add a new breakpoint here.'.
   387 The reason is that the method needs to be recompiled for the breakpoint, which would not affect the currently executed method.'.
   384 	    ].
   388                 "/ Dialog warn:'Sorry, can only add a new breakpoint in a wrapped method which has not yet started.'.
   385 	]
   389             ] ifFalse:[
       
   390                 Dialog warn:'Sorry, cannot add a new breakpoint here.'.
       
   391             ].
       
   392         ]
   386     ] ifFalse:[
   393     ] ifFalse:[
   387 	"/ breakpoint already there - just enable/disable
   394         "/ breakpoint already there - just enable/disable
   388 	Display shiftDown ifTrue:[
   395         Display shiftDown ifTrue:[
   389 	    bpnt toggleTracing
   396             bpnt toggleTracing
   390 	] ifFalse:[
   397         ] ifFalse:[
   391 	    bpnt toggle.
   398             bpnt toggle.
   392 	].
   399         ].
   393 	currentMethod mclass isNil ifTrue:[
   400         currentMethod mclass isNil ifTrue:[
   394 	    "/ hack: ouch - was wrapped in the meantime;
   401             "/ hack: ouch - was wrapped in the meantime;
   395 	    "/ hurry up and update. Should be done elsewhere (in codeView)
   402             "/ hurry up and update. Should be done elsewhere (in codeView)
   396 	    self updateCurrentMethod.
   403             self updateCurrentMethod.
   397 	].
   404         ].
   398 	Smalltalk changed:#methodTrap with:(MethodTrapChangeNotificationParameter changeClass:currentMethod mclass changeSelector:currentMethod selector).
   405         Smalltalk changed:#methodTrap with:(MethodTrapChangeNotificationParameter changeClass:currentMethod mclass changeSelector:currentMethod selector).
   399     ].
   406     ].
   400 
   407 
   401     gutterView redrawLine:line.
   408     gutterView redrawLine:line.
   402 
   409 
   403     "Created: / 17-06-2011 / 13:45:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   410     "Created: / 17-06-2011 / 13:45:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
   498 ! !
   505 ! !
   499 
   506 
   500 !BreakpointService class methodsFor:'documentation'!
   507 !BreakpointService class methodsFor:'documentation'!
   501 
   508 
   502 version
   509 version
   503     ^ '$Header: /cvs/stx/stx/libtool/Tools__BreakpointService.st,v 1.23 2013-06-20 23:21:35 cg Exp $'
   510     ^ '$Header: /cvs/stx/stx/libtool/Tools__BreakpointService.st,v 1.25 2013-06-23 08:26:25 cg Exp $'
   504 !
   511 !
   505 
   512 
   506 version_CVS
   513 version_CVS
   507     ^ '$Header: /cvs/stx/stx/libtool/Tools__BreakpointService.st,v 1.23 2013-06-20 23:21:35 cg Exp $'
   514     ^ '$Header: /cvs/stx/stx/libtool/Tools__BreakpointService.st,v 1.25 2013-06-23 08:26:25 cg Exp $'
   508 !
   515 !
   509 
   516 
   510 version_HG
   517 version_HG
   511 
   518 
   512     ^ '$Changeset: <not expanded> $'
   519     ^ '$Changeset: <not expanded> $'
   513 !
   520 !
   514 
   521 
   515 version_SVN
   522 version_SVN
   516     ^ '$Id: Tools__BreakpointService.st,v 1.23 2013-06-20 23:21:35 cg Exp $'
   523     ^ '$Id: Tools__BreakpointService.st,v 1.25 2013-06-23 08:26:25 cg Exp $'
   517 ! !
   524 ! !
       
   525