зеркало из https://github.com/mozilla/gecko-dev.git
Switch to line info extraction through single top script processing
This commit is contained in:
Родитель
bca4ff3ba4
Коммит
30e9aee832
|
@ -45,15 +45,18 @@ import java.awt.*;
|
|||
import java.awt.event.*;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import org.mozilla.javascript.*;
|
||||
import org.mozilla.javascript.debug.*;
|
||||
import org.mozilla.javascript.tools.shell.ConsoleTextArea;
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import javax.swing.tree.DefaultMutableTreeNode;
|
||||
import javax.swing.tree.DefaultTreeCellRenderer;
|
||||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
|
||||
import org.mozilla.javascript.Scriptable;
|
||||
|
||||
import org.mozilla.javascript.Kit;
|
||||
|
||||
import org.mozilla.javascript.tools.shell.ConsoleTextArea;
|
||||
|
||||
|
||||
class MessageDialogWrapper {
|
||||
|
||||
|
@ -353,8 +356,6 @@ class FilePopupMenu extends JPopupMenu {
|
|||
item.addActionListener(w);
|
||||
add(item = new JMenuItem("Clear Breakpoint"));
|
||||
item.addActionListener(w);
|
||||
//add(item = new JMenuItem("Run to Cursor"));
|
||||
//item.addActionListener(w);
|
||||
add(item = new JMenuItem("Run"));
|
||||
item.addActionListener(w);
|
||||
}
|
||||
|
@ -459,8 +460,6 @@ class FileTextArea extends JTextArea implements ActionListener,
|
|||
w.setBreakPoint(line + 1);
|
||||
} else if (cmd.equals("Clear Breakpoint")) {
|
||||
w.clearBreakPoint(line + 1);
|
||||
} else if (cmd.equals("Run to Cursor")) {
|
||||
w.runToCursor(e);
|
||||
} else if (cmd.equals("Run")) {
|
||||
w.load();
|
||||
}
|
||||
|
@ -608,7 +607,6 @@ class MoreWindows extends JDialog implements ActionListener {
|
|||
class FindFunction extends JDialog implements ActionListener {
|
||||
private String value = null;
|
||||
private JList list;
|
||||
Hashtable functionNames;
|
||||
DebugGui debugGui;
|
||||
JButton setButton;
|
||||
JButton refreshButton;
|
||||
|
@ -641,11 +639,11 @@ class FindFunction extends JDialog implements ActionListener {
|
|||
return;
|
||||
}
|
||||
setVisible(false);
|
||||
Main.ScriptItem item = (Main.ScriptItem)functionNames.get(value);
|
||||
Main.FunctionSource item = debugGui.main.functionSourceByName(value);
|
||||
if (item != null) {
|
||||
Main.SourceInfo si = item.getSourceInfo();
|
||||
String url = si.getUrl();
|
||||
int lineNumber = item.getFirstLine();
|
||||
Main.SourceInfo si = item.sourceInfo();
|
||||
String url = si.url();
|
||||
int lineNumber = item.firstLine();
|
||||
FileWindow w = debugGui.getFileWindow(url);
|
||||
if (w == null) {
|
||||
debugGui.createFileWindow(si, lineNumber);
|
||||
|
@ -676,11 +674,9 @@ class FindFunction extends JDialog implements ActionListener {
|
|||
}
|
||||
};
|
||||
|
||||
FindFunction(DebugGui debugGui, Hashtable functionNames,
|
||||
String title,
|
||||
String labelText) {
|
||||
FindFunction(DebugGui debugGui, String title, String labelText)
|
||||
{
|
||||
super(debugGui, title, true);
|
||||
this.functionNames = functionNames;
|
||||
this.debugGui = debugGui;
|
||||
|
||||
cancelButton = new JButton("Cancel");
|
||||
|
@ -693,14 +689,9 @@ class FindFunction extends JDialog implements ActionListener {
|
|||
DefaultListModel model = (DefaultListModel)list.getModel();
|
||||
model.clear();
|
||||
|
||||
Enumeration e = functionNames.keys();
|
||||
String[] a = new String[functionNames.size()];
|
||||
int i = 0;
|
||||
while (e.hasMoreElements()) {
|
||||
a[i++] = e.nextElement().toString();
|
||||
}
|
||||
String[] a = debugGui.main.functionNames();
|
||||
java.util.Arrays.sort(a);
|
||||
for (i = 0; i < a.length; i++) {
|
||||
for (int i = 0; i < a.length; i++) {
|
||||
model.addElement(a[i]);
|
||||
}
|
||||
list.setSelectedIndex(0);
|
||||
|
@ -900,24 +891,10 @@ class FileWindow extends JInternalFrame implements ActionListener {
|
|||
}
|
||||
}
|
||||
|
||||
void runToCursor(ActionEvent e) {
|
||||
try {
|
||||
debugGui.runToCursor(getUrl(),
|
||||
textArea.getLineOfOffset(textArea.getCaretPosition()) + 1,
|
||||
e);
|
||||
} catch (BadLocationException exc) {
|
||||
}
|
||||
}
|
||||
|
||||
void load() {
|
||||
Scriptable scope = debugGui.main.getScope();
|
||||
if (scope == null) {
|
||||
MessageDialogWrapper.showMessageDialog(debugGui, "Can't load scripts: no scope available", "Run", JOptionPane.ERROR_MESSAGE);
|
||||
} else {
|
||||
String url = getUrl();
|
||||
if (url != null) {
|
||||
new Thread(new LoadFile(debugGui,scope,url)).start();
|
||||
}
|
||||
String url = getUrl();
|
||||
if (url != null) {
|
||||
new Thread(new LoadFile(debugGui,url,sourceInfo.source())).start();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -931,7 +908,7 @@ class FileWindow extends JInternalFrame implements ActionListener {
|
|||
}
|
||||
|
||||
boolean isBreakPoint(int line) {
|
||||
return sourceInfo.hasBreakpoint(line);
|
||||
return sourceInfo.breakableLine(line) && sourceInfo.breakpoint(line);
|
||||
}
|
||||
|
||||
void toggleBreakPoint(int line) {
|
||||
|
@ -943,19 +920,25 @@ class FileWindow extends JInternalFrame implements ActionListener {
|
|||
}
|
||||
|
||||
void setBreakPoint(int line) {
|
||||
if (sourceInfo.placeBreakpoint(line)) {
|
||||
fileHeader.repaint();
|
||||
if (sourceInfo.breakableLine(line)) {
|
||||
boolean changed = sourceInfo.breakpoint(line, true);
|
||||
if (changed) {
|
||||
fileHeader.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clearBreakPoint(int line) {
|
||||
if (sourceInfo.removeBreakpoint(line)) {
|
||||
fileHeader.repaint();
|
||||
if (sourceInfo.breakableLine(line)) {
|
||||
boolean changed = sourceInfo.breakpoint(line, false);
|
||||
if (changed) {
|
||||
fileHeader.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FileWindow(DebugGui debugGui, Main.SourceInfo sourceInfo) {
|
||||
super(Main.SourceInfo.getShortName(sourceInfo.getUrl()),
|
||||
super(DebugGui.getShortName(sourceInfo.url()),
|
||||
true, true, true, true);
|
||||
this.debugGui = debugGui;
|
||||
this.sourceInfo = sourceInfo;
|
||||
|
@ -970,7 +953,7 @@ class FileWindow extends JInternalFrame implements ActionListener {
|
|||
p.setRowHeaderView(fileHeader);
|
||||
setContentPane(p);
|
||||
pack();
|
||||
updateText();
|
||||
updateText(sourceInfo);
|
||||
textArea.select(0);
|
||||
}
|
||||
|
||||
|
@ -984,11 +967,12 @@ class FileWindow extends JInternalFrame implements ActionListener {
|
|||
}
|
||||
|
||||
public String getUrl() {
|
||||
return sourceInfo.getUrl();
|
||||
return sourceInfo.url();
|
||||
}
|
||||
|
||||
void updateText() {
|
||||
String newText = sourceInfo.getSource();
|
||||
void updateText(Main.SourceInfo sourceInfo) {
|
||||
this.sourceInfo = sourceInfo;
|
||||
String newText = sourceInfo.source();
|
||||
if (!textArea.getText().equals(newText)) {
|
||||
textArea.setText(newText);
|
||||
int pos = 0;
|
||||
|
@ -1737,7 +1721,7 @@ class Menubar extends JMenuBar implements ActionListener
|
|||
count--;
|
||||
windowMenu.remove(lastItem);
|
||||
}
|
||||
String shortName = Main.SourceInfo.getShortName(url);
|
||||
String shortName = DebugGui.getShortName(url);
|
||||
|
||||
windowMenu.add(item = new JMenuItem((char)('0' + (count-4)) + " " + shortName, '0' + (count - 4)));
|
||||
if (hasMoreWin) {
|
||||
|
@ -1754,63 +1738,49 @@ class Menubar extends JMenuBar implements ActionListener
|
|||
|
||||
class OpenFile implements Runnable
|
||||
{
|
||||
String fileName;
|
||||
DebugGui debugGui;
|
||||
OpenFile(DebugGui debugGui, String fileName)
|
||||
String fileName;
|
||||
String text;
|
||||
|
||||
OpenFile(DebugGui debugGui, String fileName, String text)
|
||||
{
|
||||
this.fileName = fileName;
|
||||
this.debugGui = debugGui;
|
||||
this.fileName = fileName;
|
||||
this.text = text;
|
||||
}
|
||||
|
||||
public void run() {
|
||||
Context cx = Context.enter();
|
||||
ContextData contextData = ContextData.get(cx);
|
||||
contextData.breakNextLine = true;
|
||||
try {
|
||||
cx.compileReader(new FileReader(fileName), fileName, 1, null);
|
||||
} catch (Exception exc) {
|
||||
String msg = exc.getMessage();
|
||||
if (exc instanceof EcmaError) {
|
||||
EcmaError err = (EcmaError)exc;
|
||||
msg = err.getSourceName() + ", line " + err.getLineNumber() + ": " + msg;
|
||||
}
|
||||
debugGui.main.compileScript(fileName, text);
|
||||
} catch (RuntimeException ex) {
|
||||
MessageDialogWrapper.showMessageDialog(debugGui,
|
||||
msg,
|
||||
"Error Compiling File",
|
||||
ex.getMessage(),
|
||||
"Error Compiling "+fileName,
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
} finally {
|
||||
cx.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class LoadFile implements Runnable {
|
||||
Scriptable scope;
|
||||
String fileName;
|
||||
class LoadFile implements Runnable
|
||||
{
|
||||
DebugGui debugGui;
|
||||
LoadFile(DebugGui debugGui, Scriptable scope, String fileName) {
|
||||
this.scope = scope;
|
||||
this.fileName = fileName;
|
||||
String fileName;
|
||||
String text;
|
||||
LoadFile(DebugGui debugGui, String fileName, String text)
|
||||
{
|
||||
this.debugGui = debugGui;
|
||||
this.fileName = fileName;
|
||||
this.text = text;
|
||||
}
|
||||
public void run() {
|
||||
Context cx = Context.enter();
|
||||
ContextData contextData = ContextData.get(cx);
|
||||
contextData.breakNextLine = true;
|
||||
public void run()
|
||||
{
|
||||
try {
|
||||
cx.evaluateReader(scope, new FileReader(fileName),
|
||||
fileName, 1, null);
|
||||
} catch (Exception exc) {
|
||||
String msg = exc.getMessage();
|
||||
if (exc instanceof EcmaError) {
|
||||
EcmaError err = (EcmaError)exc;
|
||||
msg = err.getSourceName() + ", line " + err.getLineNumber() + ": " + msg;
|
||||
}
|
||||
debugGui.main.evalScript(fileName, text);
|
||||
} catch (RuntimeException ex) {
|
||||
MessageDialogWrapper.showMessageDialog(debugGui,
|
||||
msg,
|
||||
"Run",
|
||||
ex.getMessage(),
|
||||
"Run error for "+fileName,
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
} finally {
|
||||
cx.exit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1993,12 +1963,24 @@ class DebugGui extends JFrame
|
|||
return (FileWindow)fileWindows.get(url);
|
||||
}
|
||||
|
||||
static String getShortName(String url) {
|
||||
int lastSlash = url.lastIndexOf('/');
|
||||
if (lastSlash < 0) {
|
||||
lastSlash = url.lastIndexOf('\\');
|
||||
}
|
||||
String shortName = url;
|
||||
if (lastSlash >= 0 && lastSlash + 1 < url.length()) {
|
||||
shortName = url.substring(lastSlash + 1);
|
||||
}
|
||||
return shortName;
|
||||
}
|
||||
|
||||
void removeWindow(FileWindow w) {
|
||||
fileWindows.remove(w.getUrl());
|
||||
JMenu windowMenu = getWindowMenu();
|
||||
int count = windowMenu.getItemCount();
|
||||
JMenuItem lastItem = windowMenu.getItem(count -1);
|
||||
String name = Main.SourceInfo.getShortName(w.getUrl());
|
||||
String name = getShortName(w.getUrl());
|
||||
for (int i = 5; i < count; i++) {
|
||||
JMenuItem item = windowMenu.getItem(i);
|
||||
if (item == null) continue; // separator
|
||||
|
@ -2070,7 +2052,7 @@ class DebugGui extends JFrame
|
|||
{
|
||||
boolean activate = true;
|
||||
|
||||
String url = sourceInfo.getUrl();
|
||||
String url = sourceInfo.url();
|
||||
FileWindow w = new FileWindow(this, sourceInfo);
|
||||
fileWindows.put(url, w);
|
||||
if (line != -1) {
|
||||
|
@ -2141,10 +2123,10 @@ class DebugGui extends JFrame
|
|||
|
||||
public void updateFileText(Main.SourceInfo sourceInfo)
|
||||
{
|
||||
String fileName = sourceInfo.getUrl();
|
||||
String fileName = sourceInfo.url();
|
||||
FileWindow w = getFileWindow(fileName);
|
||||
if (w != null) {
|
||||
w.updateText();
|
||||
w.updateText(sourceInfo);
|
||||
w.show();
|
||||
} else if (!fileName.equals("<stdin>")) {
|
||||
createFileWindow(sourceInfo, -1);
|
||||
|
@ -2213,20 +2195,6 @@ class DebugGui extends JFrame
|
|||
ctx.setMinimumSize(new Dimension(50, ctx.getMinimumSize().height));
|
||||
}
|
||||
|
||||
void runToCursor(String fileName,
|
||||
int lineNumber,
|
||||
ActionEvent evt) {
|
||||
Main.SourceInfo si = (Main.SourceInfo)main.sourceNames.get(fileName);
|
||||
if (si == null) {
|
||||
System.out.println("debugger error: Couldn't find source: " + fileName);
|
||||
}
|
||||
if (si.breakableLine(lineNumber)) {
|
||||
main.runToCursorFile = fileName;
|
||||
main.runToCursorLine = lineNumber;
|
||||
actionPerformed(evt);
|
||||
}
|
||||
}
|
||||
|
||||
JMenu getWindowMenu() {
|
||||
return menubar.getMenu(3);
|
||||
}
|
||||
|
@ -2285,24 +2253,22 @@ class DebugGui extends JFrame
|
|||
returnValue = Main.GO;
|
||||
} else if (cmd.equals("Break")) {
|
||||
main.doBreak();
|
||||
} else if (cmd.equals("Run to Cursor")) {
|
||||
returnValue = Main.RUN_TO_CURSOR;
|
||||
} else if (cmd.equals("Exit")) {
|
||||
main.Exit();
|
||||
} else if (cmd.equals("Open")) {
|
||||
String fileName = chooseFile("Select a file to compile");
|
||||
if (fileName != null) {
|
||||
new Thread(new OpenFile(this, fileName)).start();
|
||||
String text = readFile(fileName);
|
||||
if (text != null) {
|
||||
new Thread(new OpenFile(this, fileName, text)).start();
|
||||
}
|
||||
}
|
||||
} else if (cmd.equals("Load")) {
|
||||
Scriptable scope = main.getScope();
|
||||
if (scope == null) {
|
||||
MessageDialogWrapper.showMessageDialog(this, "Can't run scripts: no scope available", "Run", JOptionPane.ERROR_MESSAGE);
|
||||
} else {
|
||||
String fileName = chooseFile("Select a file to execute");
|
||||
if (fileName != null) {
|
||||
new Thread(new LoadFile(this, scope,
|
||||
fileName)).start();
|
||||
String fileName = chooseFile("Select a file to execute");
|
||||
if (fileName != null) {
|
||||
String text = readFile(fileName);
|
||||
if (text != null) {
|
||||
new Thread(new LoadFile(this, fileName, text)).start();
|
||||
}
|
||||
}
|
||||
} else if (cmd.equals("More Windows...")) {
|
||||
|
@ -2320,8 +2286,7 @@ class DebugGui extends JFrame
|
|||
} else if (cmd.equals("Copy")) {
|
||||
} else if (cmd.equals("Paste")) {
|
||||
} else if (cmd.equals("Go to function...")) {
|
||||
FindFunction dlg = new FindFunction(this, main.functionNames,
|
||||
"Go to function",
|
||||
FindFunction dlg = new FindFunction(this, "Go to function",
|
||||
"Function");
|
||||
dlg.showDialog(this);
|
||||
} else if (cmd.equals("Tile")) {
|
||||
|
@ -2433,5 +2398,25 @@ class DebugGui extends JFrame
|
|||
}
|
||||
}
|
||||
|
||||
String readFile(String fileName)
|
||||
{
|
||||
String text;
|
||||
try {
|
||||
Reader r = new FileReader(fileName);
|
||||
try {
|
||||
text = Kit.readReader(r);
|
||||
} finally {
|
||||
r.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
MessageDialogWrapper.showMessageDialog(this,
|
||||
ex.getMessage(),
|
||||
"Error reading "+fileName,
|
||||
JOptionPane.ERROR_MESSAGE);
|
||||
text = null;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -55,7 +55,7 @@ import javax.swing.tree.DefaultTreeCellRenderer;
|
|||
import java.lang.reflect.Method;
|
||||
import java.net.URL;
|
||||
|
||||
public class Main implements Debugger, ContextListener {
|
||||
public class Main {
|
||||
|
||||
DebugGui debugGui;
|
||||
|
||||
|
@ -64,8 +64,7 @@ public class Main implements Debugger, ContextListener {
|
|||
static final int STEP_OUT = 2;
|
||||
static final int GO = 3;
|
||||
static final int BREAK = 4;
|
||||
static final int RUN_TO_CURSOR = 5;
|
||||
static final int EXIT = 6;
|
||||
static final int EXIT = 5;
|
||||
|
||||
static class ContextData
|
||||
{
|
||||
|
@ -103,10 +102,10 @@ public class Main implements Debugger, ContextListener {
|
|||
this.db = db;
|
||||
this.contextData = ContextData.get(cx);
|
||||
this.fnOrScript = fnOrScript;
|
||||
ScriptItem item = db.getScriptItem(fnOrScript);
|
||||
FunctionSource item = db.getFunctionSource(fnOrScript);
|
||||
if (item != null) {
|
||||
this.sourceInfo = item.getSourceInfo();
|
||||
this.lineNumber = item.getFirstLine();
|
||||
this.sourceInfo = item.sourceInfo();
|
||||
this.lineNumber = item.firstLine();
|
||||
}
|
||||
contextData.pushFrame(this);
|
||||
}
|
||||
|
@ -125,7 +124,7 @@ public class Main implements Debugger, ContextListener {
|
|||
this.lineNumber = lineno;
|
||||
|
||||
checks:
|
||||
if (sourceInfo == null || !sourceInfo.hasBreakpoint(lineno)) {
|
||||
if (sourceInfo == null || !sourceInfo.checkBreakpointFast(lineno)) {
|
||||
if (db.breakFlag) {
|
||||
break checks;
|
||||
}
|
||||
|
@ -175,7 +174,7 @@ public class Main implements Debugger, ContextListener {
|
|||
|
||||
String getUrl() {
|
||||
if (sourceInfo != null) {
|
||||
return sourceInfo.getUrl();
|
||||
return sourceInfo.url();
|
||||
}
|
||||
return db.getNormilizedUrl(fnOrScript);
|
||||
}
|
||||
|
@ -197,184 +196,222 @@ public class Main implements Debugger, ContextListener {
|
|||
private int lineNumber;
|
||||
}
|
||||
|
||||
static class ScriptItem {
|
||||
|
||||
ScriptItem(DebuggableScript fnOrScript, SourceInfo sourceInfo) {
|
||||
this.fnOrScript = fnOrScript;
|
||||
this.sourceInfo = sourceInfo;
|
||||
}
|
||||
|
||||
DebuggableScript getScript() { return fnOrScript; }
|
||||
|
||||
SourceInfo getSourceInfo() { return sourceInfo; }
|
||||
|
||||
int getFirstLine() {
|
||||
return (firstLine == 0) ? 1 : firstLine;
|
||||
}
|
||||
|
||||
void setFirstLine(int firstLine) {
|
||||
if (firstLine <= 0) { throw new IllegalArgumentException(); }
|
||||
if (this.firstLine != 0) { throw new IllegalStateException(); }
|
||||
this.firstLine = firstLine;
|
||||
}
|
||||
|
||||
private DebuggableScript fnOrScript;
|
||||
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 {
|
||||
static class SourceInfo
|
||||
{
|
||||
private String source;
|
||||
private String url;
|
||||
|
||||
static String getShortName(String url) {
|
||||
int lastSlash = url.lastIndexOf('/');
|
||||
if (lastSlash < 0) {
|
||||
lastSlash = url.lastIndexOf('\\');
|
||||
}
|
||||
String shortName = url;
|
||||
if (lastSlash >= 0 && lastSlash + 1 < url.length()) {
|
||||
shortName = url.substring(lastSlash + 1);
|
||||
}
|
||||
return shortName;
|
||||
}
|
||||
private int minLine;
|
||||
private boolean[] breakableLines;
|
||||
private boolean[] breakpoints;
|
||||
|
||||
SourceInfo(String sourceUrl, String source) {
|
||||
this.sourceUrl = sourceUrl;
|
||||
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;
|
||||
|
||||
String getUrl() {
|
||||
return sourceUrl;
|
||||
}
|
||||
int N = functions.length;
|
||||
int[][] lineArrays = new int[N][];
|
||||
for (int i = 0; i != N; ++i) {
|
||||
lineArrays[i] = functions[i].getLineNumbers();
|
||||
}
|
||||
|
||||
String getSource() {
|
||||
return source;
|
||||
}
|
||||
|
||||
synchronized void setSource(String source) {
|
||||
if (!this.source.equals(source)) {
|
||||
this.source = source;
|
||||
endLine = 0;
|
||||
breakableLines = null;
|
||||
|
||||
if (breakpoints != null) {
|
||||
for (int i = breakpoints.length - 1; i >= 0; --i) {
|
||||
if (breakpoints[i] == BREAK_FLAG) {
|
||||
breakpoints[i] = OLD_BREAK_FLAG;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void updateLineInfo(ScriptItem item) {
|
||||
|
||||
int[] lines = item.getScript().getLineNumbers();
|
||||
if (lines.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
int fnFirstLine = lines[0];
|
||||
int fnEndLine = fnFirstLine + 1;
|
||||
for (int i = 1; i != lines.length; ++i) {
|
||||
int line = lines[i];
|
||||
if (line < fnFirstLine) {
|
||||
fnFirstLine = line;
|
||||
}else if (line >= fnEndLine) {
|
||||
fnEndLine = line + 1;
|
||||
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));
|
||||
}
|
||||
}
|
||||
item.setFirstLine(fnFirstLine);
|
||||
|
||||
if (endLine < fnEndLine) {
|
||||
endLine = fnEndLine;
|
||||
}
|
||||
if (breakableLines == null) {
|
||||
int newLength = 20;
|
||||
if (newLength < endLine) { newLength = endLine; }
|
||||
breakableLines = new boolean[newLength];
|
||||
}else if (breakableLines.length < endLine) {
|
||||
int newLength = breakableLines.length * 2;
|
||||
if (newLength < endLine) { newLength = endLine; }
|
||||
boolean[] tmp = new boolean[newLength];
|
||||
System.arraycopy(breakableLines, 0, tmp, 0, breakableLines.length);
|
||||
breakableLines = tmp;
|
||||
}
|
||||
int breakpointsEnd = (breakpoints == null) ? 0 : breakpoints.length;
|
||||
for (int i = 0; i != lines.length; ++i) {
|
||||
int line = lines[i];
|
||||
breakableLines[line] = true;
|
||||
if (line < breakpointsEnd) {
|
||||
if (breakpoints[line] == OLD_BREAK_FLAG) {
|
||||
breakpoints[line] = BREAK_FLAG;
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
boolean breakableLine(int line) {
|
||||
boolean[] breakableLines = this.breakableLines;
|
||||
if (breakableLines != null && line < breakableLines.length) {
|
||||
return breakableLines[line];
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
boolean hasBreakpoint(int line) {
|
||||
byte[] breakpoints = this.breakpoints;
|
||||
if (breakpoints != null && line < breakpoints.length) {
|
||||
return breakpoints[line] == BREAK_FLAG;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
synchronized boolean placeBreakpoint(int line) {
|
||||
if (breakableLine(line)) {
|
||||
if (breakpoints == null) {
|
||||
breakpoints = new byte[endLine];
|
||||
}else if (line >= breakpoints.length) {
|
||||
byte[] tmp = new byte[endLine];
|
||||
System.arraycopy(breakpoints, 0, tmp, 0, breakpoints.length);
|
||||
breakpoints = tmp;
|
||||
this.functionSources = new FunctionSource[N];
|
||||
for (int i = 0; i != N; ++i) {
|
||||
String name = functions[i].getFunctionName();
|
||||
if (name == null) {
|
||||
name = "";
|
||||
}
|
||||
breakpoints[line] = BREAK_FLAG;
|
||||
return true;
|
||||
this.functionSources[i]
|
||||
= new FunctionSource(this, firstLines[i], name);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
synchronized boolean removeBreakpoint(int line) {
|
||||
boolean wasBreakpoint = false;
|
||||
if (breakpoints != null && line < breakpoints.length) {
|
||||
wasBreakpoint = (breakpoints[line] == BREAK_FLAG);
|
||||
breakpoints[line] = 0;
|
||||
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;
|
||||
}
|
||||
}
|
||||
return wasBreakpoint;
|
||||
}
|
||||
|
||||
synchronized void removeAllBreakpoints() {
|
||||
breakpoints = null;
|
||||
boolean breakableLine(int line)
|
||||
{
|
||||
return (line < this.breakableLines.length)
|
||||
&& this.breakableLines[line];
|
||||
}
|
||||
|
||||
private String sourceUrl;
|
||||
private String source;
|
||||
boolean breakpoint(int line)
|
||||
{
|
||||
if (!breakableLine(line)) {
|
||||
throw new IllegalArgumentException(String.valueOf(line));
|
||||
}
|
||||
return line < this.breakpoints.length && this.breakpoints[line];
|
||||
}
|
||||
|
||||
private int endLine;
|
||||
private boolean[] breakableLines;
|
||||
final boolean checkBreakpointFast(int line)
|
||||
{
|
||||
return this.breakpoints[line];
|
||||
}
|
||||
|
||||
private static final byte BREAK_FLAG = 1;
|
||||
private static final byte OLD_BREAK_FLAG = 2;
|
||||
private byte[] breakpoints;
|
||||
boolean breakpoint(int line, boolean value)
|
||||
{
|
||||
if (!breakableLine(line)) {
|
||||
throw new IllegalArgumentException(String.valueOf(line));
|
||||
}
|
||||
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 final Debugger debuggerImpl = new Debugger()
|
||||
{
|
||||
public DebugFrame getFrame(Context cx, DebuggableScript fnOrScript)
|
||||
{
|
||||
return mirrorStackFrame(cx, fnOrScript);
|
||||
}
|
||||
|
||||
public void handleCompilationDone(Context cx,
|
||||
DebuggableScript fnOrScript,
|
||||
String source)
|
||||
{
|
||||
onCompilationDone(cx, fnOrScript, source);
|
||||
}
|
||||
};
|
||||
|
||||
int runToCursorLine;
|
||||
String runToCursorFile;
|
||||
private Hashtable scriptItems = new Hashtable();
|
||||
Hashtable sourceNames = new Hashtable();
|
||||
|
||||
Hashtable functionNames = new Hashtable();
|
||||
|
||||
boolean breakFlag = false;
|
||||
|
||||
|
@ -400,80 +437,209 @@ public class Main implements Debugger, ContextListener {
|
|||
boolean breakOnEnter;
|
||||
boolean breakOnReturn;
|
||||
|
||||
private final Hashtable urlToSourceInfo = new Hashtable();
|
||||
private final Hashtable functionNames = new Hashtable();
|
||||
private final Hashtable functionToSource = new Hashtable();
|
||||
|
||||
/* ContextListener interface */
|
||||
void enableForAllNewContexts()
|
||||
{
|
||||
Context.addContextListener(new ContextListener() {
|
||||
|
||||
public void contextCreated(Context cx) {
|
||||
public void contextCreated(Context cx)
|
||||
{
|
||||
initNewContext(cx);
|
||||
}
|
||||
|
||||
public void contextEntered(Context cx) { }
|
||||
|
||||
public void contextExited(Context cx) { }
|
||||
|
||||
public void contextReleased(Context cx) { }
|
||||
});
|
||||
}
|
||||
|
||||
void initNewContext(Context cx)
|
||||
{
|
||||
ContextData contextData = new ContextData();
|
||||
cx.setDebugger(this, contextData);
|
||||
cx.setDebugger(debuggerImpl, contextData);
|
||||
cx.setGeneratingDebug(true);
|
||||
cx.setOptimizationLevel(-1);
|
||||
}
|
||||
|
||||
public void contextEntered(Context cx) {
|
||||
DebugFrame mirrorStackFrame(Context cx, DebuggableScript fnOrScript)
|
||||
{
|
||||
return new StackFrame(cx, this, fnOrScript);
|
||||
}
|
||||
|
||||
public void contextExited(Context cx) {
|
||||
void onCompilationDone(Context cx, DebuggableScript fnOrScript,
|
||||
String source)
|
||||
{
|
||||
if (!fnOrScript.isTopLevel()) {
|
||||
return;
|
||||
}
|
||||
registerTopScript(fnOrScript, source);
|
||||
}
|
||||
|
||||
public void contextReleased(Context cx) {
|
||||
}
|
||||
|
||||
/* end ContextListener interface */
|
||||
|
||||
public void doBreak() {
|
||||
breakFlag = true;
|
||||
}
|
||||
|
||||
ScriptItem getScriptItem(DebuggableScript fnOrScript) {
|
||||
ScriptItem item = (ScriptItem)scriptItems.get(fnOrScript);
|
||||
if (item == null) {
|
||||
FunctionSource getFunctionSource(DebuggableScript fnOrScript)
|
||||
{
|
||||
FunctionSource fsource = functionSource(fnOrScript);
|
||||
if (fsource == null) {
|
||||
String url = getNormilizedUrl(fnOrScript);
|
||||
SourceInfo si = (SourceInfo)sourceNames.get(url);
|
||||
SourceInfo si = sourceInfo(url);
|
||||
if (si == null) {
|
||||
if (!fnOrScript.isGeneratedScript()) {
|
||||
// Not eval or Function, try to load it from URL
|
||||
String source = null;
|
||||
try {
|
||||
InputStream is = openSource(url);
|
||||
try {
|
||||
source = Kit.readReader(new InputStreamReader(is));
|
||||
} finally {
|
||||
is.close();
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
System.err.println
|
||||
("Failed to load source from "+url+": "+ ex);
|
||||
}
|
||||
String source = loadSource(url);
|
||||
if (source != null) {
|
||||
si = registerSource(url, source);
|
||||
DebuggableScript top = fnOrScript;
|
||||
for (;;) {
|
||||
DebuggableScript parent = top.getParent();
|
||||
if (parent == null) {
|
||||
break;
|
||||
}
|
||||
top = parent;
|
||||
}
|
||||
registerTopScript(top, source);
|
||||
fsource = functionSource(fnOrScript);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (si != null) {
|
||||
item = registerScript(si, 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 java.net.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;
|
||||
}
|
||||
|
||||
private 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
return item;
|
||||
|
||||
synchronized (functionToSource) {
|
||||
for (int i = 0; i != functions.length; ++i) {
|
||||
FunctionSource fsource = sourceInfo.functionSource(i);
|
||||
functionToSource.put(functions[i], fsource);
|
||||
}
|
||||
}
|
||||
|
||||
swingInvokeLater(new Runnable() {
|
||||
public void run()
|
||||
{
|
||||
debugGui.updateFileText(sourceInfo);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/* Debugger Interface */
|
||||
|
||||
public void handleCompilationDone(Context cx, DebuggableScript fnOrScript,
|
||||
String source)
|
||||
FunctionSource functionSource(DebuggableScript fnOrScript)
|
||||
{
|
||||
String sourceUrl = getNormilizedUrl(fnOrScript);
|
||||
SourceInfo si = registerSource(sourceUrl, source);
|
||||
registerScript(si, fnOrScript);
|
||||
return (FunctionSource)functionToSource.get(fnOrScript);
|
||||
}
|
||||
|
||||
String getNormilizedUrl(DebuggableScript 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)
|
||||
// strip line numbers, i.e. replace all #[0-9]+\(eval\) by
|
||||
// (eval)
|
||||
// Option: similar teatment for Function?
|
||||
char evalSeparator = '#';
|
||||
StringBuffer sb = null;
|
||||
|
@ -520,78 +686,26 @@ public class Main implements Debugger, ContextListener {
|
|||
return url;
|
||||
}
|
||||
|
||||
private static InputStream openSource(String sourceUrl)
|
||||
throws IOException
|
||||
private static DebuggableScript[] getAllFunctions(DebuggableScript function)
|
||||
{
|
||||
int hash = sourceUrl.indexOf('#');
|
||||
if (hash >= 0) {
|
||||
sourceUrl = sourceUrl.substring(0, hash);
|
||||
}
|
||||
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()) {
|
||||
return new FileInputStream(f);
|
||||
}
|
||||
}
|
||||
}
|
||||
File f = new File(sourceUrl);
|
||||
if (f.exists()) {
|
||||
return new FileInputStream(f);
|
||||
}
|
||||
} 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;
|
||||
}
|
||||
}
|
||||
|
||||
return (new java.net.URL(sourceUrl)).openStream();
|
||||
ObjArray functions = new ObjArray();
|
||||
collectFunctions_r(function, functions);
|
||||
DebuggableScript[] result = new DebuggableScript[functions.size()];
|
||||
functions.toArray(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
private SourceInfo registerSource(String sourceUrl, String source) {
|
||||
SourceInfo si;
|
||||
synchronized (sourceNames) {
|
||||
si = (SourceInfo)sourceNames.get(sourceUrl);
|
||||
if (si == null) {
|
||||
si = new SourceInfo(sourceUrl, source);
|
||||
sourceNames.put(sourceUrl, si);
|
||||
} else {
|
||||
si.setSource(source);
|
||||
}
|
||||
private static void collectFunctions_r(DebuggableScript function,
|
||||
ObjArray array)
|
||||
{
|
||||
array.add(function);
|
||||
for (int i = 0; i != function.getFunctionCount(); ++i) {
|
||||
collectFunctions_r(function.getFunction(i), array);
|
||||
}
|
||||
return si;
|
||||
}
|
||||
|
||||
private ScriptItem registerScript(final SourceInfo si,
|
||||
DebuggableScript fnOrScript)
|
||||
{
|
||||
ScriptItem item = new ScriptItem(fnOrScript, si);
|
||||
si.updateLineInfo(item);
|
||||
scriptItems.put(fnOrScript, item);
|
||||
|
||||
String name = fnOrScript.getFunctionName();
|
||||
if (name != null && name.length() > 0 && !name.equals("anonymous")) {
|
||||
functionNames.put(name, item);
|
||||
}
|
||||
|
||||
swingInvokeLater(new Runnable() {
|
||||
public void run()
|
||||
{
|
||||
debugGui.updateFileText(si);
|
||||
}
|
||||
});
|
||||
|
||||
return item;
|
||||
public void doBreak() {
|
||||
breakFlag = true;
|
||||
}
|
||||
|
||||
void handleBreakpointHit(StackFrame frame, Context cx) {
|
||||
|
@ -635,15 +749,37 @@ public class Main implements Debugger, ContextListener {
|
|||
}
|
||||
}
|
||||
|
||||
public DebugFrame getFrame(Context cx, DebuggableScript fnOrScript) {
|
||||
return new StackFrame(cx, this, fnOrScript);
|
||||
}
|
||||
|
||||
/* end Debugger interface */
|
||||
|
||||
void compileScript(String url, String text)
|
||||
{
|
||||
Context cx = Context.enter();
|
||||
try {
|
||||
cx.compileString(text, url, 1, null);
|
||||
} finally {
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
|
||||
Scriptable getScope() {
|
||||
return (scopeProvider != null) ? scopeProvider.getScope() : null;
|
||||
void evalScript(String url, String text)
|
||||
{
|
||||
Context cx = Context.enter();
|
||||
try {
|
||||
Scriptable scope = null;
|
||||
if (scopeProvider != null) {
|
||||
scope = scopeProvider.getScope();
|
||||
}
|
||||
if (scope == null) {
|
||||
scope = new ImporterTopLevel(cx);
|
||||
}
|
||||
try {
|
||||
cx.evaluateString(scope, text, url, 1, null);
|
||||
} catch (JavaScriptException ex) {
|
||||
throw new RuntimeException(ex.getMessage());
|
||||
}
|
||||
} finally {
|
||||
Context.exit();
|
||||
}
|
||||
}
|
||||
|
||||
static void swingInvokeLater(Runnable f)
|
||||
|
@ -700,21 +836,6 @@ public class Main implements Debugger, ContextListener {
|
|||
currentContextData = contextData;
|
||||
}
|
||||
do {
|
||||
if (runToCursorFile != null) {
|
||||
if (url != null && url.equals(runToCursorFile)) {
|
||||
if (line == runToCursorLine) {
|
||||
runToCursorFile = null;
|
||||
} else {
|
||||
SourceInfo si = frame.sourceInfo();
|
||||
if (si == null || !si.hasBreakpoint(line))
|
||||
{
|
||||
break;
|
||||
} else {
|
||||
runToCursorFile = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
int frameCount = contextData.frameCount();
|
||||
this.frameIndex = frameCount -1;
|
||||
|
||||
|
@ -795,10 +916,6 @@ public class Main implements Debugger, ContextListener {
|
|||
contextData.stopAtFrameDepth = contextData.frameCount() -1;
|
||||
}
|
||||
break;
|
||||
case RUN_TO_CURSOR:
|
||||
contextData.breakNextLine = true;
|
||||
contextData.stopAtFrameDepth = -1;
|
||||
break;
|
||||
}
|
||||
} while (false);
|
||||
|
||||
|
@ -963,8 +1080,9 @@ public class Main implements Debugger, ContextListener {
|
|||
*
|
||||
* Remove all breakpoints
|
||||
*/
|
||||
public void clearAllBreakpoints() {
|
||||
Enumeration e = sourceNames.elements();
|
||||
public void clearAllBreakpoints()
|
||||
{
|
||||
Enumeration e = urlToSourceInfo.elements();
|
||||
while (e.hasMoreElements()) {
|
||||
SourceInfo si = (SourceInfo)e.nextElement();
|
||||
si.removeAllBreakpoints();
|
||||
|
@ -1036,7 +1154,7 @@ public class Main implements Debugger, ContextListener {
|
|||
System.setIn(sdb.getIn());
|
||||
System.setOut(sdb.getOut());
|
||||
System.setErr(sdb.getErr());
|
||||
Context.addContextListener(sdb);
|
||||
sdb.enableForAllNewContexts();
|
||||
sdb.setScopeProvider(new ScopeProvider() {
|
||||
public Scriptable getScope() {
|
||||
return org.mozilla.javascript.tools.shell.Main.getScope();
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
|
||||
|
||||
var x = 10;
|
||||
var x = 12;
|
||||
|
||||
function sleep(millis)
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче