Helios-Debugger.st 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342
  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. unregister
  72. super unregister.
  73. self inspectorWidget unregister
  74. ! !
  75. !HLDebugger methodsFor: 'keybindings'!
  76. registerBindingsOn: aBindingGroup
  77. HLToolCommand
  78. registerConcreteClassesOn: aBindingGroup
  79. for: self model
  80. ! !
  81. !HLDebugger methodsFor: 'reactions'!
  82. onContextSelected: anAnnouncement
  83. self inspectorWidget inspect: (HLContextInspectorDecorator on: anAnnouncement context)
  84. ! !
  85. !HLDebugger methodsFor: 'rendering'!
  86. renderContentOn: html
  87. html with: (HLContainer with: (HLHorizontalSplitter
  88. with: self stackListWidget
  89. with: (HLVerticalSplitter
  90. with: self codeWidget
  91. with: self inspectorWidget)))
  92. ! !
  93. !HLDebugger class methodsFor: 'accessing'!
  94. tabClass
  95. ^ 'debugger'
  96. !
  97. tabLabel
  98. ^ 'Debugger'
  99. ! !
  100. !HLDebugger class methodsFor: 'instance creation'!
  101. on: aMethodContext
  102. ^ self new
  103. initializeFromMethodContext: aMethodContext;
  104. yourself
  105. ! !
  106. HLBrowserCodeWidget subclass: #HLDebuggerCodeWidget
  107. instanceVariableNames: 'highlightedNode'
  108. package: 'Helios-Debugger'!
  109. !HLDebuggerCodeWidget methodsFor: 'accessing'!
  110. contents: aString
  111. self clearHighlight.
  112. super contents: aString
  113. !
  114. editorOptions
  115. ^ super editorOptions
  116. at: 'gutters' put: #('CodeMirror-linenumbers' 'stops');
  117. yourself
  118. !
  119. highlightedNode
  120. ^ highlightedNode
  121. !
  122. highlightedNode: aNode
  123. highlightedNode := aNode
  124. ! !
  125. !HLDebuggerCodeWidget methodsFor: 'actions'!
  126. addStopAt: anInteger
  127. editor
  128. setGutterMarker: anInteger
  129. gutter: 'stops'
  130. value: '<div class="stop"></stop>' asJQuery toArray first
  131. !
  132. clearHighlight
  133. editor clearGutter: 'stops'.
  134. self highlightedNode ifNotNil: [ :node |
  135. editor
  136. removeLineClass: node position x - 1
  137. where: 'background'
  138. class: 'highlighted' ]
  139. !
  140. highlight
  141. | anchor head selection |
  142. head := #{
  143. 'line' -> (self highlightedNode position x - 1).
  144. 'ch' -> (self highlightedNode position y - 1)
  145. }.
  146. anchor := #{
  147. 'line' -> (self highlightedNode extent x - 1).
  148. 'ch' -> (self highlightedNode extent y - 1)
  149. }.
  150. editor setSelection: head to: anchor
  151. !
  152. highlightLine: anInteger
  153. editor
  154. addLineClass: anInteger
  155. where: 'background'
  156. class: 'highlighted'
  157. !
  158. highlightNode: aNode
  159. | line |
  160. aNode ifNotNil: [
  161. line := aNode position x - 1.
  162. self
  163. clearHighlight;
  164. addStopAt: line;
  165. highlightLine: line;
  166. highlightedNode: aNode
  167. ]
  168. !
  169. observeBrowserModel
  170. super observeBrowserModel.
  171. self browserModel announcer
  172. on: HLDebuggerContextSelected
  173. send: #onContextSelected
  174. to: self
  175. ! !
  176. !HLDebuggerCodeWidget methodsFor: 'reactions'!
  177. onContextSelected
  178. self highlightNode: self browserModel nextNode
  179. ! !
  180. HLToolModel subclass: #HLDebuggerModel
  181. instanceVariableNames: 'rootContext currentContext contexts interpreter'
  182. package: 'Helios-Debugger'!
  183. !HLDebuggerModel commentStamp!
  184. I am a model for Helios debugging.
  185. My instances hold a reference to an `AIContext` instance, built from a `MethodContext`. The context should be the root of the context stack.!
  186. !HLDebuggerModel methodsFor: 'accessing'!
  187. contexts
  188. ^ contexts
  189. !
  190. currentContext
  191. currentContext ifNil: [ self currentContext: self rootContext ].
  192. ^ currentContext
  193. !
  194. currentContext: aContext
  195. self withChangesDo: [
  196. self selectedMethod: aContext method.
  197. currentContext := aContext.
  198. interpreter := ASTDebugger context: aContext.
  199. self announcer announce: (HLDebuggerContextSelected new
  200. context: aContext;
  201. yourself) ]
  202. !
  203. interpreter
  204. ^ interpreter
  205. !
  206. nextNode
  207. ^ self interpreter nextNode
  208. !
  209. rootContext
  210. ^ rootContext
  211. ! !
  212. !HLDebuggerModel methodsFor: 'initialization'!
  213. initializeContexts
  214. "Flatten the context stack into an OrderedCollection"
  215. | context |
  216. contexts := OrderedCollection new.
  217. context := self rootContext.
  218. [ context notNil ] whileTrue: [
  219. contexts add: context.
  220. context := context outerContext ]
  221. !
  222. initializeFromContext: aMethodContext
  223. rootContext := AIContext fromMethodContext: aMethodContext.
  224. self initializeContexts
  225. ! !
  226. !HLDebuggerModel class methodsFor: 'instance creation'!
  227. on: aMethodContext
  228. ^ self new
  229. initializeFromContext: aMethodContext;
  230. yourself
  231. ! !
  232. ErrorHandler subclass: #HLErrorHandler
  233. instanceVariableNames: ''
  234. package: 'Helios-Debugger'!
  235. !HLErrorHandler methodsFor: 'error handling'!
  236. handleError: anError
  237. [
  238. (HLDebugger on: anError context) openAsTab
  239. ]
  240. on: Error
  241. do: [ :error | ErrorHandler new handleError: error ]
  242. ! !
  243. !HLErrorHandler class methodsFor: 'error handling'!
  244. handleError: anError
  245. ^ self new handleError: anError
  246. ! !
  247. HLToolListWidget subclass: #HLStackListWidget
  248. instanceVariableNames: ''
  249. package: 'Helios-Debugger'!
  250. !HLStackListWidget methodsFor: 'accessing'!
  251. items
  252. ^ items ifNil: [ items := self model contexts ]
  253. !
  254. label
  255. ^ 'Call stack'
  256. ! !
  257. !HLStackListWidget methodsFor: 'actions'!
  258. selectItem: aContext
  259. self model currentContext: aContext
  260. ! !