📄 dim.java
字号:
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- * * The contents of this file are subject to the Netscape Public * License Version 1.1 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.mozilla.org/NPL/ * * Software distributed under the License is distributed on an "AS * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or * implied. See the License for the specific language governing * rights and limitations under the License. * * The Original Code is Rhino JavaScript Debugger code, released * November 21, 2000. * * The Initial Developer of the Original Code is SeeBeyond Corporation. * Portions created by SeeBeyond are * Copyright (C) 2000 SeeBeyond Technology Corporation. All * Rights Reserved. * * Contributor(s): * Igor Bukanov * Matt Gould * Christopher Oliver * * Alternatively, the contents of this file may be used under the * terms of the GNU Public License (the "GPL"), in which case the * provisions of the GPL are applicable instead of those above. * If you wish to allow use of your version of this file only * under the terms of the GPL and not to allow others to use your * version of this file under the NPL, indicate your decision by * deleting the provisions above and replace them with the notice * and other provisions required by the GPL. If you do not delete * the provisions above, a recipient may use your version of this * file under either the NPL or the GPL. */package org.mozilla.javascript.tools.debugger;import org.mozilla.javascript.*;import org.mozilla.javascript.debug.*;import java.util.*;import java.io.*;import java.net.URL;/** * Dim or Debugger Implementation for Rhino.*/class Dim { static final int STEP_OVER = 0; static final int STEP_INTO = 1; static final int STEP_OUT = 2; static final int GO = 3; static final int BREAK = 4; static final int EXIT = 5; GuiCallback callback; boolean breakFlag = false; ScopeProvider scopeProvider; int frameIndex = -1; private volatile ContextData interruptedContextData = null; ContextFactory contextFactory; private Object monitor = new Object(); private Object eventThreadMonitor = new Object(); private volatile int returnValue = -1; private boolean insideInterruptLoop; private String evalRequest; private StackFrame evalFrame; private String evalResult; boolean breakOnExceptions; boolean breakOnEnter; boolean breakOnReturn; private final Hashtable urlToSourceInfo = new Hashtable(); private final Hashtable functionNames = new Hashtable(); private final Hashtable functionToSource = new Hashtable(); static class ContextData { static ContextData get(Context cx) { return (ContextData)cx.getDebuggerContextData(); } int frameCount() { return frameStack.size(); } StackFrame getFrame(int frameNumber) { return (StackFrame) frameStack.get(frameStack.size() - frameNumber - 1); } void pushFrame(StackFrame frame) { frameStack.push(frame); } void popFrame() { frameStack.pop(); } ObjArray frameStack = new ObjArray(); boolean breakNextLine; int stopAtFrameDepth = -1; boolean eventThreadFlag; Throwable lastProcessedException; } static class StackFrame implements DebugFrame { StackFrame(Context cx, Dim dim, FunctionSource fsource) { this.dim = dim; this.contextData = ContextData.get(cx); this.fsource = fsource; this.breakpoints = fsource.sourceInfo().breakpoints; this.lineNumber = fsource.firstLine(); } public void onEnter(Context cx, Scriptable scope, Scriptable thisObj, Object[] args) { contextData.pushFrame(this); this.scope = scope; this.thisObj = thisObj; if (dim.breakOnEnter) { dim.handleBreakpointHit(this, cx); } } public void onLineChange(Context cx, int lineno) { this.lineNumber = lineno; if (!breakpoints[lineno] && !dim.breakFlag) { boolean lineBreak = contextData.breakNextLine; if (lineBreak && contextData.stopAtFrameDepth >= 0) { lineBreak = (contextData.frameCount() <= contextData.stopAtFrameDepth); } if (!lineBreak) { return; } contextData.stopAtFrameDepth = -1; contextData.breakNextLine = false; } dim.handleBreakpointHit(this, cx); } public void onExceptionThrown(Context cx, Throwable exception) { dim.handleExceptionThrown(cx, exception, this); } public void onExit(Context cx, boolean byThrow, Object resultOrException) { if (dim.breakOnReturn && !byThrow) { dim.handleBreakpointHit(this, cx); } contextData.popFrame(); } SourceInfo sourceInfo() { return fsource.sourceInfo(); } ContextData contextData() { return contextData; } Object scope() { return scope; } Object thisObj() { return thisObj; } String getUrl() { return fsource.sourceInfo().url(); } int getLineNumber() { return lineNumber; } private Dim dim; private ContextData contextData; private Scriptable scope; private Scriptable thisObj; private FunctionSource fsource; private boolean[] breakpoints; private int lineNumber; } static class FunctionSource { private SourceInfo sourceInfo; private int firstLine; private String name; FunctionSource(SourceInfo sourceInfo, int firstLine, String name) { if (name == null) throw new IllegalArgumentException(); this.sourceInfo = sourceInfo; this.firstLine = firstLine; this.name = name; } SourceInfo sourceInfo() { return sourceInfo; } int firstLine() { return firstLine; } String name() { return name; } } static class SourceInfo { private String source; private String url; private int minLine; private boolean[] breakableLines; boolean[] breakpoints; private static final boolean[] EMPTY_BOOLEAN_ARRAY = new boolean[0]; private FunctionSource[] functionSources; SourceInfo(String source, DebuggableScript[] functions, String normilizedUrl) { this.source = source; this.url = normilizedUrl; int N = functions.length; int[][] lineArrays = new int[N][]; for (int i = 0; i != N; ++i) { lineArrays[i] = functions[i].getLineNumbers(); } int minAll = 0, maxAll = -1; int[] firstLines = new int[N]; for (int i = 0; i != N; ++i) { int[] lines = lineArrays[i]; if (lines == null || lines.length == 0) { firstLines[i] = -1; } else { int min, max; min = max = lines[0]; for (int j = 1; j != lines.length; ++j) { int line = lines[j]; if (line < min) { min = line; } else if (line > max) { max = line; } } firstLines[i] = min; if (minAll > maxAll) { minAll = min; maxAll = max; } else { if (min < minAll) { minAll = min; } if (max > maxAll) { maxAll = max; } } } } if (minAll > maxAll) { // No line information this.minLine = -1; this.breakableLines = EMPTY_BOOLEAN_ARRAY; this.breakpoints = EMPTY_BOOLEAN_ARRAY; } else { if (minAll < 0) { // Line numbers can not be negative throw new IllegalStateException(String.valueOf(minAll)); } this.minLine = minAll; int linesTop = maxAll + 1; this.breakableLines = new boolean[linesTop]; this.breakpoints = new boolean[linesTop]; for (int i = 0; i != N; ++i) { int[] lines = lineArrays[i]; if (lines != null && lines.length != 0) { for (int j = 0; j != lines.length; ++j) { int line = lines[j]; this.breakableLines[line] = true; } } } } this.functionSources = new FunctionSource[N]; for (int i = 0; i != N; ++i) { String name = functions[i].getFunctionName(); if (name == null) { name = ""; } this.functionSources[i] = new FunctionSource(this, firstLines[i], name); } } String source() { return this.source; } String url() { return this.url; } int functionSourcesTop() { return functionSources.length; } FunctionSource functionSource(int i) { return functionSources[i]; } void copyBreakpointsFrom(SourceInfo old) { int end = old.breakpoints.length; if (end > this.breakpoints.length) { end = this.breakpoints.length; } for (int line = 0; line != end; ++line) { if (old.breakpoints[line]) { this.breakpoints[line] = true; } } } boolean breakableLine(int line) { return (line < this.breakableLines.length) && this.breakableLines[line]; } boolean breakpoint(int line) { if (!breakableLine(line)) { throw new IllegalArgumentException(String.valueOf(line)); } return line < this.breakpoints.length && this.breakpoints[line]; } boolean breakpoint(int line, boolean value) { if (!breakableLine(line)) { throw new IllegalArgumentException(String.valueOf(line));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -