📄 beanshell.java
字号:
try { return _eval(view,namespace,command); } catch(Throwable e) { Log.log(Log.ERROR,BeanShell.class,e); handleException(view,null,e); } return null; } //}}} //{{{ _eval() method /** * Evaluates the specified BeanShell expression. Unlike * <code>eval()</code>, this method passes any exceptions to the caller. * * @param view The view. Within the script, references to * <code>buffer</code>, <code>textArea</code> and <code>editPane</code> * are determined with reference to this parameter. * @param namespace The namespace * @param command The expression * @exception Exception instances are thrown when various BeanShell * errors occur * @since jEdit 3.2pre7 */ public static Object _eval(View view, NameSpace namespace, String command) throws Exception { Interpreter interp = createInterpreter(namespace); try { setupDefaultVariables(namespace,view); if(Debug.BEANSHELL_DEBUG) Log.log(Log.DEBUG,BeanShell.class,command); return interp.eval(command); } catch(Exception e) { unwrapException(e); // never called return null; } finally { try { resetDefaultVariables(namespace); } catch(UtilEvalError e) { // do nothing } } } //}}} //{{{ cacheBlock() method /** * Caches a block of code, returning a handle that can be passed to * runCachedBlock(). * @param id An identifier. If null, a unique identifier is generated * @param code The code * @param namespace If true, the namespace will be set * @exception Exception instances are thrown when various BeanShell errors * occur * @since jEdit 4.1pre1 */ public static BshMethod cacheBlock(String id, String code, boolean namespace) throws Exception { String name = "__internal_" + id; // evaluate a method declaration if(namespace) { _eval(null,global,name + "(ns) {\nthis.callstack.set(0,ns);\n" + code + "\n}"); return global.getMethod(name,new Class[] { NameSpace.class }); } else { _eval(null,global,name + "() {\n" + code + "\n}"); return global.getMethod(name,new Class[0]); } } //}}} //{{{ runCachedBlock() method /** * Runs a cached block of code in the specified namespace. Faster than * evaluating the block each time. * @param method The method instance returned by cacheBlock() * @param view The view * @param namespace The namespace to run the code in * @exception Exception instances are thrown when various BeanShell * errors occur * @since jEdit 4.1pre1 */ public static Object runCachedBlock(BshMethod method, View view, NameSpace namespace) throws Exception { boolean useNamespace; if(namespace == null) { useNamespace = false; namespace = global; } else useNamespace = true; try { setupDefaultVariables(namespace,view); Object retVal = method.invoke(useNamespace ? new Object[] { namespace } : NO_ARGS, interpForMethods,new CallStack()); if(retVal instanceof Primitive) { if(retVal == Primitive.VOID) return null; else return ((Primitive)retVal).getValue(); } else return retVal; } catch(Exception e) { unwrapException(e); // never called return null; } finally { resetDefaultVariables(namespace); } } //}}} //{{{ isScriptRunning() method /** * Returns if a BeanShell script or macro is currently running. * @since jEdit 2.7pre2 */ public static boolean isScriptRunning() { return running; } //}}} //{{{ getNameSpace() method /** * Returns the global namespace. * @since jEdit 3.2pre5 */ public static NameSpace getNameSpace() { return global; } //}}} //{{{ Deprecated functions //{{{ runScript() method /** * @deprecated The <code>rethrowBshErrors</code> parameter is now * obsolete; call <code>_runScript()</code> or <code>runScript()</code> * instead. */ public static void runScript(View view, String path, boolean ownNamespace, boolean rethrowBshErrors) { runScript(view,path,null,ownNamespace); } //}}} //{{{ runScript() method /** * @deprecated The <code>rethrowBshErrors</code> parameter is now * obsolete; call <code>_runScript()</code> or <code>runScript()</code> * instead. */ public static void runScript(View view, String path, Reader in, boolean ownNamespace, boolean rethrowBshErrors) { runScript(view,path,in,ownNamespace); } //}}} //{{{ eval() method /** * @deprecated The <code>rethrowBshErrors</code> parameter is now * obsolete; call <code>_eval()</code> or <code>eval()</code> instead. */ public static Object eval(View view, String command, boolean rethrowBshErrors) { return eval(view,global,command); } //}}} //{{{ eval() method /** * @deprecated The <code>rethrowBshErrors</code> parameter is now * obsolete; call <code>_eval()</code> or <code>eval()</code> instead. */ public static Object eval(View view, NameSpace namespace, String command, boolean rethrowBshErrors) { return eval(view,namespace,command); } //}}} //}}} //{{{ Package-private members //{{{ init() method static void init() { try { NameSpace.class.getMethod("addCommandPath", new Class[] { String.class, Class.class }); } catch(Exception e) { Log.log(Log.ERROR,BeanShell.class,"You have BeanShell version " + Interpreter.VERSION + " in your CLASSPATH."); Log.log(Log.ERROR,BeanShell.class,"Please remove it from the CLASSPATH since jEdit can only run with the bundled BeanShell version " + REQUIRED_VERSION); System.exit(1); } classManager = new CustomClassManager(); classManager.setClassLoader(new JARClassLoader()); global = new NameSpace(classManager, "jEdit embedded BeanShell interpreter"); global.importPackage("org.gjt.sp.jedit"); global.importPackage("org.gjt.sp.jedit.browser"); global.importPackage("org.gjt.sp.jedit.buffer"); global.importPackage("org.gjt.sp.jedit.gui"); global.importPackage("org.gjt.sp.jedit.help"); global.importPackage("org.gjt.sp.jedit.io"); global.importPackage("org.gjt.sp.jedit.menu"); global.importPackage("org.gjt.sp.jedit.msg"); global.importPackage("org.gjt.sp.jedit.options"); global.importPackage("org.gjt.sp.jedit.pluginmgr"); global.importPackage("org.gjt.sp.jedit.print"); global.importPackage("org.gjt.sp.jedit.search"); global.importPackage("org.gjt.sp.jedit.syntax"); global.importPackage("org.gjt.sp.jedit.textarea"); global.importPackage("org.gjt.sp.util"); interpForMethods = createInterpreter(global); } //}}} //{{{ resetClassManager() method /** * Causes BeanShell internal structures to drop references to cached * Class instances. */ static void resetClassManager() { classManager.reset(); } //}}} //}}} //{{{ Private members //{{{ Static variables private static final Object[] NO_ARGS = new Object[0]; private static CustomClassManager classManager; private static Interpreter interpForMethods; private static NameSpace global; private static boolean running; //}}} //{{{ setupDefaultVariables() method private static void setupDefaultVariables(NameSpace namespace, View view) throws UtilEvalError { if(view != null) { EditPane editPane = view.getEditPane(); namespace.setVariable("view",view); namespace.setVariable("editPane",editPane); namespace.setVariable("buffer",editPane.getBuffer()); namespace.setVariable("textArea",editPane.getTextArea()); namespace.setVariable("wm",view.getDockableWindowManager()); } } //}}} //{{{ resetDefaultVariables() method private static void resetDefaultVariables(NameSpace namespace) throws UtilEvalError { namespace.setVariable("view",null); namespace.setVariable("editPane",null); namespace.setVariable("buffer",null); namespace.setVariable("textArea",null); namespace.setVariable("wm",null); } //}}} //{{{ unwrapException() method /** * This extracts an exception from a 'wrapping' exception, as BeanShell * sometimes throws. This gives the user a more accurate error traceback */ private static void unwrapException(Exception e) throws Exception { if(e instanceof TargetError) { Throwable t = ((TargetError)e).getTarget(); if(t instanceof Exception) throw (Exception)t; else if(t instanceof Error) throw (Error)t; } if(e instanceof InvocationTargetException) { Throwable t = ((InvocationTargetException)e).getTargetException(); if(t instanceof Exception) throw (Exception)t; else if(t instanceof Error) throw (Error)t; } throw e; } //}}} //{{{ handleException() method private static void handleException(View view, String path, Throwable t) { if(t instanceof IOException) { VFSManager.error(view,path,"ioerror.read-error", new String[] { t.toString() }); } else new BeanShellErrorDialog(view,t); } //}}} //{{{ createInterpreter() method private static Interpreter createInterpreter(NameSpace nameSpace) { return new Interpreter(null,System.out,System.err,false,nameSpace); } //}}} //}}} //{{{ CustomClassManager class static class CustomClassManager extends BshClassManager { private LinkedList listeners = new LinkedList(); private ReferenceQueue refQueue = new ReferenceQueue(); // copy and paste from bsh/classpath/ClassManagerImpl.java... public synchronized void addListener( Listener l ) { listeners.add( new WeakReference( l, refQueue) ); // clean up old listeners Reference deadref; while ( (deadref = refQueue.poll()) != null ) { boolean ok = listeners.remove( deadref ); if ( ok ) { //System.err.println("cleaned up weak ref: "+deadref); } else { if ( Interpreter.DEBUG ) Interpreter.debug( "tried to remove non-existent weak ref: "+deadref); } } } public void removeListener( Listener l ) { throw new Error("unimplemented"); } public void reset() { classLoaderChanged(); } protected synchronized void classLoaderChanged() { // clear the static caches in BshClassManager clearCaches(); for (Iterator iter = listeners.iterator(); iter.hasNext(); ) { WeakReference wr = (WeakReference) iter.next(); Listener l = (Listener)wr.get(); if ( l == null ) // garbage collected iter.remove(); else l.classLoaderChanged(); } } } //}}}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -