Tools__BreakpointService.st
branchjv
changeset 13175 64da878033cc
parent 13173 e9da2324940d
parent 12976 d8aec7edf3d5
child 13180 64a4186ddfce
--- a/Tools__BreakpointService.st	Fri Jun 21 19:16:23 2013 +0100
+++ b/Tools__BreakpointService.st	Mon Jun 24 13:11:03 2013 +0100
@@ -195,8 +195,10 @@
 breakpointAtLine:line
     |pos|
 
+    breakpoints isNil ifTrue:[^ nil].
+
     pos := textView characterPositionOfLine:line col:1.
-    ^ breakpoints ? #() detect:[:each | each position = pos ] ifNone:[ nil ]
+    ^ breakpoints detect:[:each | each position = pos ] ifNone:[ nil ]
 
     "Modified: / 17-06-2011 / 13:59:17 / Jan Vrany <jan.vrany@fit.cvut.cz>"
     "Modified (format): / 05-07-2011 / 21:33:23 / cg"
@@ -226,82 +228,84 @@
 
     oldMethod := codeView methodHolder value.
     (oldMethod notNil and:[oldMethod hasPrimitiveCode not]) ifTrue:[
-	"/ be careful: if the text has been edited/modified, do not compile
-	textView modified ifTrue:[
-	    self breakPoint: #cg.
-	    self breakPoint: #jv.
-	    ^self.
-	] ifFalse:[
-	    "/ prepare to get reachable bpts
-	    breakpoints do:[:bp | bp isReached:false].
+        "/ be careful: if the text has been edited/modified, do not compile
+        textView modified ifTrue:[
+            self breakPoint: #cg.
+            self breakPoint: #jv.
+            ^self.
+        ] ifFalse:[
+            "/ prepare to get reachable bpts
+            breakpoints do:[:bp | bp isReached:false].
 
-	    class := oldMethod mclass.
-	    class isNil ifTrue:[
-		class := codeView classHolder value.
-		class isNil ifTrue:[
-		    self breakPoint:#jv.
-		    Dialog warn:'oops - lost the methods''s class'.
-		    ^ self.
-		]
-	    ].
-	    selector := oldMethod selector.
+            class := oldMethod mclass.
+            class isNil ifTrue:[
+                class := codeView classHolder value.
+                class isNil ifTrue:[
+                    self breakPoint:#jv.
+                    Dialog warn:'oops - lost the methods''s class'.
+                    ^ self.
+                ]
+            ].
+            selector := oldMethod selector.
 
-	    Class withoutUpdatingChangesDo:[
-		compiler := ByteCodeCompilerWithBreakpointSupport new.
-		compiler breakpoints:breakpoints.
-		compiler methodClass:MethodWithBreakpoints.
-		newMethod := compiler
-			    compile:oldMethod source
-			    forClass:class
-			    inCategory:oldMethod category
-			    notifying:nil
-			    install:false
-			    skipIfSame:false
-			    silent:true
-			    foldConstants:true
-			    ifFail:[ Transcript showCR:'BreakpointService: failed to recompile for breakpoint' ].
+            Class withoutUpdatingChangesDo:[
+                compiler := ByteCodeCompilerWithBreakpointSupport new.
+                compiler breakpoints:breakpoints.
+                compiler methodClass:MethodWithBreakpoints.
+                newMethod := compiler
+                            compile:oldMethod source
+                            forClass:class
+                            inCategory:oldMethod category
+                            notifying:nil
+                            install:false
+                            skipIfSame:false
+                            silent:true
+                            foldConstants:true
+                            ifFail:[ Transcript showCR:'BreakpointService: failed to recompile for breakpoint' ].
 
-		selector isNil ifTrue:[
-		    "/ May happen as the selector is not stored in the method but
-		    "/ searches through method's mclass methodDictionary.
-		    "/ Following should be save as breakpoint is not installed when
-		    "/ the code is modified...
-		    selector := compiler selector.
-		].
+                selector isNil ifTrue:[
+                    "/ May happen as the selector is not stored in the method but
+                    "/ searches through method's mclass methodDictionary.
+                    "/ Following should be save as breakpoint is not installed when
+                    "/ the code is modified...
+                    selector := compiler selector.
+                ].
 
-		oldMethod isWrapped ifTrue:[
-		    "/ update the wrapped method - do not install
-		    newMethod originalMethod: oldMethod originalMethod.
-		    oldMethod replaceOriginalMethodWith:newMethod.
-		] ifFalse:[
-		    "/ install
-		    newMethod originalMethod: oldMethod.
-		    (class primAddSelector: selector withMethod:newMethod) ifFalse:[
-			oldMethod mclass:class.
-			self breakPoint: #cg.
-			self breakPoint: #jv.
-			^ self
-		    ].
-		].
-		"/ must come indirectly!!
-		codeView methodHolder value:newMethod.
-		oldMethod mclass isNil ifTrue:[
-		    "/ although this is not strictly true, not doing this
-		    "/ would confuse a lot of other tools (such as the browser)
-		    oldMethod mclass:class.
-		].
-		class changed:#methodTrap with:selector. "/ tell browsers
-		Smalltalk changed:#methodTrap with:(MethodTrapChangeNotificationParameter changeClass:class changeSelector:selector).
-	    ].
+                oldMethod isWrapped ifTrue:[
+                    "/ update the wrapped method - do not install
+                    newMethod originalMethod: oldMethod originalMethod.
+                    oldMethod replaceOriginalMethodWith:newMethod.
+                ] ifFalse:[
+                    "/ install
+                    newMethod originalMethod: oldMethod.
+                    (class primAddSelector: selector withMethod:newMethod) ifFalse:[
+                        oldMethod mclass:class.
+                        self breakPoint: #cg.
+                        self breakPoint: #jv.
+                        ^ self
+                    ].
+                ].
 
-	    breakpoints := breakpoints
-			    select:[:bp |
-"/                                bp isReached ifFalse:[
-"/                                    "/ Transcript show:'remove unreached:'; showCR:bp
-"/                                ].
-				bp isReached
-			    ]
-	]
+                breakpoints := breakpoints
+                                select:[:bp |
+"/                                    bp isReached ifFalse:[ 
+"/                                        "/ Transcript show:'remove unreached:'; showCR:bp 
+"/                                    ].
+                                    bp isReached
+                                ].
+
+                "/ must update breakpoints BEFORE the following, because it leads to a change
+                "/ notification, which may clear the breakpoints collection!!
+                codeView methodHolder value:newMethod.
+                oldMethod mclass isNil ifTrue:[
+                    "/ although this is not strictly true, not doing this
+                    "/ would confuse a lot of other tools (such as the browser)
+                    oldMethod mclass:class.
+                ].
+                class changed:#methodTrap with:selector. "/ tell browsers
+                Smalltalk changed:#methodTrap with:(MethodTrapChangeNotificationParameter changeClass:class changeSelector:selector).
+            ].
+        ]
     ]
 
     "Created: / 05-07-2011 / 21:33:13 / cg"
