📄 dim.java
字号:
} boolean changed; synchronized (breakpoints) { if (breakpoints[line] != value) { breakpoints[line] = value; changed = true; } else { changed = false; } } return changed; } void removeAllBreakpoints() { synchronized (breakpoints) { for (int line = 0; line != breakpoints.length; ++line) { breakpoints[line] = false; } } } } private static final int IPROXY_DEBUG = 0; private static final int IPROXY_LISTEN = 1; private static final int IPROXY_COMPILE_SCRIPT = 2; private static final int IPROXY_EVAL_SCRIPT = 3; private static final int IPROXY_STRING_IS_COMPILABLE = 4; private static final int IPROXY_OBJECT_TO_STRING = 5; private static final int IPROXY_OBJECT_PROPERTY = 6; private static final int IPROXY_OBJECT_IDS = 7; /** * Proxy class to implement debug interfaces without bloat of class * files. */ private static class DimIProxy implements ContextAction, ContextFactory.Listener, Debugger { private Dim dim; private int type; String url; String text; Object object; Object id; boolean booleanResult; String stringResult; Object objectResult; Object[] objectArrayResult; DimIProxy(Dim dim, int type) { this.dim = dim; this.type = type; } // ContextAction interface public Object run(Context cx) { switch (type) { case IPROXY_COMPILE_SCRIPT: cx.compileString(text, url, 1, null); break; case IPROXY_EVAL_SCRIPT: { Scriptable scope = null; if (dim.scopeProvider != null) { scope = dim.scopeProvider.getScope(); } if (scope == null) { scope = new ImporterTopLevel(cx); } cx.evaluateString(scope, text, url, 1, null); } break; case IPROXY_STRING_IS_COMPILABLE: booleanResult = cx.stringIsCompilableUnit(text); break; case IPROXY_OBJECT_TO_STRING: if (object == Undefined.instance) { stringResult = "undefined"; } else if (object == null) { stringResult = "null"; } else if (object instanceof NativeCall) { stringResult = "[object Call]"; } else { stringResult = Context.toString(object); } break; case IPROXY_OBJECT_PROPERTY: objectResult = dim.getObjectPropertyImpl(cx, object, id); break; case IPROXY_OBJECT_IDS: objectArrayResult = dim.getObjectIdsImpl(cx, object); break; default: throw Kit.codeBug(); } return null; } void withContext() { dim.contextFactory.call(this); } // ContextFactory.Listener interface public void contextCreated(Context cx) { if (type != IPROXY_LISTEN) Kit.codeBug(); ContextData contextData = new ContextData(); Debugger debugger = new DimIProxy(dim, IPROXY_DEBUG); cx.setDebugger(debugger, contextData); cx.setGeneratingDebug(true); cx.setOptimizationLevel(-1); } public void contextReleased(Context cx) { if (type != IPROXY_LISTEN) Kit.codeBug(); } // Debugger interface public DebugFrame getFrame(Context cx, DebuggableScript fnOrScript) { if (type != IPROXY_DEBUG) Kit.codeBug(); FunctionSource item = dim.getFunctionSource(fnOrScript); if (item == null) { // Can not debug if source is not available return null; } return new StackFrame(cx, dim, item); } public void handleCompilationDone(Context cx, DebuggableScript fnOrScript, String source) { if (type != IPROXY_DEBUG) Kit.codeBug(); if (!fnOrScript.isTopLevel()) { return; } dim.registerTopScript(fnOrScript, source); } } void attachTo(ContextFactory factory) { this.contextFactory = factory; factory.addListener(new DimIProxy(this, IPROXY_LISTEN)); } FunctionSource getFunctionSource(DebuggableScript fnOrScript) { FunctionSource fsource = functionSource(fnOrScript); if (fsource == null) { String url = getNormilizedUrl(fnOrScript); SourceInfo si = sourceInfo(url); if (si == null) { if (!fnOrScript.isGeneratedScript()) { // Not eval or Function, try to load it from URL String source = loadSource(url); if (source != null) { DebuggableScript top = fnOrScript; for (;;) { DebuggableScript parent = top.getParent(); if (parent == null) { break; } top = parent; } registerTopScript(top, source); fsource = functionSource(fnOrScript); } } } } return fsource; } private String loadSource(String sourceUrl) { String source = null; int hash = sourceUrl.indexOf('#'); if (hash >= 0) { sourceUrl = sourceUrl.substring(0, hash); } try { InputStream is; openStream: { if (sourceUrl.indexOf(':') < 0) { // Can be a file name try { if (sourceUrl.startsWith("~/")) { String home = System.getProperty("user.home"); if (home != null) { String pathFromHome = sourceUrl.substring(2); File f = new File(new File(home), pathFromHome); if (f.exists()) { is = new FileInputStream(f); break openStream; } } } File f = new File(sourceUrl); if (f.exists()) { is = new FileInputStream(f); break openStream; } } catch (SecurityException ex) { } // No existing file, assume missed http:// if (sourceUrl.startsWith("//")) { sourceUrl = "http:" + sourceUrl; } else if (sourceUrl.startsWith("/")) { sourceUrl = "http://127.0.0.1" + sourceUrl; } else { sourceUrl = "http://" + sourceUrl; } } is = (new URL(sourceUrl)).openStream(); } try { source = Kit.readReader(new InputStreamReader(is)); } finally { is.close(); } } catch (IOException ex) { System.err.println ("Failed to load source from "+sourceUrl+": "+ ex); } return source; } void registerTopScript(DebuggableScript topScript, String source) { if (!topScript.isTopLevel()) { throw new IllegalArgumentException(); } String url = getNormilizedUrl(topScript); DebuggableScript[] functions = getAllFunctions(topScript); final SourceInfo sourceInfo = new SourceInfo(source, functions, url); synchronized (urlToSourceInfo) { SourceInfo old = (SourceInfo)urlToSourceInfo.get(url); if (old != null) { sourceInfo.copyBreakpointsFrom(old); } urlToSourceInfo.put(url, sourceInfo); for (int i = 0; i != sourceInfo.functionSourcesTop(); ++i) { FunctionSource fsource = sourceInfo.functionSource(i); String name = fsource.name(); if (name.length() != 0) { functionNames.put(name, fsource); } } } synchronized (functionToSource) { for (int i = 0; i != functions.length; ++i) { FunctionSource fsource = sourceInfo.functionSource(i); functionToSource.put(functions[i], fsource); } } callback.updateSourceText(sourceInfo); } FunctionSource functionSource(DebuggableScript fnOrScript) { return (FunctionSource)functionToSource.get(fnOrScript); } String[] functionNames() { String[] a; synchronized (urlToSourceInfo) { Enumeration e = functionNames.keys(); a = new String[functionNames.size()]; int i = 0; while (e.hasMoreElements()) { a[i++] = (String)e.nextElement(); } } return a; } FunctionSource functionSourceByName(String functionName) { return (FunctionSource)functionNames.get(functionName); } SourceInfo sourceInfo(String url) { return (SourceInfo)urlToSourceInfo.get(url); } String getNormilizedUrl(DebuggableScript fnOrScript) { String url = fnOrScript.getSourceName(); if (url == null) { url = "<stdin>"; } else { // Not to produce window for eval from different lines, // strip line numbers, i.e. replace all #[0-9]+\(eval\) by // (eval) // Option: similar teatment for Function? char evalSeparator = '#'; StringBuffer sb = null; int urlLength = url.length(); int cursor = 0; for (;;) { int searchStart = url.indexOf(evalSeparator, cursor); if (searchStart < 0) { break; } String replace = null; int i = searchStart + 1; boolean hasDigits = false; while (i != urlLength) { int c = url.charAt(i); if (!('0' <= c && c <= '9')) { break; } ++i; } if (i != searchStart + 1) { // i points after #[0-9]+ if ("(eval)".regionMatches(0, url, i, 6)) { cursor = i + 6; replace = "(eval)"; } } if (replace == null) { break; } if (sb == null) { sb = new StringBuffer(); sb.append(url.substring(0, searchStart)); } sb.append(replace); } if (sb != null) { if (cursor != urlLength) { sb.append(url.substring(cursor)); } url = sb.toString(); } } return url; } private static DebuggableScript[] getAllFunctions(DebuggableScript function) { ObjArray functions = new ObjArray(); collectFunctions_r(function, functions); DebuggableScript[] result = new DebuggableScript[functions.size()]; functions.toArray(result); return result; } private static void collectFunctions_r(DebuggableScript function, ObjArray array) { array.add(function);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -