Helios-Debugger.st 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339
  1. Smalltalk current createPackage: 'Helios-Debugger'!
  2. Object subclass: #HLContextInspectorDecorator
  3. instanceVariableNames: 'context'
  4. package: 'Helios-Debugger'!
  5. !HLContextInspectorDecorator methodsFor: 'accessing'!
  6. context
  7. ^ context
  8. ! !
  9. !HLContextInspectorDecorator methodsFor: 'initialization'!
  10. initializeFromContext: aContext
  11. context := aContext
  12. ! !
  13. !HLContextInspectorDecorator methodsFor: 'inspecting'!
  14. inspectOn: anInspector
  15. | variables inspectedContext |
  16. variables := Dictionary new.
  17. inspectedContext := self context.
  18. variables addAll: inspectedContext locals.
  19. [ inspectedContext notNil and: [ inspectedContext isBlockContext ] ] whileTrue: [
  20. inspectedContext := inspectedContext outerContext.
  21. inspectedContext ifNotNil: [
  22. variables addAll: inspectedContext locals ] ].
  23. anInspector
  24. setLabel: 'Context';
  25. setVariables: variables
  26. ! !
  27. !HLContextInspectorDecorator class methodsFor: 'instance creation'!
  28. on: aContext
  29. ^ self new
  30. initializeFromContext: aContext;
  31. yourself
  32. ! !
  33. HLFocusableWidget subclass: #HLDebugger
  34. instanceVariableNames: 'model stackListWidget codeWidget inspectorWidget'
  35. package: 'Helios-Debugger'!
  36. !HLDebugger commentStamp!
  37. I am the main widget for the Helios debugger.!
  38. !HLDebugger methodsFor: 'accessing'!
  39. codeWidget
  40. ^ codeWidget ifNil: [ codeWidget := HLDebuggerCodeWidget new
  41. browserModel: self model;
  42. yourself ]
  43. !
  44. initializeFromMethodContext: aMethodContext
  45. model := HLDebuggerModel on: aMethodContext.
  46. self observeModel
  47. !
  48. inspectorWidget
  49. ^ inspectorWidget ifNil: [
  50. inspectorWidget := HLInspectorWidget new ]
  51. !
  52. model
  53. ^ model ifNil: [ model := HLDebuggerModel new ]
  54. !
  55. stackListWidget
  56. ^ stackListWidget ifNil: [
  57. stackListWidget := (HLStackListWidget on: self model)
  58. next: self codeWidget;
  59. yourself ]
  60. ! !
  61. !HLDebugger methodsFor: 'actions'!
  62. focus
  63. self stackListWidget focus
  64. !
  65. observeModel
  66. self model announcer
  67. on: HLDebuggerContextSelected
  68. send: #onContextSelected:
  69. to: self
  70. ! !
  71. !HLDebugger methodsFor: 'keybindings'!
  72. registerBindingsOn: aBindingGroup
  73. HLToolCommand
  74. registerConcreteClassesOn: aBindingGroup
  75. for: self model
  76. ! !
  77. !HLDebugger methodsFor: 'reactions'!
  78. onContextSelected: anAnnouncement
  79. self inspectorWidget inspect: (HLContextInspectorDecorator on: anAnnouncement context)
  80. ! !
  81. !HLDebugger methodsFor: 'rendering'!
  82. open
  83. HLManager current addTab: (HLTab on: self labelled: self class tabLabel)
  84. !
  85. renderContentOn: html
  86. html with: (HLContainer with: (HLHorizontalSplitter
  87. with: self stackListWidget
  88. with: (HLVerticalSplitter
  89. with: self codeWidget
  90. with: self inspectorWidget)))
  91. ! !
  92. !HLDebugger class methodsFor: 'accessing'!
  93. tabClass
  94. ^ 'debugger'
  95. !
  96. tabLabel
  97. ^ 'Debugger'
  98. ! !
  99. !HLDebugger class methodsFor: 'instance creation'!
  100. on: aMethodContext
  101. ^ self new
  102. initializeFromMethodContext: aMethodContext;
  103. yourself
  104. ! !
  105. HLBrowserCodeWidget subclass: #HLDebuggerCodeWidget
  106. instanceVariableNames: 'highlightedNode'
  107. package: 'Helios-Debugger'!
  108. !HLDebuggerCodeWidget methodsFor: 'accessing'!
  109. contents: aString
  110. self clearHighlight.
  111. super contents: aString
  112. !
  113. editorOptions
  114. ^ super editorOptions
  115. at: 'gutters' put: #('CodeMirror-linenumbers' 'stops');
  116. yourself
  117. !
  118. highlightedNode
  119. ^ highlightedNode
  120. !
  121. highlightedNode: aNode
  122. highlightedNode := aNode
  123. ! !
  124. !HLDebuggerCodeWidget methodsFor: 'actions'!
  125. addStopAt: anInteger
  126. editor
  127. setGutterMarker: anInteger
  128. gutter: 'stops'
  129. value: '<div class="stop"></stop>' asJQuery toArray first
  130. !
  131. clearHighlight
  132. editor clearGutter: 'stops'.
  133. self highlightedNode ifNotNil: [ :node |
  134. editor
  135. removeLineClass: node position x - 1
  136. where: 'background'
  137. class: 'highlighted' ]
  138. !
  139. highlight
  140. | anchor head selection |
  141. head := #{
  142. 'line' -> (self highlightedNode position x - 1).
  143. 'ch' -> (self highlightedNode position y - 1)
  144. }.
  145. anchor := #{
  146. 'line' -> (self highlightedNode extent x - 1).
  147. 'ch' -> (self highlightedNode extent y - 1)
  148. }.
  149. editor setSelection: head to: anchor
  150. !
  151. highlightLine: anInteger
  152. editor
  153. addLineClass: anInteger
  154. where: 'background'
  155. class: 'highlighted'
  156. !
  157. highlightNode: aNode
  158. | line |
  159. aNode ifNotNil: [
  160. line := aNode position x - 1.
  161. self
  162. clearHighlight;
  163. addStopAt: line;
  164. highlightLine: line;
  165. highlightedNode: aNode
  166. ]
  167. !
  168. observeBrowserModel
  169. super observeBrowserModel.
  170. self browserModel announcer
  171. on: HLDebuggerContextSelected
  172. send: #onContextSelected
  173. to: self
  174. ! !
  175. !HLDebuggerCodeWidget methodsFor: 'reactions'!
  176. onContextSelected
  177. self highlightNode: self browserModel nextNode
  178. ! !
  179. HLToolModel subclass: #HLDebuggerModel
  180. instanceVariableNames: 'rootContext currentContext contexts interpreter'
  181. package: 'Helios-Debugger'!
  182. !HLDebuggerModel commentStamp!
  183. I am a model for Helios debugging.
  184. My instances hold a reference to an `AIContext` instance, built from a `MethodContext`. The context should be the root of the context stack.!
  185. !HLDebuggerModel methodsFor: 'accessing'!
  186. contexts
  187. ^ contexts
  188. !
  189. currentContext
  190. currentContext ifNil: [ self currentContext: self rootContext ].
  191. ^ currentContext
  192. !
  193. currentContext: aContext
  194. self withChangesDo: [
  195. self selectedMethod: aContext method.
  196. currentContext := aContext.
  197. interpreter := ASTDebugger context: aContext.
  198. self announcer announce: (HLDebuggerContextSelected new
  199. context: aContext;
  200. yourself) ]
  201. !
  202. interpreter
  203. ^ interpreter
  204. !
  205. nextNode
  206. ^ self interpreter nextNode
  207. !
  208. rootContext
  209. ^ rootContext
  210. ! !
  211. !HLDebuggerModel methodsFor: 'initialization'!
  212. initializeContexts
  213. "Flatten the context stack into an OrderedCollection"
  214. | context |
  215. contexts := OrderedCollection new.
  216. context := self rootContext.
  217. [ context notNil ] whileTrue: [
  218. contexts add: context.
  219. context := context outerContext ]
  220. !
  221. initializeFromContext: aMethodContext
  222. rootContext := AIContext fromMethodContext: aMethodContext.
  223. self initializeContexts
  224. ! !
  225. !HLDebuggerModel class methodsFor: 'instance creation'!
  226. on: aMethodContext
  227. ^ self new
  228. initializeFromContext: aMethodContext;
  229. yourself
  230. ! !
  231. ErrorHandler subclass: #HLErrorHandler
  232. instanceVariableNames: ''
  233. package: 'Helios-Debugger'!
  234. !HLErrorHandler methodsFor: 'error handling'!
  235. handleError: anError
  236. [ (HLDebugger on: anError context)
  237. open ] on: Error do: [ :error |
  238. ErrorHandler new handleError: error ]
  239. ! !
  240. !HLErrorHandler class methodsFor: 'error handling'!
  241. handleError: anError
  242. ^ self new handleError: anError
  243. ! !
  244. HLToolListWidget subclass: #HLStackListWidget
  245. instanceVariableNames: ''
  246. package: 'Helios-Debugger'!
  247. !HLStackListWidget methodsFor: 'accessing'!
  248. items
  249. ^ items ifNil: [ items := self model contexts ]
  250. !
  251. label
  252. ^ 'Call stack'
  253. ! !
  254. !HLStackListWidget methodsFor: 'actions'!
  255. selectItem: aContext
  256. self model currentContext: aContext
  257. ! !