interactiveshell.java

来自「Groovy动态语言 运行在JVM中的动态语言 可以方便的处理业务逻辑变化大的业」· Java 代码 · 共 570 行 · 第 1/2 页

JAVA
570
字号
                    case COMMAND_ID_HELP:
                        displayHelp();
                        break;

                    case COMMAND_ID_DISCARD:
                        reset();
                        done = true;
                        break;

                    case COMMAND_ID_DISPLAY:
                        displayStatement();
                        break;

                    case COMMAND_ID_EXPLAIN:
                        explainStatement();
                        break;

                    case COMMAND_ID_BINDING:
                        displayBinding();
                        break;

                    case COMMAND_ID_EXECUTE:
                        if (complete) {
                            done = true;
                        }
                        else {
                            err.println("statement not complete");
                        }
                        break;
                    case COMMAND_ID_DISCARD_LOADED_CLASSES:
                        resetLoadedClasses();
                        break;
                    case COMMAND_ID_INSPECT:
                        inspect();
                        break;
                }

                continue;                                     // <<<< LOOP CONTROL <<<<<<<<
            }

            // Otherwise, it's part of a statement.  If it's just whitespace,
            // we'll just accept it and move on.  Otherwise, parsing is attempted
            // on the cumulated statement text, and errors are reported.  The
            // pending input is accepted or rejected based on that parsing.

            freshen();

            if (pending.trim().length() == 0) {
                accept();
                continue;                                     // <<<< LOOP CONTROL <<<<<<<<
            }

            final String code = current();

            if (parse(code, 1)) {
                accept();
                complete = true;
            }
            else if (error == null) {
                accept();
            }
            else {
                report();
            }

        }

        // Get and return the statement.
        return accepted(complete);
    }

    private void inspect() {
        if (null == lastResult){
            err.println("nothing to inspect (preceding \"go\" missing?)");
            return;
        }
        // this should read: groovy.inspect.swingui.ObjectBrowser.inspect(lastResult)
        // but this doesnt compile since ObjectBrowser.groovy is compiled after this class.
        try {
            Class browserClass = Class.forName("groovy.inspect.swingui.ObjectBrowser");
            Method inspectMethod = browserClass.getMethod("inspect", new Class[]{Object.class});
            inspectMethod.invoke(browserClass, new Object[]{lastResult});
        } catch (Exception e) {
            err.println("cannot invoke ObjectBrowser");
            e.printStackTrace();
        }
    }


    /**
     * Returns the accepted statement as a string.  If not <code>complete</code>,
     * returns the empty string.
     */
    private String accepted(boolean complete) {
        if (complete) {
            return accepted.toString();
        }
        return "";
    }


    /**
     * Returns the current statement, including pending text.
     */
    private String current() {
        return accepted.toString() + pending + "\n";
    }


    /**
     * Accepts the pending text into the statement.
     */
    private void accept() {
        accepted.append(pending).append("\n");
        line += 1;
    }


    /**
     * Clears accepted if stale.
     */
    private void freshen() {
        if (stale) {
            accepted.setLength(0);
            stale = false;
        }
    }


    //---------------------------------------------------------------------------
    // SUPPORT ROUTINES


    /**
     * Attempts to parse the specified code with the specified tolerance.
     * Updates the <code>parser</code> and <code>error</code> members
     * appropriately.  Returns true if the text parsed, false otherwise.
     * The attempts to identify and suppress errors resulting from the
     * unfinished source text.
     */
    private boolean parse(String code, int tolerance) {
        boolean parsed = false;

        parser = null;
        error = null;

        // Create the parser and attempt to parse the text as a top-level statement.
        try {
            parser = SourceUnit.create("groovysh script", code, tolerance);
            parser.parse();

            parsed = true;
        }

        // We report errors other than unexpected EOF to the user.
        catch (CompilationFailedException e) {
            if (parser.getErrorCollector().getErrorCount() > 1 || !parser.failedWithUnexpectedEOF()) {
                error = e;
            }
        }
        catch (Exception e) {
            error = e;
        }

        return parsed;
    }


    /**
     * Reports the last parsing error to the user.
     */

    private void report() {
        err.println("Discarding invalid text:");
        new ErrorReporter(error, false).write(err);
    }

    //-----------------------------------------------------------------------
    // COMMANDS

    private static final int COMMAND_ID_EXIT = 0;
    private static final int COMMAND_ID_HELP = 1;
    private static final int COMMAND_ID_DISCARD = 2;
    private static final int COMMAND_ID_DISPLAY = 3;
    private static final int COMMAND_ID_EXPLAIN = 4;
    private static final int COMMAND_ID_EXECUTE = 5;
    private static final int COMMAND_ID_BINDING = 6;
    private static final int COMMAND_ID_DISCARD_LOADED_CLASSES = 7;
    private static final int COMMAND_ID_INSPECT = 8;

    private static final int LAST_COMMAND_ID = 8;

    private static final String[] COMMANDS = { "exit", "help", "discard", "display", "explain", "execute", "binding", "discardclasses", "inspect" };

    private static final Map COMMAND_MAPPINGS = new HashMap();

    static {
        for (int i = 0; i <= LAST_COMMAND_ID; i++) {
            COMMAND_MAPPINGS.put(COMMANDS[i], new Integer(i));
        }

        // A few synonyms

        COMMAND_MAPPINGS.put("quit", new Integer(COMMAND_ID_EXIT));
        COMMAND_MAPPINGS.put("go", new Integer(COMMAND_ID_EXECUTE));
    }

    private static final Map COMMAND_HELP = new HashMap();

    static {
        COMMAND_HELP.put(COMMANDS[COMMAND_ID_EXIT],    "exit/quit         - terminates processing");
        COMMAND_HELP.put(COMMANDS[COMMAND_ID_HELP],    "help              - displays this help text");
        COMMAND_HELP.put(COMMANDS[COMMAND_ID_DISCARD], "discard           - discards the current statement");
        COMMAND_HELP.put(COMMANDS[COMMAND_ID_DISPLAY], "display           - displays the current statement");
        COMMAND_HELP.put(COMMANDS[COMMAND_ID_EXPLAIN], "explain           - explains the parsing of the current statement (currently disabled)");
        COMMAND_HELP.put(COMMANDS[COMMAND_ID_EXECUTE], "execute/go        - temporary command to cause statement execution");
        COMMAND_HELP.put(COMMANDS[COMMAND_ID_BINDING], "binding           - shows the binding used by this interactive shell");
        COMMAND_HELP.put(COMMANDS[COMMAND_ID_DISCARD_LOADED_CLASSES],
                                                       "discardclasses    - discards all former unbound class definitions");
        COMMAND_HELP.put(COMMANDS[COMMAND_ID_INSPECT], "inspect           - opens ObjectBrowser on expression returned from previous \"go\"");
    }


    /**
     * Displays help text about available commands.
     */
    private void displayHelp() {
        out.println("Available commands (must be entered without extraneous characters):");
        for (int i = 0; i <= LAST_COMMAND_ID; i++) {
            out.println((String) COMMAND_HELP.get(COMMANDS[i]));
        }
    }


    /**
     * Displays the accepted statement.
     */
    private void displayStatement() {
        final String[] lines = accepted.toString().split("\n");
        for (int i = 0; i < lines.length; i++) {
            out.println((i + 1) + "> " + lines[i]);
        }
    }

    /**
     * Displays the current binding used when instanciating the shell.
     */
    private void displayBinding() {
        out.println("Available variables in the current binding");
        Binding context = shell.getContext();
        Map variables = context.getVariables();
        Set set = variables.keySet();
        if (set.isEmpty()) {
            out.println("The current binding is empty.");
        }
        else {
            for (Iterator it = set.iterator(); it.hasNext();) {
                String key = (String) it.next();
                out.println(key + " = " + variables.get(key));
            }
        }
    }


    /**
     * Attempts to parse the accepted statement and display the
     * parse tree for it.
     */
    private void explainStatement() {
        if (parse(accepted(true), 10) || error == null) {
            out.println("Parse tree:");
            //out.println(tree);
        }
        else {
            out.println("Statement does not parse");
        }
    }

    private void resetLoadedClasses() {
        shell.resetLoadedClasses();
        out.println("all former unbound class definitions are discarded");
    }
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?