You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@groovy.apache.org by pa...@apache.org on 2016/07/17 06:05:26 UTC
groovy git commit: GROOVY-5501: When inspecting the AST,
it would be nice to have the node metadata properties listed too
(based on PR 54 from the old repo)
Repository: groovy
Updated Branches:
refs/heads/master 9efebf173 -> 5ec4de266
GROOVY-5501: When inspecting the AST, it would be nice to have the node metadata properties listed too (based on PR 54 from the old repo)
Project: http://git-wip-us.apache.org/repos/asf/groovy/repo
Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/5ec4de26
Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/5ec4de26
Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/5ec4de26
Branch: refs/heads/master
Commit: 5ec4de266b6511cf955e44f204499486f198db84
Parents: 9efebf1
Author: paulk <pa...@asert.com.au>
Authored: Sun Jul 17 16:05:10 2016 +1000
Committer: paulk <pa...@asert.com.au>
Committed: Sun Jul 17 16:05:10 2016 +1000
----------------------------------------------------------------------
gradle/pomconfigurer.gradle | 3 +
src/main/org/codehaus/groovy/ast/ASTNode.java | 4 +
.../groovy/inspect/swingui/AstBrowser.groovy | 95 +++++++++++++-------
.../swingui/ButtonOrDefaultRenderer.groovy | 40 +++++++++
.../inspect/swingui/ButtonOrTextEditor.groovy | 62 +++++++++++++
5 files changed, 171 insertions(+), 33 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/groovy/blob/5ec4de26/gradle/pomconfigurer.gradle
----------------------------------------------------------------------
diff --git a/gradle/pomconfigurer.gradle b/gradle/pomconfigurer.gradle
index ad92275..9495481 100644
--- a/gradle/pomconfigurer.gradle
+++ b/gradle/pomconfigurer.gradle
@@ -570,6 +570,9 @@ project.ext.pomConfigureClosureWithoutTweaks = {
contributor {
name 'Pap L\u0151rinc'
}
+ contributor {
+ name 'Guillaume Balaine'
+ }
}
mailingLists {
mailingList {
http://git-wip-us.apache.org/repos/asf/groovy/blob/5ec4de26/src/main/org/codehaus/groovy/ast/ASTNode.java
----------------------------------------------------------------------
diff --git a/src/main/org/codehaus/groovy/ast/ASTNode.java b/src/main/org/codehaus/groovy/ast/ASTNode.java
index 8874794..c6d238d 100644
--- a/src/main/org/codehaus/groovy/ast/ASTNode.java
+++ b/src/main/org/codehaus/groovy/ast/ASTNode.java
@@ -193,4 +193,8 @@ public class ASTNode {
}
return Collections.unmodifiableMap(metaDataMap);
}
+
+ public ListHashMap getMetaDataMap() {
+ return metaDataMap;
+ }
}
http://git-wip-us.apache.org/repos/asf/groovy/blob/5ec4de26/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/AstBrowser.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/AstBrowser.groovy b/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/AstBrowser.groovy
index 09fb6bb..5d83958 100644
--- a/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/AstBrowser.groovy
+++ b/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/AstBrowser.groovy
@@ -18,12 +18,16 @@
*/
package groovy.inspect.swingui
+import groovy.lang.GroovyClassLoader.ClassCollector
import groovy.swing.SwingBuilder
+import org.codehaus.groovy.ast.ClassNode
+import org.codehaus.groovy.control.CompilationUnit
+import org.codehaus.groovy.control.Phases
+import org.codehaus.groovy.control.SourceUnit
+import org.objectweb.asm.ClassReader
+import org.objectweb.asm.util.TraceClassVisitor
-import java.awt.Cursor
-import java.awt.Font
-import java.awt.event.KeyEvent
-import java.util.prefs.Preferences
+import javax.swing.JFrame
import javax.swing.JSplitPane
import javax.swing.KeyStroke
import javax.swing.UIManager
@@ -34,27 +38,24 @@ import javax.swing.tree.DefaultMutableTreeNode
import javax.swing.tree.DefaultTreeModel
import javax.swing.tree.TreeNode
import javax.swing.tree.TreeSelectionModel
-import org.codehaus.groovy.control.Phases
-
+import java.awt.Cursor
+import java.awt.Font
+import java.awt.event.KeyEvent
+import java.util.prefs.Preferences
import java.util.regex.Pattern
-import static java.awt.GridBagConstraints.*
-import org.codehaus.groovy.ast.ClassNode
-import groovy.lang.GroovyClassLoader.ClassCollector
-import org.codehaus.groovy.control.CompilationUnit
-import org.codehaus.groovy.control.SourceUnit
-import org.objectweb.asm.ClassReader
-import org.objectweb.asm.util.TraceClassVisitor
+import static java.awt.GridBagConstraints.BOTH
+import static java.awt.GridBagConstraints.HORIZONTAL
+import static java.awt.GridBagConstraints.NONE
+import static java.awt.GridBagConstraints.NORTHEAST
+import static java.awt.GridBagConstraints.NORTHWEST
+import static java.awt.GridBagConstraints.WEST
/**
* This object is a GUI for looking at the AST that Groovy generates.
*
* Usage: java groovy.inspect.swingui.AstBrowser [filename]
* where [filename] is an existing Groovy script.
- *
- * @author Hamlet D'Arcy (hamletdrc@gmail.com)
- * @author Guillaume Laforge, highlighting the code corresponding to a node selected in the tree view
- * @author Roshan Dawrani - separated out the swing UI related code from the model part so model could be used for various UIs
*/
class AstBrowser {
@@ -200,11 +201,46 @@ class AstBrowser {
jTree.addTreeSelectionListener({ TreeSelectionEvent e ->
propertyTable.model.rows.clear()
+ propertyTable.columnModel.getColumn(1).cellRenderer = new ButtonOrDefaultRenderer()
+ propertyTable.columnModel.getColumn(1).cellEditor = new ButtonOrTextEditor()
TreeNode node = jTree.lastSelectedPathComponent
if (node instanceof TreeNodeWithProperties) {
-
- node.properties.each {
- propertyTable.model.rows << ['name': it[0], 'value': it[1], 'type': it[2]]
+ def titleSuffix = node.properties.find{ it[0] == 'text' }?.get(1)
+ for (it in node.properties) {
+ def propList = it
+ if (propList[2] == "ListHashMap" && propList[1] != 'null' && propList[1] != '[:]') {
+ //If the class is a ListHashMap, make it accessible in a new frame through a button
+ def btnPanel = swing.button(
+ text: "See key/value pairs",
+ actionPerformed: {
+ def mapTable
+ String title = titleSuffix ? propList[0] + " (" + titleSuffix + ")" : propList[0]
+ swing.frame(title: title, defaultCloseOperation: JFrame.DISPOSE_ON_CLOSE,
+ size: [800, 600], show: true, locationRelativeTo: null ) {
+ lookAndFeel("system")
+ panel {
+ scrollPane() {
+ mapTable = swing.table() {
+ tableModel(list: [[:]]) {
+ propertyColumn(header: 'Name', propertyName: 'name')
+ propertyColumn(header: 'Value', propertyName: 'value')
+ }
+ }
+ }
+ }
+ }
+ mapTable.model.rows.clear()
+ propList[1].substring(1, propList[1].length() - 1).tokenize(',').each {
+ def kv = it.tokenize(':')
+ if (kv)
+ mapTable.model.rows << ["name": kv[0], "value": kv[1]]
+ }
+ })
+ propertyTable.model.rows << ["name": propList[0], "value": btnPanel, "type": propList[2]]
+ btnPanel.updateUI()
+ } else {
+ propertyTable.model.rows << ["name": it[0], "value": it[1], "type": it[2]]
+ }
}
if (inputArea && rootElement) {
@@ -277,7 +313,8 @@ class AstBrowser {
frame.size = prefs.frameSize
splitterPane.dividerLocation = prefs.verticalDividerLocation
mainSplitter.dividerLocation = prefs.horizontalDividerLocation
- frame.show()
+ frame.pack()
+ frame.visible = true
String source = script()
decompile(phasePicker.selectedItem.phaseId, source)
@@ -317,9 +354,11 @@ class AstBrowser {
void showAbout(EventObject evt) {
def pane = swing.optionPane()
- pane.setMessage('An interactive GUI to explore AST capabilities.')
+ def version = GroovySystem.getVersion()
+ pane.setMessage('An interactive GUI to explore AST capabilities\nVersion ' + version)
def dialog = pane.createDialog(frame, 'About Groovy AST Browser')
- dialog.show()
+ dialog.pack()
+ dialog.visible = true
}
void showScriptFreeForm(EventObject evt) {
@@ -401,8 +440,6 @@ class AstBrowser {
/**
* This class sets and restores control positions in the browser.
- *
- * @author Hamlet D'Arcy
*/
class AstBrowserUiPreferences {
@@ -458,8 +495,6 @@ class AstBrowserUiPreferences {
/**
* An adapter for the CompilePhase enum that can be entered into a Swing combobox.
- *
- * @author Hamlet D'Arcy
*/
enum CompilePhaseAdapter {
INITIALIZATION(Phases.INITIALIZATION, 'Initialization'),
@@ -487,8 +522,6 @@ enum CompilePhaseAdapter {
/**
* This class is a TreeNode and you can store additional properties on it.
- *
- * @author Hamlet D'Arcy
*/
class TreeNodeWithProperties extends DefaultMutableTreeNode {
@@ -520,8 +553,6 @@ class TreeNodeWithProperties extends DefaultMutableTreeNode {
/**
* This interface is used to create tree nodes of various types
- *
- * @author Roshan Dawrani
*/
interface AstBrowserNodeMaker<T> {
T makeNode(Object userObject)
@@ -531,8 +562,6 @@ interface AstBrowserNodeMaker<T> {
/**
* Creates tree nodes for swing UI
- *
- * @author Roshan Dawrani
*/
class SwingTreeNodeMaker implements AstBrowserNodeMaker<DefaultMutableTreeNode> {
DefaultMutableTreeNode makeNode(Object userObject) {
http://git-wip-us.apache.org/repos/asf/groovy/blob/5ec4de26/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/ButtonOrDefaultRenderer.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/ButtonOrDefaultRenderer.groovy b/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/ButtonOrDefaultRenderer.groovy
new file mode 100644
index 0000000..00a7f0d
--- /dev/null
+++ b/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/ButtonOrDefaultRenderer.groovy
@@ -0,0 +1,40 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package groovy.inspect.swingui
+
+import javax.swing.JComponent
+import javax.swing.JTable
+import javax.swing.table.DefaultTableCellRenderer
+import java.awt.Component
+
+/**
+ * A table cell renderer that will return a component instead of drawing it,
+ * or call the default in the case of a non component object.
+ * This hack allows to render a button shape in a table cell.
+ */
+class ButtonOrDefaultRenderer extends DefaultTableCellRenderer {
+ Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+ if (value instanceof JComponent) {
+ value.setSize(Math.round(value.getSize().getWidth())?.toInteger(), table.getRowHeight(row))
+ return value
+ }
+ return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column)
+ }
+}
http://git-wip-us.apache.org/repos/asf/groovy/blob/5ec4de26/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/ButtonOrTextEditor.groovy
----------------------------------------------------------------------
diff --git a/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/ButtonOrTextEditor.groovy b/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/ButtonOrTextEditor.groovy
new file mode 100644
index 0000000..6253f62
--- /dev/null
+++ b/subprojects/groovy-console/src/main/groovy/groovy/inspect/swingui/ButtonOrTextEditor.groovy
@@ -0,0 +1,62 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package groovy.inspect.swingui
+
+import javax.swing.AbstractCellEditor
+import javax.swing.JButton
+import javax.swing.JComponent
+import javax.swing.JTable
+import javax.swing.JTextArea
+import javax.swing.table.TableCellEditor
+import java.awt.Component
+import java.awt.event.ActionListener
+import java.awt.event.FocusListener
+
+/**
+ * A table cell editor that will return a button automatically if it is the cell value,
+ * a text field if the value exists, or null otherwise (non editable cell).
+ * This hack allows to interact with buttons in a cell.
+ */
+class ButtonOrTextEditor extends AbstractCellEditor implements TableCellEditor {
+ /** The Swing component being edited. */
+ protected JComponent editorComponent
+
+ @Override
+ Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
+ if (value instanceof JButton) {
+ editorComponent = value
+ editorComponent.addActionListener({ fireEditingStopped() } as ActionListener)
+ } else if (value instanceof JTextArea) {
+ editorComponent = value
+ } else if (value) {
+ editorComponent = new JTextArea(value.toString())
+ editorComponent.addFocusListener({ fireEditingCanceled() } as FocusListener)
+ } else {
+ editorComponent = null
+ }
+ editorComponent
+ }
+
+ @Override
+ Object getCellEditorValue() {
+ editorComponent
+ }
+}
+