Skip to content

Commit

Permalink
Merge pull request #697 from adri09070/debug-point-browser-integration
Browse files Browse the repository at this point in the history
Debug Point Browser integration
  • Loading branch information
Ducasse authored Mar 15, 2024
2 parents 1cbb5a8 + 6e09e48 commit 937a4e9
Show file tree
Hide file tree
Showing 53 changed files with 2,068 additions and 8 deletions.
48 changes: 48 additions & 0 deletions docs/debug-points-browser.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# Debug Points Browser

The debug points browser is a new tool to visualize and configure existing debug points.
Full details on the new debug points model are [described here](https://github.com/pharo-project/pharo/blob/Pharo12/doc/DebugPoints/debug-points.md)

The tool can be opened via the `Debug > Debug Point Browser` world menu and looks like that:

![Opening Debug Point Browser via the World menu](https://github.com/pharo-spec/NewTools/assets/97704417/1cacd05d-f459-4a5c-bd9e-6587a89d6a95)

On the top-left, a table allows to visualize all debug points (breakpoints/watchpoints/basic debug points/etc.)
Each debug point has a name, which we could assimilate to a tag, that can be edited directly in this table.
The "enabled" state of the debug point is also displayed via a checkbox, as well as the scope of the debug point (class or object).

All behaviors of the selected can be configured via the right pane of debug point browser

When a debug point is selected, according to the target of the debug point, different information are displayed.
If the target is an AST node, the code of the concerned method is displayed (as in the screenshot above), while highlighting the corresponding code
If the target is an instance variable, all concerned methods are listed and selecting a method displays the corresponding code and highlights the correct variable accesses:

![image](https://github.com/pharo-spec/NewTools/assets/97704417/4c746e55-c50b-4a0f-97a6-9812acb5ca57)

Also, if the target is an instance variable, it is possible to configure the accesss strategy on which the debug point should be hit.

It is possible to filter the displayed debug points by name, thanks to an input field at the top. Validating the input field will filter so that all the remaining debug points contain the entered sequence of characters in their name:

![image](https://github.com/pharo-spec/NewTools/assets/97704417/c42d125e-bb45-4836-a524-b00f3364c6e5)

## Object-centric debug points

To set object-centric debug points, the second button in the inspector toolbar, with the `objects` icon, allows to do the same thing in the same way as former object-centric breakpoints So, this is possible to set object-centric breakpoints and watchpoints on all variables of a target for this object:

![image](https://github.com/adri09070/NewTools/assets/97704417/295fd03f-3591-47b1-b808-67d21d45a678)

Just as it was possible before debug points existed, it is still possible to set debug points on only some instance variables of the objects.
To do that, from the raw view in the inspector, select the variables you want to watch/break on and right-click to open a context menu to install breakpoints/watchpoints on them:

![image](https://github.com/adri09070/NewTools/assets/97704417/41f65031-36be-4659-9d71-87c43ab6284a)

Moreover, you can set object-centric breakpoints from the meta view in the inspector. Right-click on the method on which you want to break and select **Break on call** or **Break once on call**:

![image](https://github.com/adri09070/NewTools/assets/97704417/32dbf212-5eef-410e-b60d-331c0e2de31e)

Last but not least, it is also possible to change the scope of an existing debug point to an object, which was not possible before.
The third button in the inspector toolbar, with the `debug` icon, allows to do that and opens a modal to choose a debug point whose scope should be changed to the inspected object:

![image](https://github.com/pharo-spec/NewTools/assets/97704417/1d254ee1-704d-4501-878d-176a2b2e71af)


21 changes: 13 additions & 8 deletions src/BaselineOfNewTools/BaselineOfNewTools.class.st
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ BaselineOfNewTools >> baseline: spec [
package: 'NewTools-FontChooser-Tests' with: [ spec requires: #( 'NewTools-FontChooser' ) ];
package: 'NewTools-SpTextPresenterDecorators';
package: 'NewTools-Debugger-Breakpoints-Tools' with: [ spec requires: #( 'NewTools-Inspector' ) ];
"Debug points"
package: 'NewTools-DebugPointsBrowser' with: [spec requires: #( 'NewTools-SpTextPresenterDecorators' )];
package: 'NewTools-ObjectCentricDebugPoints' with: [spec requires: #( 'NewTools-DebugPointsBrowser' 'NewTools-Inspector' 'NewTools-Debugger' )];
package: 'NewTools-ProjectLoader';
package: 'NewTools-ProjectLoader-Microdown';
"Object-centric breakpoints"
Expand Down Expand Up @@ -111,17 +114,19 @@ BaselineOfNewTools >> baseline: spec [
'Core'
'Inspector'
'NewTools-Debugger-Commands'
'NewTools-Debugger-Extensions'
'NewTools-Debugger-Extensions'
'NewTools-Debugger'
'NewTools-ObjectCentricBreakpoints'
'NewTools-Sindarin-Tools'
'NewTools-ObjectCentricBreakpoints'
'NewTools-Sindarin-Tools'
'NewTools-Sindarin-Commands'
'NewTools-Sindarin-Commands-Tests'
'NewTools-Debugger-Breakpoints-Tools'
'NewTools-Debugger-Tests'
'NewTools-Sindarin-Commands-Tests'
'NewTools-Debugger-Breakpoints-Tools'
'NewTools-Debugger-Tests'
'NewTools-Debugger-Fuel'
'NewTools-Debugger-Fuel-Tests'
'NewTools-Fuel' );
'NewTools-Debugger-Fuel-Tests'
'NewTools-Fuel'
'NewTools-DebugPointsBrowser'
'NewTools-ObjectCentricDebugPoints' );
group: 'Spotter' with: #(
'NewTools-Morphic-Spotter'
'NewTools-Spotter-Processors'
Expand Down
6 changes: 6 additions & 0 deletions src/NewTools-DebugPointsBrowser/BreakDebugPoint.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
Extension { #name : 'BreakDebugPoint' }

{ #category : '*NewTools-DebugPointsBrowser' }
BreakDebugPoint >> uiElement [
^BreakPresenter new debugPoint: self.
]
19 changes: 19 additions & 0 deletions src/NewTools-DebugPointsBrowser/BreakPresenter.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
"
I am the breakpoint-specific UI element.
"
Class {
#name : 'BreakPresenter',
#superclass : 'DebugPointPresenter',
#category : 'NewTools-DebugPointsBrowser',
#package : 'NewTools-DebugPointsBrowser'
}

{ #category : 'layout' }
BreakPresenter >> defaultLayout [

^SpBoxLayout newTopToBottom
add: (self newLabel label: 'Break') expand: false ;
yourself.


]
7 changes: 7 additions & 0 deletions src/NewTools-DebugPointsBrowser/ChainBehavior.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Extension { #name : 'ChainBehavior' }

{ #category : '*NewTools-DebugPointsBrowser' }
ChainBehavior class >> uiElement [

^ ChainLinkPresenter
]
85 changes: 85 additions & 0 deletions src/NewTools-DebugPointsBrowser/ChainLinkPresenter.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
"
I am the UI element for the ChainLinkBehavior of DebugPoints and am added to the DebugPointEditor.
"
Class {
#name : 'ChainLinkPresenter',
#superclass : 'DebugPointBehaviorPresenter',
#instVars : [
'chain'
],
#category : 'NewTools-DebugPointsBrowser',
#package : 'NewTools-DebugPointsBrowser'
}

{ #category : 'accessing' }
ChainLinkPresenter >> debugPoint: aDebugPoint [

super debugPoint: aDebugPoint.
behavior := self debugPoint getBehavior: ChainBehavior.
checkBox state: behavior isNotNil.
behavior ifNotNil: [
chain roots:
{ (ChainBehavior rootFor: aDebugPoint) } asOrderedCollection.
chain children: [ :dp |
(ChainBehavior childFor: dp)
ifNil: [ OrderedCollection new ]
ifNotNil: [ :dp2 | { dp2 } ] ].
"chain expandAll."
"since selectItem does not work after expanding this requires a different solution to clarify which chainlink is currently selected"
chain selectItem: aDebugPoint ]
]

{ #category : 'layout' }
ChainLinkPresenter >> defaultLayout [
| newLayout |

newLayout := SpBoxLayout newTopToBottom

add: checkBox expand: false;
yourself.

self behavior ifNotNil: [
newLayout add: ( SpBoxLayout newTopToBottom borderWidth: 5;
add: (self newButton label: 'Reset Chain State'; action: [self resetChain.]) expand: false;
add: chain "height: 100" ;
yourself) expand: true;

yourself].

^newLayout




]

{ #category : 'expanding-collapsing' }
ChainLinkPresenter >> expand [
^true
]

{ #category : 'initialization' }
ChainLinkPresenter >> initializePresenters [

chain := self newTreeTable beResizable.
chain
addColumn:
(SpStringTableColumn title: 'Type' evaluated: [ :item | item name ])
yourself;
addColumn: (SpStringTableColumn
title: 'Target'
evaluated: [ :item | item targetString ]) yourself.
checkBox := self newCheckBox label:
'Chain: Each debug point is hit once in sequential order'.
checkBox whenActivatedDo: [
self behavior ifNil: [ debugPoint addBehavior: ChainBehavior new ] ].
checkBox whenDeactivatedDo: [
self debugPoint removeBehavior: ChainBehavior.
self behavior: nil ]
]

{ #category : 'API' }
ChainLinkPresenter >> resetChain [

self behavior resetChain.
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
"
I define a command to add a breakpoint on the AST node corresponding to the selected code and I open a debug point browser on the created breakpoint to configure it
"
Class {
#name : 'ClyAddAndConfigureBreakPointCommand',
#superclass : 'ClyDebuggingPointsCommand',
#category : 'NewTools-DebugPointsBrowser',
#package : 'NewTools-DebugPointsBrowser'
}

{ #category : 'accessing' }
ClyAddAndConfigureBreakPointCommand >> defaultMenuIconName [

^ #smallConfiguration
]

{ #category : 'accessing' }
ClyAddAndConfigureBreakPointCommand >> defaultMenuItemName [

^ ' Add Breakpoint to: ' , sourceNode displaySourceCode
, 'and configure it'
]

{ #category : 'execution' }
ClyAddAndConfigureBreakPointCommand >> execute [

| dp |
dp := DebugPointManager installNew: BreakDebugPoint on: sourceNode.
DebugPointBrowserPresenter openOn: dp
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Extension { #name : 'ConditionBehavior' }

{ #category : '*NewTools-DebugPointsBrowser' }
ConditionBehavior class >> uiElement [

^ConditionPresenter
]
69 changes: 69 additions & 0 deletions src/NewTools-DebugPointsBrowser/ConditionPresenter.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"
I am the UI element for the ConditionBehavior of DebugPoints and am added to the DebugPointEditor.
"
Class {
#name : 'ConditionPresenter',
#superclass : 'DebugPointBehaviorPresenter',
#instVars : [
'codeInput'
],
#category : 'NewTools-DebugPointsBrowser',
#package : 'NewTools-DebugPointsBrowser'
}

{ #category : 'model updates' }
ConditionPresenter >> activate [
| bh |
self behavior ifNotNil: [ ^self ].
bh := (ConditionBehavior new condition: (self debugPoint properties at: #Condition ifAbsent: '')).
self debugPoint addBehavior: bh.
self behavior: bh
]

{ #category : 'model updates' }
ConditionPresenter >> deactivate [
self debugPoint removeBehavior: ConditionBehavior.
self behavior: nil.
]

{ #category : 'accessing' }
ConditionPresenter >> debugPoint: aDebugPoint [
super debugPoint: aDebugPoint.

behavior := self debugPoint getBehavior: ConditionBehavior.
checkBox state: self behavior isNotNil.
codeInput enabled: checkBox state.
(self behavior ifNotNil: [:bh | codeInput text: bh condition]).

]

{ #category : 'layout' }
ConditionPresenter >> defaultLayout [
| newLayout |

newLayout := SpBoxLayout newTopToBottom
add: checkBox expand: false;
yourself.

self behavior ifNotNil: [
newLayout add: ( SpBoxLayout newLeftToRight borderWidth: 5;
add: codeInput expand: true ;
yourself) height: 60;
yourself].

^newLayout

]

{ #category : 'initialization' }
ConditionPresenter >> initializePresenters [

codeInput := self newCode.
codeInput beForScripting.
codeInput whenTextChangedDo: [ self behavior ifNotNil: [behavior condition: codeInput text ]].
checkBox := self newCheckBox label: 'Condition: Hit when the condition evaluates to true'.
checkBox whenActivatedDo: [ self activate ].
checkBox whenDeactivatedDo: [ self deactivate ].


]
7 changes: 7 additions & 0 deletions src/NewTools-DebugPointsBrowser/CountBehavior.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
Extension { #name : 'CountBehavior' }

{ #category : '*NewTools-DebugPointsBrowser' }
CountBehavior class >> uiElement [

^ CountPresenter
]
59 changes: 59 additions & 0 deletions src/NewTools-DebugPointsBrowser/CountPresenter.class.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
"
I am the UI element for the CountBehavior of DebugPoints and am added to the DebugPointEditor.
"
Class {
#name : 'CountPresenter',
#superclass : 'DebugPointBehaviorPresenter',
#instVars : [
'textInput'
],
#category : 'NewTools-DebugPointsBrowser',
#package : 'NewTools-DebugPointsBrowser'
}

{ #category : 'accessing' }
CountPresenter >> debugPoint: aDebugPoint [
super debugPoint: aDebugPoint.
behavior := self debugPoint getBehavior: CountBehavior.
checkBox state: (self debugPoint getBehavior: CountBehavior) isNotNil.
behavior ifNotNil: [
textInput text: behavior count asString ].
]

{ #category : 'layout' }
CountPresenter >> defaultLayout [
| newLayout |
newLayout := SpBoxLayout newTopToBottom
add: checkBox expand: false;
yourself.

self behavior ifNotNil: [
newLayout add: self expandedLayout expand: false;
yourself].

^newLayout

]

{ #category : 'layout' }
CountPresenter >> expandedLayout [
^( SpBoxLayout newLeftToRight borderWidth: 5;
add: (self newLabel label: 'Current Count:') expand: false ;
add: textInput expand: true ;
yourself)
]

{ #category : 'initialization' }
CountPresenter >> initializePresenters [

textInput := self newTextInput beNotEditable .

checkBox := self newCheckBox label: 'Counter: Tracks how many times the debug point was reached'.
checkBox whenActivatedDo: [
self behavior ifNil: [
debugPoint addBehavior: CountBehavior new ] ].
checkBox whenDeactivatedDo: [

self debugPoint removeBehavior: CountBehavior.
self behavior: nil. ].
]
13 changes: 13 additions & 0 deletions src/NewTools-DebugPointsBrowser/DebugPoint.extension.st
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
Extension { #name : 'DebugPoint' }

{ #category : '*NewTools-DebugPointsBrowser' }
DebugPoint >> uiElement [
^nil

]

{ #category : '*NewTools-DebugPointsBrowser' }
DebugPoint >> updateDebugPointUIManager: aDebugPointUIManager [

self target updateDebugPointUIManager: aDebugPointUIManager
]
Loading

0 comments on commit 937a4e9

Please sign in to comment.