summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala126
1 files changed, 111 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
index 8fd0017b81..613928856d 100644
--- a/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
+++ b/src/compiler/scala/tools/nsc/ast/TreeBrowsers.scala
@@ -31,6 +31,9 @@ abstract class TreeBrowsers {
import global._
import nme.EMPTY
+ val borderSize = 10
+
+
def create(): SwingBrowser = new SwingBrowser();
/** Pseudo tree class, so that all JTree nodes are treated uniformly */
@@ -93,37 +96,38 @@ abstract class TreeBrowsers {
listeners = l :: listeners
/** Return the index'th child of parent */
- def getChild(parent: Any, index: Int): AnyRef =
+ def getChild(parent: AnyRef, index: Int): AnyRef =
packChildren(parent)(index)
/** Return the number of children this 'parent' has */
- def getChildCount(parent: Any): Int =
+ def getChildCount(parent: AnyRef): Int =
packChildren(parent).length
/** Return the index of the given child */
- def getIndexOfChild(parent: Any, child: Any): Int =
+ def getIndexOfChild(parent: AnyRef, child: AnyRef): Int =
packChildren(parent) indexOf child
/** Return the root node */
def getRoot(): AnyRef = program
/** Test whether the given node is a leaf */
- def isLeaf(node: Any): Boolean = packChildren(node).isEmpty
+ def isLeaf(node: AnyRef): Boolean = packChildren(node).isEmpty
def removeTreeModelListener(l: TreeModelListener): Unit =
listeners = listeners filterNot (_ == l)
/** we ignore this message for now */
- def valueForPathChanged(path: TreePath, newValue: Any) = ()
+ def valueForPathChanged(path: TreePath, newValue: AnyRef) = ()
/**
* Return a list of children for the given node.
*/
- def packChildren(t: Any): List[AnyRef] =
- TreeInfo.children(t.asInstanceOf[Tree])
+ def packChildren(t: AnyRef): List[AnyRef] = TreeInfo.children(t.asInstanceOf[Tree])
}
+
+
/**
* A window that can host the Tree widget and provide methods for
* displaying information
@@ -132,16 +136,45 @@ abstract class TreeBrowsers {
* @version 1.0
*/
class BrowserFrame(phaseName: String = "unknown") {
- val frame = new JFrame("Scala AST [" + phaseName + "]")
+ try {
+ UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel")
+ }
+ catch {
+ case _ => UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName())
+ }
+
+ val frame = new JFrame("Scala AST after " + phaseName + " phase")
+ frame.setJMenuBar(new ASTMenuBar())
val topLeftPane = new JPanel(new BorderLayout())
val topRightPane = new JPanel(new BorderLayout())
val bottomPane = new JPanel(new BorderLayout())
var splitPane: JSplitPane = _
- var treeModel: TreeModel = _
-
+ var treeModel: ASTTreeModel = _
+ var jTree: JTree = _
val textArea: JTextArea = new JTextArea(30, 120)
+ textArea.setBorder(BorderFactory.createEmptyBorder(borderSize, borderSize, borderSize, borderSize))
+
val infoPanel = new TextInfoPanel()
+
+ private def setExpansionState(root: JTree, expand: Boolean): Unit = {
+ def _setExpansionState(root: JTree, path: TreePath): Unit = {
+ val last = path.getLastPathComponent
+ for (i <- 0 until root.getModel.getChildCount(last)) {
+ val child = root.getModel.getChild(last, i)
+ val childPath = path pathByAddingChild child
+ _setExpansionState(root, childPath)
+ }
+ if (expand) {jTree expandPath path}
+ else {jTree collapsePath path}
+ }
+ _setExpansionState(root, new TreePath(root.getModel.getRoot))
+ }
+
+ def expandAll(subtree: JTree) = setExpansionState(subtree, true)
+ def collapseAll(subtree: JTree) = setExpansionState(subtree, false)
+
+
/** Create a frame that displays the AST.
*
* @param lock The lock is used in order to stop the compilation thread
@@ -160,7 +193,7 @@ abstract class TreeBrowsers {
override def windowClosed(e: WindowEvent): Unit = lock.release
});
- val tree = new JTree(treeModel) {
+ jTree = new JTree(treeModel) {
/** Return the string for a tree node. */
override def convertValueToText(value: Any, sel: Boolean,
exp: Boolean, leaf: Boolean,
@@ -173,7 +206,7 @@ abstract class TreeBrowsers {
}
}
- tree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
+ jTree.addTreeSelectionListener(new javax.swing.event.TreeSelectionListener() {
def valueChanged(e: javax.swing.event.TreeSelectionEvent): Unit = {
textArea.setText(e.getPath().getLastPathComponent().toString())
infoPanel.update(e.getPath().getLastPathComponent())
@@ -183,9 +216,10 @@ abstract class TreeBrowsers {
val topSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, topLeftPane, topRightPane)
topSplitPane.setResizeWeight(0.5)
- topLeftPane.add(new JScrollPane(tree), BorderLayout.CENTER)
+ jTree.setBorder(
+ BorderFactory.createEmptyBorder(borderSize, borderSize, borderSize, borderSize))
+ topLeftPane.add(new JScrollPane(jTree), BorderLayout.CENTER)
topRightPane.add(new JScrollPane(infoPanel), BorderLayout.CENTER)
-
bottomPane.add(new JScrollPane(textArea), BorderLayout.CENTER)
textArea.setFont(new Font("monospaced", Font.PLAIN, 14))
textArea.setEditable(false)
@@ -196,7 +230,67 @@ abstract class TreeBrowsers {
frame.setVisible(true)
}
- def setTreeModel(tm: TreeModel): Unit = treeModel = tm
+ class ASTMenuBar extends JMenuBar {
+ val menuKey = Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()
+ val shiftKey = InputEvent.SHIFT_MASK
+ val jmFile = new JMenu("File")
+ // val jmiSaveImage = new JMenuItem(
+ // new AbstractAction("Save Tree Image") {
+ // putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_S, menuKey, false))
+ // override def actionPerformed(e: ActionEvent) {
+ // //TODO
+ // }
+ // }
+ // )
+
+ // jmFile add jmiSaveImage
+
+ def closeWindow() = frame.getToolkit().getSystemEventQueue().postEvent(
+ new WindowEvent(frame, WindowEvent.WINDOW_CLOSING))
+
+ val jmiCancel = new JMenuItem (
+ new AbstractAction("Cancel Compilation") {
+ putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_Q, menuKey + shiftKey, false))
+ override def actionPerformed(e: ActionEvent) {
+ closeWindow()
+ global.currentRun.cancel
+ }
+ }
+ )
+ jmFile add jmiCancel
+
+ val jmiExit = new JMenuItem (
+ new AbstractAction("Exit") {
+ putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_Q, menuKey, false))
+ override def actionPerformed(e: ActionEvent) = closeWindow()
+ }
+ )
+ jmFile add jmiExit
+ add(jmFile)
+
+ val jmView = new JMenu("View")
+ val jmiExpand = new JMenuItem(
+ new AbstractAction("Expand All Nodes") {
+ putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_E, menuKey, false))
+ override def actionPerformed(e: ActionEvent) {
+ expandAll(jTree)
+ }
+ }
+ )
+ jmView add jmiExpand
+ val jmiCollapse = new JMenuItem(
+ new AbstractAction("Collapse All Nodes") {
+ putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(KeyEvent.VK_L, menuKey, false))
+ override def actionPerformed(e: ActionEvent) {
+ collapseAll(jTree)
+ }
+ }
+ )
+ jmView add jmiCollapse
+ add(jmView)
+ }
+
+ def setTreeModel(tm: ASTTreeModel): Unit = treeModel = tm
}
/**
@@ -204,6 +298,8 @@ abstract class TreeBrowsers {
*/
class TextInfoPanel extends JTextArea(20, 50) {
+ setBorder(BorderFactory.createEmptyBorder(borderSize, borderSize, borderSize, borderSize))
+ setEditable(false)
setFont(new Font("monospaced", Font.PLAIN, 12))
def update(v: AnyRef): Unit = {