/* * Copyright (c) 2014 Sam Harwell, Tunnel Vision Laboratories LLC * All rights reserved. * * The source code of this document is proprietary work, and is not licensed for * distribution. For information about licensing, contact Sam Harwell at: * sam@tunnelvisionlabs.com */ package org.antlr.works.editor.grammar.debugger; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import java.io.IOException; import java.util.List; import javax.swing.SwingUtilities; import javax.swing.text.Document; import org.antlr.netbeans.editor.text.DocumentSnapshot; import org.antlr.netbeans.editor.text.VersionedDocumentUtilities; import org.antlr.netbeans.util.NotificationIcons; import org.antlr.works.editor.grammar.GrammarEditorKit; import org.antlr.works.editor.grammar.actions.RunInTestRigAction; import org.antlr.works.editor.grammar.codemodel.FileModel; import org.netbeans.modules.editor.NbEditorUtilities; import org.openide.DialogDisplayer; import org.openide.WizardDescriptor; import org.openide.awt.ActionID; import org.openide.awt.ActionReference; import org.openide.awt.ActionRegistration; import org.openide.awt.NotificationDisplayer; import org.openide.cookies.EditorCookie; import org.openide.cookies.OpenCookie; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileSystem; import org.openide.filesystems.FileUtil; import org.openide.loaders.DataObject; import org.openide.loaders.DataObjectNotFoundException; import org.openide.util.Exceptions; import org.openide.util.NbBundle.Messages; /** * * @author Sam Harwell */ @ActionID( category = "Debug", id = "org.antlr.works.editor.grammar.debugger.InterpretCurrentParserAction") @ActionRegistration( displayName = "#CTL_InterpretCurrentParserAction") @ActionReference(path = "Menu/BuildProject", position = 249, separatorBefore = 223) @Messages("CTL_InterpretCurrentParserAction=Interpret Parser...") public class InterpretCurrentParserAction implements ActionListener { private final EditorCookie context; public InterpretCurrentParserAction(EditorCookie context) { this.context = context; } @Override public void actionPerformed(ActionEvent ev) { Document document = context.getDocument(); if (document == null) { displayError("This command is only valid in the context of a document."); return; } String mimeType = NbEditorUtilities.getMimeType(document); if (!GrammarEditorKit.GRAMMAR_MIME_TYPE.equals(mimeType)) { displayError("This command is only valid for ANTLR grammar files."); return; } if (GrammarEditorKit.isLegacyMode(document)) { displayError("This command is not valid in legacy (ANTLR 3) mode."); return; } WizardDescriptor wizard = new WizardDescriptor(new ParserDebuggerWizardIterator()); wizard.setTitle("{0} ({1})"); wizard.setTitle("Parser Interpreter"); DocumentSnapshot snapshot = VersionedDocumentUtilities.getVersionedDocument(document).getCurrentSnapshot(); FileModel fileModel = RunInTestRigAction.getFileModel(snapshot); List<String> availableRules = RunInTestRigAction.getAvailableRules(fileModel); if (fileModel != null) { String initialStartRule = RunInTestRigAction.getFirstRule(fileModel, true); wizard.putProperty(ParserDebuggerWizardPanel.START_RULE, initialStartRule); } wizard.putProperty(ParserDebuggerWizardPanel.AVAILABLE_RULES, availableRules.toArray(new String[availableRules.size()])); if (DialogDisplayer.getDefault().notify(wizard) != WizardDescriptor.FINISH_OPTION) { return; } ParserInterpreterData parserInterpreterData = ParserInterpreterData.buildFromSnapshot(snapshot); if (parserInterpreterData == null) { displayError("An error occurred while constructing a lexer or parser ATN from the grammar."); return; } File inputFile = new File(ParserDebuggerWizardOptions.getInputFile(wizard)); if (!inputFile.isFile()) { return; } if (inputFile.length() > 1024 * 1024) { displayError("This specified input file is too large. Please choose a file smaller than 1MB."); return; } String startRule = ParserDebuggerWizardOptions.getStartRule(wizard); parserInterpreterData.startRuleIndex = parserInterpreterData.ruleNames.indexOf(startRule); if (parserInterpreterData.startRuleIndex < 0) { displayError(String.format("Could not locate a rule named '%s'", startRule)); return; } try { FileSystem fileSystem = FileUtil.createMemoryFileSystem(); FileObject tempFileObject = FileUtil.copyFile(FileUtil.toFileObject(inputFile), fileSystem.getRoot(), inputFile.getName(), "pinterp"); DataObject od = DataObject.find(tempFileObject); EditorCookie ec = od.getLookup().lookup(EditorCookie.class); Document opened = ec.openDocument(); if (opened != null) { opened.putProperty(ParserDebuggerEditorKit.PROP_LEXER_INTERP_DATA, parserInterpreterData.lexerInterpreterData); opened.putProperty(ParserDebuggerEditorKit.PROP_PARSER_INTERP_DATA, parserInterpreterData); OpenCookie oc = od.getLookup().lookup(OpenCookie.class); if (oc != null) { doOpen(oc); } } } catch (DataObjectNotFoundException ex) { Exceptions.printStackTrace(ex); displayError("An error occurred. See the IDE Log output window for details."); } catch (IOException ex) { Exceptions.printStackTrace(ex); displayError("An error occurred. See the IDE Log output window for details."); } } private void displayError(String message) { NotificationDisplayer.getDefault().notify("Interpret Current Parser", NotificationIcons.ERROR, message, null); } private void doOpen(final OpenCookie oc) { if (SwingUtilities.isEventDispatchThread()) { oc.open(); } else { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { oc.open(); } }); } } }