--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/SmallSense__ParseTreeInspector.st Wed Jan 14 08:28:46 2015 +0000
@@ -0,0 +1,772 @@
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+"{ Package: 'stx:goodies/smallsense' }"
+
+"{ NameSpace: SmallSense }"
+
+ApplicationModel subclass:#ParseTreeInspector
+ instanceVariableNames:'classHolder selectorHolder methodHolder nodeHolder sourceHolder
+ sourceView inspectorView'
+ classVariableNames:''
+ poolDictionaries:''
+ category:'SmallSense-Core-Interface'
+!
+
+HierarchicalItem subclass:#ParseTreeItem
+ instanceVariableNames:'astNode ivarName'
+ classVariableNames:''
+ poolDictionaries:''
+ privateIn:ParseTreeInspector
+!
+
+!ParseTreeInspector class methodsFor:'documentation'!
+
+copyright
+"
+stx:goodies/smallsense - A productivity plugin for Smalltalk/X IDE
+Copyright (C) 2013-2014 Jan Vrany
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation; either
+version 2.1 of the License.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+"
+! !
+
+!ParseTreeInspector class methodsFor:'instance creation'!
+
+node: node source: source
+
+ ^self new node: node source: source
+
+ "Created: / 14-09-2011 / 17:25:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeInspector class methodsFor:'interface opening'!
+
+openOnClass: class selector: selector
+
+ ^self new
+ class: class selector: selector;
+ open
+
+ "
+ SmallSenseParseNodeInspector
+ openOnClass: self
+ selector: #openOnClass:selector:
+ "
+
+ "Created: / 26-11-2011 / 12:30:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+openOnNode: node source: source
+
+ ^self new
+ node: node source: source;
+ open
+
+ "Created: / 25-08-2013 / 10:28:36 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeInspector class methodsFor:'interface specs'!
+
+inspectorTabSpec
+ "This resource specification was automatically generated
+ by the UIPainter of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the UIPainter may not be able to read the specification."
+
+ "
+ UIPainter new openOnClass:Tools::ParseNodeInspector andSelector:#inspectorTabSpec
+ Tools::ParseNodeInspector new openInterface:#inspectorTabSpec
+ "
+
+ <resource: #canvas>
+
+ ^
+ #(FullSpec
+ name: inspectorTabSpec
+ window:
+ (WindowSpec
+ label: 'InspectorTab'
+ name: 'InspectorTab'
+ min: (Point 10 10)
+ bounds: (Rectangle 0 0 300 300)
+ )
+ component:
+ (SpecCollection
+ collection: (
+ (NonScrollableArbitraryComponentSpec
+ name: 'InspectorView'
+ layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+ component: nodeInspectorView
+ )
+ )
+
+ )
+ )
+
+ "Modified: / 09-04-2014 / 22:29:34 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+sourceTabSpec
+ "This resource specification was automatically generated
+ by the UIPainter of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the UIPainter may not be able to read the specification."
+
+ "
+ UIPainter new openOnClass:SmallSense::ParseNodeInspector andSelector:#sourceTabSpec
+ SmallSense::ParseNodeInspector new openInterface:#sourceTabSpec
+ "
+
+ <resource: #canvas>
+
+ ^
+ #(FullSpec
+ name: sourceTabSpec
+ window:
+ (WindowSpec
+ label: 'SourceTab'
+ name: 'SourceTab'
+ min: (Point 10 10)
+ bounds: (Rectangle 0 0 300 300)
+ )
+ component:
+ (SpecCollection
+ collection: (
+ (TextEditorSpec
+ name: 'SourceView'
+ layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+ model: sourceHolder
+ hasHorizontalScrollBar: true
+ hasVerticalScrollBar: true
+ isReadOnly: true
+ showingCode: true
+ hasKeyboardFocusInitially: false
+ postBuildCallback: postBuildSourceView:
+ viewClassName: 'CodeView'
+ )
+ )
+
+ )
+ )
+!
+
+windowSpec
+ ^ self windowSpecWithInspector
+
+ "Modified: / 09-04-2014 / 22:27:07 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+windowSpecWithInspector
+ "This resource specification was automatically generated
+ by the UIPainter of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the UIPainter may not be able to read the specification."
+
+ "
+ UIPainter new openOnClass:SmallSense::ParseNodeInspector andSelector:#windowSpecWithInspector
+ SmallSense::ParseNodeInspector new openInterface:#windowSpecWithInspector
+ "
+
+ <resource: #canvas>
+
+ ^
+ #(FullSpec
+ name: windowSpecWithInspector
+ window:
+ (WindowSpec
+ label: 'Parse Tree Inspector'
+ name: 'Parse Tree Inspector'
+ min: (Point 10 10)
+ bounds: (Rectangle 0 0 630 322)
+ )
+ component:
+ (SpecCollection
+ collection: (
+ (VariableHorizontalPanelSpec
+ name: 'QueryTreeAndSourcePanel'
+ layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+ showHandle: true
+ snapMode: both
+ handlePosition: right
+ component:
+ (SpecCollection
+ collection: (
+ (HierarchicalListViewSpec
+ name: 'QueryTree'
+ model: selectionHolder
+ menu: queryTreeMenu
+ hasHorizontalScrollBar: true
+ hasVerticalScrollBar: true
+ listModel: parseTree
+ useIndex: false
+ highlightMode: line
+ useDefaultIcons: false
+ )
+ (NoteBookViewSpec
+ name: 'NoteBook'
+ menu: tabList
+ )
+ )
+
+ )
+ handles: (Any 0.3 1.0)
+ )
+ )
+
+ )
+ )
+!
+
+windowSpecWithoutInspector
+ "This resource specification was automatically generated
+ by the UIPainter of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the UIPainter may not be able to read the specification."
+
+ "
+ UIPainter new openOnClass:SmallSenseParseNodeInspector andSelector:#windowSpec
+ SmallSenseParseNodeInspector new openInterface:#windowSpec
+ SmallSenseParseNodeInspector open
+ "
+
+ <resource: #canvas>
+
+ ^
+ #(FullSpec
+ name: windowSpec
+ window:
+ (WindowSpec
+ label: 'Parse Tree Inspector'
+ name: 'Parse Tree Inspector'
+ min: (Point 10 10)
+ bounds: (Rectangle 0 0 630 322)
+ )
+ component:
+ (SpecCollection
+ collection: (
+ (VariableHorizontalPanelSpec
+ name: 'QueryTreeAndSourcePanel'
+ layout: (LayoutFrame 0 0 0 0 0 1 0 1)
+ showHandle: true
+ snapMode: both
+ handlePosition: right
+ component:
+ (SpecCollection
+ collection: (
+ (HierarchicalListViewSpec
+ name: 'QueryTree'
+ model: selectionHolder
+ menu: queryTreeMenu
+ hasHorizontalScrollBar: true
+ hasVerticalScrollBar: true
+ listModel: parseTree
+ useIndex: false
+ highlightMode: line
+ useDefaultIcons: false
+ )
+ (UISubSpecification
+ name: 'SourceSoec'
+ minorKey: sourceTabSpec
+ )
+ )
+
+ )
+ handles: (Any 0.3 1.0)
+ )
+ )
+
+ )
+ )
+
+ "Created: / 09-04-2014 / 22:26:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeInspector class methodsFor:'list specs'!
+
+tabList
+ "This resource specification was automatically generated
+ by the TabListEditor of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the TabListEditor may not be able to read the specification."
+
+ "
+ TabListEditor new openOnClass: self andSelector:#tabList
+ "
+
+ <resource: #tabList>
+
+ ^ #(
+ (TabItem
+ label: 'Source'
+ minorKey: sourceTabSpec
+ createNewBuilder: false
+ )
+ (TabItem
+ label: 'Node'
+ minorKey: inspectorTabSpec
+ createNewBuilder: false
+ )
+ )
+
+ collect:[:aTab| TabItem new fromLiteralArrayEncoding:aTab ]
+! !
+
+!ParseTreeInspector class methodsFor:'menu specs'!
+
+queryTreeMenu
+ "This resource specification was automatically generated
+ by the MenuEditor of ST/X."
+
+ "Do not manually edit this!! If it is corrupted,
+ the MenuEditor may not be able to read the specification."
+
+ "
+ MenuEditor new openOnClass:XQuery::QueryInspectorUI andSelector:#queryTreeMenu
+ (Menu new fromLiteralArrayEncoding:(XQuery::QueryInspectorUI queryTreeMenu)) startUp
+ "
+
+ <resource: #menu>
+
+ ^
+ #(Menu
+ (
+ (MenuItem
+ label: 'Inspect AST node'
+ itemValue: queryTreeMenuInspectAstNode
+ translateLabel: true
+ )
+ )
+ nil
+ nil
+ )
+
+ "Created: / 12-04-2007 / 11:46:57 / janfrog"
+! !
+
+!ParseTreeInspector class methodsFor:'plugIn spec'!
+
+aspectSelectors
+ "This resource specification was automatically generated
+ by the UIPainter of ST/X."
+
+ "Do not manually edit this. If it is corrupted,
+ the UIPainter may not be able to read the specification."
+
+ "Return a description of exported aspects;
+ these can be connected to aspects of an embedding application
+ (if this app is embedded in a subCanvas)."
+
+ ^ #(
+ #model
+ ).
+
+! !
+
+!ParseTreeInspector methodsFor:'accessing'!
+
+class: class selector: selector
+ | mth source node parser |
+
+ mth := class >> selector.
+ mth isNil ifTrue:[
+ self error:'No such method'.
+ ^self.
+ ].
+ source := mth source.
+ parser := Parser parseMethod: source.
+ node := parser tree.
+
+ self node: node source: source.
+
+ "
+ SmallSenseParseNodeInspector
+ openOnClass: SmallSenseParseNodeInspector
+ selector: #class:selector:
+ "
+
+ "Created: / 15-02-2012 / 12:25:53 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+node: node source: source
+
+ self nodeHolder value: node.
+ self sourceHolder value: source.
+
+ "Created: / 14-09-2011 / 17:23:16 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+selection
+
+ | item |
+ (item := self selectionHolder value) notNil ifTrue:[
+ ^item
+ ] ifFalse:[
+ ^nil
+ ]
+
+ "Created: / 12-04-2007 / 12:29:08 / janfrog"
+ "Created: / 26-11-2011 / 11:46:22 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeInspector methodsFor:'aspects'!
+
+nodeHolder
+ "return/create the 'nodeHolder' value holder (automatically generated)"
+
+ nodeHolder isNil ifTrue:[
+ nodeHolder := ValueHolder new.
+ ].
+ ^ nodeHolder
+!
+
+nodeHolder:something
+ "set the 'nodeHolder' value holder (automatically generated)"
+
+ nodeHolder := something.
+!
+
+nodeInspectorView
+
+ inspectorView isNil ifTrue:[
+ inspectorView := InspectorView new
+ ].
+ ^ inspectorView
+
+ "Created: / 31-10-2007 / 12:20:02 / janfrog"
+ "Created: / 14-09-2011 / 17:24:19 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+parseTree
+
+ ^self builder bindings at: #parseTree
+ ifAbsentPut:
+ [PluggableAdaptor on: self nodeHolder getter:
+ [:m|
+ | rootAstNodeItem rootAstNode hl |
+
+ rootAstNode := self nodeHolder value.
+
+ rootAstNodeItem := ParseTreeItem new
+ ivarName: 'AST';
+ astNode: rootAstNode;
+ yourself.
+
+
+ hl := HierarchicalList new
+ root: rootAstNodeItem;
+ showRoot: true;
+ yourself.
+ rootAstNodeItem expand.
+ hl]]
+
+ "Created: / 28-03-2007 / 15:58:31 / janfrog"
+ "Modified: / 31-10-2007 / 12:11:46 / janfrog"
+ "Created: / 14-09-2011 / 17:24:10 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 07-08-2014 / 10:19:47 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+selectionHolder
+
+ ^self builder bindings at: #selectionHolder
+ ifAbsentPut:
+ [nil asValue
+ onChangeSend:#updateSourceViewSelection to:self;
+ onChangeSend:#updateInspectorView to:self;
+ yourself]
+
+ "Created: / 28-03-2007 / 16:46:30 / janfrog"
+ "Modified: / 31-10-2007 / 12:25:54 / janfrog"
+ "Created: / 14-09-2011 / 17:24:39 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+ "Modified: / 09-04-2014 / 09:35:51 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+sourceHolder
+ "return/create the 'sourceHolder' value holder (automatically generated)"
+
+ sourceHolder isNil ifTrue:[
+ sourceHolder := ValueHolder new.
+ ].
+ ^ sourceHolder
+!
+
+sourceHolder:something
+ "set the 'sourceHolder' value holder (automatically generated)"
+
+ sourceHolder := something.
+!
+
+tabList
+ "Generated by the TabListEditor"
+
+ |list|
+
+ (list := builder bindingAt:#tabList) isNil ifTrue:[
+ builder aspectAt:#tabList put:(list := self class tabList).
+ ].
+ ^ list
+
+ "Created: / 31-10-2007 / 12:21:18 / janfrog"
+! !
+
+!ParseTreeInspector methodsFor:'callbacks - post build'!
+
+postBuildSourceView: aView
+
+ sourceView := aView scrolledView.
+ sourceView cursorLineHolder addDependent: self.
+ sourceView cursorColHolder addDependent: self.
+
+ "Created: / 12-04-2007 / 12:28:14 / janfrog"
+ "Modified: / 10-04-2014 / 07:55:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeInspector methodsFor:'change & update'!
+
+update:something with:aParameter from:changedObject
+ "Invoked when an object that I depend upon sends a change notification."
+
+ "stub code automatically generated - please change as required"
+
+ sourceView notNil ifTrue:[
+ changedObject == sourceView cursorLineHolder ifTrue:[
+ self updateSelectionFromCursor.
+ ^ self.
+ ].
+ changedObject == sourceView cursorColHolder ifTrue:[
+ self updateSelectionFromCursor.
+ ^ self.
+ ].
+
+ ].
+ super update:something with:aParameter from:changedObject
+
+ "Modified: / 10-04-2014 / 07:57:14 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateInspectorView
+
+ inspectorView notNil ifTrue:[
+ | selection |
+
+ selection := self selection.
+ inspectorView inspect: (selection isNil ifTrue:[ nil ] ifFalse:[ selection node ])
+ ]
+
+ "Created: / 31-10-2007 / 12:25:25 / janfrog"
+ "Modified: / 10-04-2014 / 08:34:58 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateSelectionFromCursor
+ | pos root selection |
+
+ pos := sourceView characterPositionOfCursor.
+ root := self parseTree value root.
+ selection := root leafNodeAt: pos.
+ selection notNil ifTrue:[
+ | item |
+
+ item := selection.
+ [ item notNil ] whileTrue:[
+ item expand.
+ item := item parent.
+ ].
+ self selectionHolder value: selection
+
+ ].
+
+ "Created: / 10-04-2014 / 07:57:09 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+updateSourceViewSelection
+
+ | astNode startPosition stopPosition |
+ sourceView ifNil:[^self].
+ (astNode := self selection) ifNil:[^self].
+ astNode node isNil ifTrue:[ ^ self ].
+ (startPosition := astNode node startPosition)
+ ifNil:[^sourceView unselect].
+ (stopPosition := astNode node endPosition)
+ ifNil:[^sourceView unselect].
+
+ sourceView
+ selectFromCharacterPosition: startPosition
+ to: stopPosition.
+ sourceView makeCursorVisible
+
+ "Created: / 12-04-2007 / 12:29:42 / janfrog"
+ "Modified: / 07-08-2014 / 10:21:06 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeInspector methodsFor:'menu actions'!
+
+queryTreeMenuInspectAstNode
+
+ ^self selection node inspect
+
+ "Created: / 12-04-2007 / 11:47:48 / janfrog"
+ "Modified: / 26-11-2011 / 12:12:12 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeInspector::ParseTreeItem class methodsFor:'documentation'!
+
+version
+ ^'$Id$'
+! !
+
+!ParseTreeInspector::ParseTreeItem methodsFor:'accessing'!
+
+astNode
+ ^ astNode
+
+ "Created: / 28-03-2007 / 15:51:49 / janfrog"
+!
+
+astNode:anAstNode
+ astNode := anAstNode.
+
+ "Created: / 28-03-2007 / 15:51:49 / janfrog"
+!
+
+astNodeName
+
+ ^astNode class name
+
+ "Created: / 12-04-2007 / 11:29:57 / janfrog"
+ "Modified: / 31-10-2007 / 12:13:34 / janfrog"
+ "Modified: / 26-11-2011 / 10:47:05 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+children
+
+ children isNil ifTrue:[
+ children := OrderedCollection new.
+ astNode notNil ifTrue:[
+ astNode childNamesAndValuesDo:[:ivarName :astNode|
+ astNode notNil ifTrue:[
+ children add: (self class new
+ ivarName: ivarName;
+ astNode: astNode;
+ parent: self)
+ ]
+ ].
+ ].
+ ].
+ ^children
+
+ "Created: / 28-03-2007 / 15:55:24 / janfrog"
+ "Modified: / 12-04-2007 / 11:35:24 / janfrog"
+ "Modified: / 07-08-2014 / 10:20:11 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+icon
+
+ ^nil
+
+ "Created: / 31-10-2007 / 12:14:52 / janfrog"
+ "Modified: / 26-11-2011 / 10:47:15 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+ivarName
+ ^ ivarName ? '?'
+
+ "Created: / 12-04-2007 / 11:29:28 / janfrog"
+!
+
+ivarName:something
+ ivarName := something.
+
+ "Created: / 12-04-2007 / 11:29:28 / janfrog"
+!
+
+label
+ | label start stop |
+
+ astNode isNil ifTrue:[ ^ 'No AST' ].
+
+ start := astNode startPosition.
+ stop := astNode endPosition.
+
+ label := '%1 {%2} [%3..%4]'
+ bindWith: self ivarName
+ with: self astNodeName
+ with: start ? '?'
+ with: stop ? '?'.
+ (start isNil or:[ stop isNil ]) ifTrue:[
+ label := label asText colorizeAllWith: Color red.
+ ].
+ ^ label
+
+ "Created: / 28-03-2007 / 15:53:18 / janfrog"
+ "Modified: / 12-04-2007 / 11:30:23 / janfrog"
+ "Modified: / 07-08-2014 / 10:20:35 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+leafNodeAt: pos
+ | start stop |
+
+ start := astNode startPosition.
+ stop := astNode endPosition.
+ self children do:[:each |
+ | leaf |
+ leaf := each leafNodeAt: pos.
+ leaf notNil ifTrue:[ ^ leaf ].
+ ].
+ (start notNil and:[stop notNil]) ifTrue:[
+ (pos between: start and: stop) ifTrue:[ ^ self ].
+ ].
+ ^ nil.
+
+ "Created: / 10-04-2014 / 08:02:33 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+!
+
+node
+ ^ astNode
+
+ "Created: / 28-03-2007 / 15:51:49 / janfrog"
+ "Created: / 26-11-2011 / 11:48:18 / Jan Vrany <jan.vrany@fit.cvut.cz>"
+! !
+
+!ParseTreeInspector class methodsFor:'documentation'!
+
+version_HG
+
+ ^ '$Changeset: <not expanded> $'
+!
+
+version_SVN
+ ^ '$Id$'
+! !
+