00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _KJS_DEBUGGER_H_
00022 #define _KJS_DEBUGGER_H_
00023
00024 #include <qglobal.h>
00025
00026 #define KJS_DEBUGGER
00027
00028 #ifdef KJS_DEBUGGER
00029
00030 #include <qwidget.h>
00031 #include <qmultilineedit.h>
00032 #include <qpixmap.h>
00033 #include <qptrlist.h>
00034 #include <qptrstack.h>
00035 #include <qcheckbox.h>
00036 #include <kdialogbase.h>
00037 #include <kmainwindow.h>
00038 #include <qscrollview.h>
00039
00040 #include <kjs/debugger.h>
00041
00042 #include "dom/dom_misc.h"
00043
00044 class QListBox;
00045 class QComboBox;
00046 class KActionCollection;
00047 class KAction;
00048
00049 namespace KJS {
00050 class FunctionImp;
00051 class List;
00052 class Interpreter;
00053 class KJSDebugWin;
00054
00055 class SourceFile : public DOM::DomShared
00056 {
00057 public:
00058 SourceFile(QString u, QString c, Interpreter *interp)
00059 : url(u), code(c), interpreter(interp) {}
00060 QString getCode();
00061 QString url;
00062 QString code;
00063 Interpreter *interpreter;
00064 };
00065
00081 class SourceFragment
00082 {
00083 public:
00084 SourceFragment(int sid, int bl, int el, SourceFile *sf);
00085 ~SourceFragment();
00086
00087 int sourceId;
00088 int baseLine;
00089 int errorLine;
00090 SourceFile *sourceFile;
00091 private:
00092 SourceFragment(const SourceFragment& other);
00093 SourceFragment& operator = (const SourceFragment& other);
00094 };
00095
00096 class KJSErrorDialog : public KDialogBase {
00097 Q_OBJECT
00098 public:
00099 KJSErrorDialog(QWidget *parent, const QString& errorMessage, bool showDebug);
00100 virtual ~KJSErrorDialog();
00101
00102 bool debugSelected() const { return m_debugSelected; }
00103 bool dontShowAgain() const { return m_dontShowAgainCb->isChecked(); }
00104
00105 protected slots:
00106 virtual void slotUser1();
00107
00108 private:
00109 QCheckBox *m_dontShowAgainCb;
00110 bool m_debugSelected;
00111 };
00112
00113 class EvalMultiLineEdit : public QMultiLineEdit {
00114 Q_OBJECT
00115 public:
00116 EvalMultiLineEdit(QWidget *parent);
00117 const QString & code() const { return m_code; }
00118 protected:
00119 void keyPressEvent(QKeyEvent * e);
00120 private:
00121 QString m_code;
00122 };
00123
00124 class SourceDisplay : public QScrollView {
00125 Q_OBJECT
00126 public:
00127 SourceDisplay(KJSDebugWin *debugWin, QWidget *parent, const char *name = 0);
00128 ~SourceDisplay();
00129
00130 void setSource(SourceFile *sourceFile);
00131 void setCurrentLine(int lineno, bool doCenter = true);
00132
00133 signals:
00134 void lineDoubleClicked(int lineno);
00135
00136 protected:
00137 virtual void contentsMousePressEvent(QMouseEvent *e);
00138 virtual void showEvent(QShowEvent *);
00139 virtual void drawContents(QPainter *p, int clipx, int clipy, int clipw, int cliph);
00140
00141 QString m_source;
00142 int m_currentLine;
00143 SourceFile *m_sourceFile;
00144 QStringList m_lines;
00145
00146 KJSDebugWin *m_debugWin;
00147 QFont m_font;
00148 QPixmap m_breakpointIcon;
00149 };
00150
00160 class KJSDebugWin : public KMainWindow, public Debugger, public KInstance
00161 {
00162 Q_OBJECT
00163 friend class SourceDisplay;
00164 public:
00165 KJSDebugWin(QWidget *parent=0, const char *name=0);
00166 virtual ~KJSDebugWin();
00167
00168 static KJSDebugWin *createInstance();
00169 static void destroyInstance();
00170 static KJSDebugWin *debugWindow() { return kjs_html_debugger; }
00171
00172 enum Mode { Disabled = 0,
00173 Next = 1,
00174 Step = 2,
00175 Continue = 3,
00176 Stop = 4
00177
00178 };
00179
00180 void setSourceLine(int sourceId, int lineno);
00181 void setNextSourceInfo(QString url, int baseLine);
00182 void sourceChanged(Interpreter *interpreter, QString url);
00183 bool inSession() const { return !m_execStates.isEmpty(); }
00184 void setMode(Mode m) { m_mode = m; }
00185 void clearInterpreter(Interpreter *interpreter);
00186 ExecState *getExecState() const { return m_execStates.top(); }
00187
00188
00189 bool sourceParsed(ExecState *exec, int sourceId,
00190 const UString &source, int errorLine);
00191 bool sourceUnused(ExecState * exec, int sourceId);
00192 bool exception(ExecState *exec, const Value &value, bool inTryCatch);
00193 bool atStatement(ExecState *exec);
00194 bool enterContext(ExecState *exec);
00195 bool exitContext(ExecState *exec, const Completion &completion);
00196
00197 public slots:
00198 void slotNext();
00199 void slotStep();
00200 void slotContinue();
00201 void slotStop();
00202 void slotBreakNext();
00203 void slotToggleBreakpoint(int lineno);
00204 void slotShowFrame(int frameno);
00205 void slotSourceSelected(int sourceSelIndex);
00206 void slotEval();
00207
00208 protected:
00209
00210 void closeEvent(QCloseEvent *e);
00211 bool eventFilter(QObject *obj, QEvent *evt);
00212 void disableOtherWindows();
00213 void enableOtherWindows();
00214
00215 private:
00216
00217 SourceFile *getSourceFile(Interpreter *interpreter, QString url);
00218 void setSourceFile(Interpreter *interpreter, QString url, SourceFile *sourceFile);
00219 void removeSourceFile(Interpreter *interpreter, QString url);
00220
00221 void checkBreak(ExecState *exec);
00222 void enterSession(ExecState *exec);
00223 void leaveSession();
00224 void displaySourceFile(SourceFile *sourceFile, bool forceRefresh);
00225 void updateContextList();
00226
00227 QString contextStr(const Context &ctx);
00228
00229 struct Breakpoint {
00230 int sourceId;
00231 int lineno;
00232 };
00233 Breakpoint *m_breakpoints;
00234 int m_breakpointCount;
00235 bool setBreakpoint(int sourceId, int lineno);
00236 bool deleteBreakpoint(int sourceId, int lineno);
00237 bool haveBreakpoint(SourceFile *sourceFile, int line0, int line1);
00238 bool haveBreakpoint(int sourceId, int line0, int line1) const {
00239 for (int i = 0; i < m_breakpointCount; i++) {
00240 if (m_breakpoints[i].sourceId == sourceId &&
00241 m_breakpoints[i].lineno >= line0 &&
00242 m_breakpoints[i].lineno <= line1)
00243 return true;
00244 }
00245 return false;
00246 }
00247
00248 SourceFile *m_curSourceFile;
00249 Mode m_mode;
00250 QString m_nextSourceUrl;
00251 int m_nextSourceBaseLine;
00252 QPtrStack<ExecState> m_execStates;
00253 ExecState **m_execs;
00254 int m_execsCount;
00255 int m_execsAlloc;
00256 int m_steppingDepth;
00257
00258 QMap<QString,SourceFile*> m_sourceFiles;
00259 QMap<int,SourceFragment*> m_sourceFragments;
00260 QPtrList<SourceFile> m_sourceSelFiles;
00261
00262 KActionCollection *m_actionCollection;
00263 QPixmap m_stopIcon;
00264 QPixmap m_emptyIcon;
00265 SourceDisplay *m_sourceDisplay;
00266 QListBox *m_contextList;
00267
00268 KAction *m_stepAction;
00269 KAction *m_nextAction;
00270 KAction *m_continueAction;
00271 KAction *m_stopAction;
00272 KAction *m_breakAction;
00273
00274 QComboBox *m_sourceSel;
00275 EvalMultiLineEdit *m_evalEdit;
00276 int m_evalDepth;
00277
00278 static KJSDebugWin *kjs_html_debugger;
00279 };
00280
00281 }
00282
00283 #endif // KJS_DEBUGGER
00284
00285 #endif // _KJS_DEBUGGER_H_