Repository: groovy Updated Branches: refs/heads/master b8e4a5bc8 -> 613822f2b
GROOVY-7893: LexerFrame could be made more general purpose and made accessible from GroovyConsole (closes #375) Project: http://git-wip-us.apache.org/repos/asf/groovy/repo Commit: http://git-wip-us.apache.org/repos/asf/groovy/commit/613822f2 Tree: http://git-wip-us.apache.org/repos/asf/groovy/tree/613822f2 Diff: http://git-wip-us.apache.org/repos/asf/groovy/diff/613822f2 Branch: refs/heads/master Commit: 613822f2ba22c5d95680c7019a9ce2d1539db034 Parents: b8e4a5b Author: paulk <pa...@asert.com.au> Authored: Fri Jul 29 18:40:10 2016 +1000 Committer: paulk <pa...@asert.com.au> Committed: Sat Jul 30 09:57:27 2016 +1000 ---------------------------------------------------------------------- .../org/codehaus/groovy/antlr/LexerFrame.java | 128 ++++++++++++++----- .../src/main/groovy/groovy/ui/Console.groovy | 6 + .../main/groovy/groovy/ui/ConsoleActions.groovy | 7 + .../groovy/groovy/ui/view/BasicMenuBar.groovy | 1 + .../groovy/groovy/ui/view/MacOSXMenuBar.groovy | 1 + 5 files changed, 110 insertions(+), 33 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/groovy/blob/613822f2/src/main/org/codehaus/groovy/antlr/LexerFrame.java ---------------------------------------------------------------------- diff --git a/src/main/org/codehaus/groovy/antlr/LexerFrame.java b/src/main/org/codehaus/groovy/antlr/LexerFrame.java index 0a1cb2b..046fd17 100644 --- a/src/main/org/codehaus/groovy/antlr/LexerFrame.java +++ b/src/main/org/codehaus/groovy/antlr/LexerFrame.java @@ -20,8 +20,12 @@ package org.codehaus.groovy.antlr; import antlr.CharScanner; import antlr.Token; +import org.codehaus.groovy.antlr.java.JavaLexer; +import org.codehaus.groovy.antlr.java.JavaTokenTypes; import org.codehaus.groovy.antlr.parser.GroovyLexer; import org.codehaus.groovy.antlr.parser.GroovyTokenTypes; +import org.codehaus.groovy.runtime.IOGroovyMethods; +import org.codehaus.groovy.runtime.ResourceGroovyMethods; import javax.swing.*; import javax.swing.border.Border; @@ -32,9 +36,9 @@ import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.File; -import java.io.FileInputStream; import java.io.FileReader; -import java.io.InputStream; +import java.io.Reader; +import java.io.StringReader; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import java.util.Hashtable; @@ -53,30 +57,60 @@ public class LexerFrame extends JFrame implements ActionListener { private final Class lexerClass; private final Hashtable tokens = new Hashtable(); + /** + * Constructor used when invoking as a standalone application + * + * @param lexerClass the lexer class to use + * @param tokenTypesClass the lexer token types class + */ public LexerFrame(Class lexerClass, Class tokenTypesClass) { + this(lexerClass, tokenTypesClass, null); + } + + /** + * Constructor used when invoking for a specific file + * + * @param lexerClass the lexer class to use + * @param tokenTypesClass the lexer token types class + */ + public LexerFrame(Class lexerClass, Class tokenTypesClass, Reader reader) { super("Token Steam Viewer"); this.lexerClass = lexerClass; try { - jbInit(); + jbInit(reader); setSize(500, 500); listTokens(tokenTypesClass); - final JPopupMenu popup = new JPopupMenu(); - popup.add(loadFileAction); - - jbutton.setSize(30, 30); - jbutton.addMouseListener(new MouseAdapter() { - public void mouseReleased(MouseEvent e) { - //if(e.isPopupTrigger()) - popup.show(scriptPane, e.getX(), e.getY()); - } - }); - setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); + if (reader == null) { + final JPopupMenu popup = new JPopupMenu(); + popup.add(loadFileAction); + jbutton.setSize(30, 30); + jbutton.addMouseListener(new MouseAdapter() { + public void mouseReleased(MouseEvent e) { + //if(e.isPopupTrigger()) + popup.show(scriptPane, e.getX(), e.getY()); + } + }); + } else { + safeScanScript(reader); + } + + setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); } catch (Exception e) { e.printStackTrace(); } } + /** + * Creates a Groovy language LexerFrame for the given script text + * + * @param scriptText the Groovy source file to parse/render + * @return the new frame rending the parsed tokens + */ + public static LexerFrame groovyScriptFactory(String scriptText) { + return new LexerFrame(GroovyLexer.class, GroovyTokenTypes.class, new StringReader(scriptText)); + } + private void listTokens(Class tokenTypes) throws Exception { for (Field field : tokenTypes.getDeclaredFields()) { tokens.put(field.get(null), field.getName()); @@ -98,28 +132,40 @@ public class LexerFrame extends JFrame implements ActionListener { } } - private Action loadFileAction = new AbstractAction("Open File...") { + private final Action loadFileAction = new AbstractAction("Open File...") { public void actionPerformed(ActionEvent ae) { final JFileChooser jfc = new JFileChooser(); final int response = jfc.showOpenDialog(LexerFrame.this); if (response != JFileChooser.APPROVE_OPTION) { return; } - try { - scanScript(jfc.getSelectedFile()); - } catch (final Exception ex) { - ex.printStackTrace(); - } + safeScanScript(jfc.getSelectedFile()); } }; - private void scanScript(final File file) throws Exception { - scriptPane.read(new FileReader(file), null); + private void safeScanScript(File file) { + try { + scanScript(new StringReader(ResourceGroovyMethods.getText(file))); + } catch (final Exception ex) { + ex.printStackTrace(); + } + } + + private void safeScanScript(Reader reader) { + try { + scanScript(reader instanceof StringReader ? (StringReader) reader : new StringReader(IOGroovyMethods.getText(reader))); + } catch (final Exception ex) { + ex.printStackTrace(); + } + } + + private void scanScript(final StringReader reader) throws Exception { + scriptPane.read(reader, null); + reader.reset(); // create lexer - final Constructor constructor = lexerClass.getConstructor(InputStream.class); - final FileInputStream fileInputStream = new FileInputStream(file); - final CharScanner lexer = (CharScanner) constructor.newInstance(fileInputStream); + final Constructor constructor = lexerClass.getConstructor(Reader.class); + final CharScanner lexer = (CharScanner) constructor.newInstance(reader); tokenPane.setEditable(true); tokenPane.setText(""); @@ -142,14 +188,14 @@ public class LexerFrame extends JFrame implements ActionListener { line = token.getLine(); } insertComponent(tokenButton); - if (token.getType() == Token.EOF_TYPE){ + if (token.getType() == Token.EOF_TYPE) { break; } } tokenPane.setEditable(false); tokenPane.setCaretPosition(0); - fileInputStream.close(); + reader.close(); } private void insertComponent(JComponent comp) { @@ -166,8 +212,8 @@ public class LexerFrame extends JFrame implements ActionListener { tokenPane.insertComponent(comp); } - private void jbInit() throws Exception { - final Border border1 = BorderFactory.createEmptyBorder(); + private void jbInit(Reader reader) throws Exception { + final Border border = BorderFactory.createEmptyBorder(); jSplitPane1.setOrientation(JSplitPane.VERTICAL_SPLIT); tokenPane.setEditable(false); tokenPane.setText(""); @@ -175,11 +221,13 @@ public class LexerFrame extends JFrame implements ActionListener { scriptPane.setEditable(false); scriptPane.setMargin(new Insets(5, 5, 5, 5)); scriptPane.setText(""); - jScrollPane1.setBorder(border1); - jScrollPane2.setBorder(border1); + jScrollPane1.setBorder(border); + jScrollPane2.setBorder(border); jSplitPane1.setMinimumSize(new Dimension(800, 600)); mainPanel.add(jSplitPane1, BorderLayout.CENTER); - mainPanel.add(jbutton, BorderLayout.NORTH); + if (reader == null) { + mainPanel.add(jbutton, BorderLayout.NORTH); + } this.getContentPane().add(mainPanel); jSplitPane1.add(jScrollPane1, JSplitPane.LEFT); jScrollPane1.getViewport().add(tokenPane, null); @@ -197,7 +245,21 @@ public class LexerFrame extends JFrame implements ActionListener { } catch (Exception ignore) { // Ignore } - new LexerFrame(GroovyLexer.class, GroovyTokenTypes.class).setVisible(true); + LexerFrame lexerFrame = null; + if (args.length == 0) { + lexerFrame = new LexerFrame(GroovyLexer.class, GroovyTokenTypes.class); + } else if (args.length > 1) { + System.err.println("usage: java LexerFrame [filename.ext]"); + System.exit(1); + } else { + String filename = args[0]; + if (filename.endsWith(".java")) { + lexerFrame = new LexerFrame(JavaLexer.class, JavaTokenTypes.class, new FileReader(filename)); + } else { + lexerFrame = new LexerFrame(GroovyLexer.class, GroovyTokenTypes.class, new FileReader(filename)); + } + } + lexerFrame.setVisible(true); } private static class HScrollableTextPane extends JTextPane { http://git-wip-us.apache.org/repos/asf/groovy/blob/613822f2/subprojects/groovy-console/src/main/groovy/groovy/ui/Console.groovy ---------------------------------------------------------------------- diff --git a/subprojects/groovy-console/src/main/groovy/groovy/ui/Console.groovy b/subprojects/groovy-console/src/main/groovy/groovy/ui/Console.groovy index 40348ca..6c3ce54 100644 --- a/subprojects/groovy-console/src/main/groovy/groovy/ui/Console.groovy +++ b/subprojects/groovy-console/src/main/groovy/groovy/ui/Console.groovy @@ -22,6 +22,7 @@ import groovy.inspect.swingui.ObjectBrowser import groovy.inspect.swingui.AstBrowser import groovy.swing.SwingBuilder import groovy.ui.text.FindReplaceUtility +import org.codehaus.groovy.antlr.LexerFrame import org.codehaus.groovy.control.messages.SimpleMessage import org.codehaus.groovy.tools.shell.util.MessageSource @@ -883,6 +884,11 @@ class Console implements CaretListener, HyperlinkListener, ComponentListener, Fo new AstBrowser(inputArea, rootElement, shell.getClassLoader()).run({ inputArea.getText() } ) } + void inspectTokens(EventObject evt = null) { + def lf = LexerFrame.groovyScriptFactory(inputArea.getText()) + lf.visible = true + } + void largerFont(EventObject evt = null) { updateFontSize(inputArea.font.size + 2) } http://git-wip-us.apache.org/repos/asf/groovy/blob/613822f2/subprojects/groovy-console/src/main/groovy/groovy/ui/ConsoleActions.groovy ---------------------------------------------------------------------- diff --git a/subprojects/groovy-console/src/main/groovy/groovy/ui/ConsoleActions.groovy b/subprojects/groovy-console/src/main/groovy/groovy/ui/ConsoleActions.groovy index 277561d..86d450b 100644 --- a/subprojects/groovy-console/src/main/groovy/groovy/ui/ConsoleActions.groovy +++ b/subprojects/groovy-console/src/main/groovy/groovy/ui/ConsoleActions.groovy @@ -255,6 +255,13 @@ inspectAstAction = action( accelerator: shortcut('T'), ) +inspectTokensAction = action( + name: 'Inspect Tokens', + closure: controller.&inspectTokens, + mnemonic: 'T', + accelerator: shortcut('K'), +) + captureStdOutAction = action( name: 'Capture Standard Output', closure: controller.&captureStdOut, http://git-wip-us.apache.org/repos/asf/groovy/blob/613822f2/subprojects/groovy-console/src/main/groovy/groovy/ui/view/BasicMenuBar.groovy ---------------------------------------------------------------------- diff --git a/subprojects/groovy-console/src/main/groovy/groovy/ui/view/BasicMenuBar.groovy b/subprojects/groovy-console/src/main/groovy/groovy/ui/view/BasicMenuBar.groovy index d951b45..b667a75 100644 --- a/subprojects/groovy-console/src/main/groovy/groovy/ui/view/BasicMenuBar.groovy +++ b/subprojects/groovy-console/src/main/groovy/groovy/ui/view/BasicMenuBar.groovy @@ -91,6 +91,7 @@ menuBar { menuItem(inspectLastAction) menuItem(inspectVariablesAction) menuItem(inspectAstAction) + menuItem(inspectTokensAction) } menu(text: 'Help', mnemonic: 'H') { http://git-wip-us.apache.org/repos/asf/groovy/blob/613822f2/subprojects/groovy-console/src/main/groovy/groovy/ui/view/MacOSXMenuBar.groovy ---------------------------------------------------------------------- diff --git a/subprojects/groovy-console/src/main/groovy/groovy/ui/view/MacOSXMenuBar.groovy b/subprojects/groovy-console/src/main/groovy/groovy/ui/view/MacOSXMenuBar.groovy index 9753f7b..1461f7b 100644 --- a/subprojects/groovy-console/src/main/groovy/groovy/ui/view/MacOSXMenuBar.groovy +++ b/subprojects/groovy-console/src/main/groovy/groovy/ui/view/MacOSXMenuBar.groovy @@ -124,6 +124,7 @@ menuBar { menuItem(inspectLastAction, icon:null) menuItem(inspectVariablesAction, icon:null) menuItem(inspectAstAction, icon:null) + menuItem(inspectTokensAction, icon:null) } }