@@ -338,64 +342,67 @@
     prepareFullBreakSupport := true.
 
     textView reallyModified ifTrue:[
-	"/ leads to ugly behavior (method no longer found), if we allow
-	"/ this...
-	  Dialog warn:'Please accept first (cannot set breakpoint while text is modified)'.
-	^ self
+        "/ leads to ugly behavior (method no longer found), if we allow
+        "/ this...
+          Dialog warn:'Please accept first (cannot set breakpoint while text is modified)'.
+        ^ self
     ].
 
     pos := textView characterPositionOfLine:line col:1.
     bpnt := self breakpointAtLine:line.
     bpnt isNil ifTrue:[
-	"/ no breakpoint there - add as required
-	(self canCreateOrToggleBreakpointAtLine:line) ifTrue:[
-	    prepareFullBreakSupport ifTrue:[
-		"/ add a (disabled) breakpoint for every source line. This
-		"/ allows for breakpoints to be enabled/disabled in the debugger...
-		1 to:textView numberOfLines do:[:eachLine |
-		    |oldBPnt eachPos otherBpnt|
+        "/ no breakpoint there - add as required
+        (self canCreateOrToggleBreakpointAtLine:line) ifTrue:[
+            prepareFullBreakSupport ifTrue:[
+                "/ add a (disabled) breakpoint for every source line. This
+                "/ allows for breakpoints to be enabled/disabled in the debugger...
+                1 to:textView numberOfLines do:[:eachLine |
+                    |oldBPnt eachPos otherBpnt|
 
-		    oldBPnt := self breakpointAtLine:eachLine.
-		    oldBPnt isNil ifTrue:[
-			eachPos := textView characterPositionOfLine:eachLine col:1.
-			breakpoints isNil ifTrue:[ breakpoints := OrderedCollection new].
-			breakpoints add:((otherBpnt := Breakpoint new) position:eachPos line:eachLine).
-			eachLine == line ifTrue:[
-			    bpnt := otherBpnt.
-			] ifFalse:[
-			    otherBpnt beInvisible.
-			]
-		    ].
-		].
-	    ] ifFalse:[
-		breakpoints add:((bpnt := Breakpoint new) position:pos line:line).
-	    ].
-	    Display shiftDown ifTrue:[
-		"/ trace
-		bpnt beTracepoint
-	    ].
-	    self recompile.
-	] ifFalse:[
-	    codeView topView class == DebugView ifTrue:[
-		Dialog warn:'Sorry, can only add a new breakpoint in an already breakpointed method.'.
-		"/ Dialog warn:'Sorry, can only add a new breakpoint in a wrapped method which has not yet started.'.
-	    ] ifFalse:[
-		Dialog warn:'Sorry, cannot add a new breakpoint here.'.
-	    ].
-	]
+                    oldBPnt := self breakpointAtLine:eachLine.
+                    oldBPnt isNil ifTrue:[
+                        eachPos := textView characterPositionOfLine:eachLine col:1.
+                        breakpoints isNil ifTrue:[ breakpoints := OrderedCollection new].
+                        breakpoints add:((otherBpnt := Breakpoint new) position:eachPos line:eachLine).
+                        eachLine == line ifTrue:[
+                            bpnt := otherBpnt.
+                        ] ifFalse:[
+                            otherBpnt beInvisible.
+                        ]
+                    ].
+                ].
+            ] ifFalse:[
+                breakpoints add:((bpnt := Breakpoint new) position:pos line:line).
+            ].
+            Display shiftDown ifTrue:[
+                "/ trace
+                bpnt beTracepoint
+            ].
+            self assert: breakpoints notEmptyOrNil.
+            self recompile.
+        ] ifFalse:[
+            codeView topView class == DebugView ifTrue:[
+                Dialog warn:'Sorry, in an active method, I can only add new breakpoints in an already breakpointed method.
+(i.e. a method stopped at a method breakpoint or one which already has statement breakpoints)
+The reason is that the method needs to be recompiled for the breakpoint, which would not affect the currently executed method.'.
+                "/ Dialog warn:'Sorry, can only add a new breakpoint in a wrapped method which has not yet started.'.
+            ] ifFalse:[
+                Dialog warn:'Sorry, cannot add a new breakpoint here.'.
+            ].
+        ]
     ] ifFalse:[
-	"/ breakpoint already there - just enable/disable
-	Display shiftDown ifTrue:[
-	    bpnt toggleTracing
-	] ifFalse:[
-	    bpnt toggle.
-	].
-	currentMethod mclass isNil ifTrue:[
-	    "/ hack: ouch - was wrapped in the meantime;
-	    "/ hurry up and update. Should be done elsewhere (in codeView)
-	    self updateCurrentMethod.
-	].
-	Smalltalk changed:#methodTrap with:(MethodTrapChangeNotificationParameter changeClass:currentMethod mclass changeSelector:currentMethod selector).
+        "/ breakpoint already there - just enable/disable
+        Display shiftDown ifTrue:[
+            bpnt toggleTracing
+        ] ifFalse:[
+            bpnt toggle.
+        ].
+        currentMethod mclass isNil ifTrue:[
+            "/ hack: ouch - was wrapped in the meantime;
+            "/ hurry up and update. Should be done elsewhere (in codeView)
+            self updateCurrentMethod.
+        ].
+        Smalltalk changed:#methodTrap with:(MethodTrapChangeNotificationParameter changeClass:currentMethod mclass changeSelector:currentMethod selector).
     ].
 
     gutterView redrawLine:line.
@@ -500,11 +507,11 @@
 !BreakpointService class methodsFor:'documentation'!
 
 version
-    ^ '$Header: /cvs/stx/stx/libtool/Tools__BreakpointService.st,v 1.23 2013-06-20 23:21:35 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libtool/Tools__BreakpointService.st,v 1.25 2013-06-23 08:26:25 cg Exp $'
 !
 
 version_CVS
-    ^ '$Header: /cvs/stx/stx/libtool/Tools__BreakpointService.st,v 1.23 2013-06-20 23:21:35 cg Exp $'
+    ^ '$Header: /cvs/stx/stx/libtool/Tools__BreakpointService.st,v 1.25 2013-06-23 08:26:25 cg Exp $'
 !
 
 version_HG
@@ -513,5 +520,6 @@
 !
 
 version_SVN
-    ^ '$Id: Tools__BreakpointService.st,v 1.23 2013-06-20 23:21:35 cg Exp $'
+    ^ '$Id: Tools__BreakpointService.st,v 1.25 2013-06-23 08:26:25 cg Exp $'
 ! !
+