1/*
2 * Copyright (C) 2010 Apple Inc. All rights reserved.
3 * Copyright (C) 2010-2011 Google Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1.  Redistributions of source code must retain the above copyright
10 *     notice, this list of conditions and the following disclaimer.
11 * 2.  Redistributions in binary form must reproduce the above copyright
12 *     notice, this list of conditions and the following disclaimer in the
13 *     documentation and/or other materials provided with the distribution.
14 * 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
15 *     its contributors may be used to endorse or promote products derived
16 *     from this software without specific prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
19 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
23 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
24 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
25 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 */
29
30#ifndef InspectorDebuggerAgent_h
31#define InspectorDebuggerAgent_h
32
33#include "bindings/v8/ScriptState.h"
34#include "core/InspectorFrontend.h"
35#include "core/frame/ConsoleTypes.h"
36#include "core/inspector/AsyncCallStackTracker.h"
37#include "core/inspector/ConsoleAPITypes.h"
38#include "core/inspector/InjectedScript.h"
39#include "core/inspector/InspectorBaseAgent.h"
40#include "core/inspector/ScriptBreakpoint.h"
41#include "core/inspector/ScriptDebugListener.h"
42#include "wtf/Forward.h"
43#include "wtf/HashMap.h"
44#include "wtf/PassRefPtr.h"
45#include "wtf/Vector.h"
46#include "wtf/text/StringHash.h"
47
48namespace WebCore {
49
50class Document;
51class Event;
52class EventListener;
53class EventTarget;
54class FormData;
55class HTTPHeaderMap;
56class InjectedScriptManager;
57class InspectorFrontend;
58class InstrumentingAgents;
59class JavaScriptCallFrame;
60class JSONObject;
61class KURL;
62class MutationObserver;
63class ScriptArguments;
64class ScriptCallStack;
65class ScriptDebugServer;
66class ScriptRegexp;
67class ScriptSourceCode;
68class ScriptValue;
69class ThreadableLoaderClient;
70class XMLHttpRequest;
71
72typedef String ErrorString;
73
74class InspectorDebuggerAgent : public InspectorBaseAgent<InspectorDebuggerAgent>, public ScriptDebugListener, public InspectorBackendDispatcher::DebuggerCommandHandler {
75    WTF_MAKE_NONCOPYABLE(InspectorDebuggerAgent); WTF_MAKE_FAST_ALLOCATED;
76public:
77    enum BreakpointSource {
78        UserBreakpointSource,
79        DebugCommandBreakpointSource,
80        MonitorCommandBreakpointSource
81    };
82
83    static const char backtraceObjectGroup[];
84
85    virtual ~InspectorDebuggerAgent();
86
87    virtual void canSetScriptSource(ErrorString*, bool* result) OVERRIDE FINAL { *result = true; }
88
89    virtual void init() OVERRIDE FINAL;
90    virtual void setFrontend(InspectorFrontend*) OVERRIDE FINAL;
91    virtual void clearFrontend() OVERRIDE FINAL;
92    virtual void restore() OVERRIDE FINAL;
93
94    bool isPaused();
95    bool runningNestedMessageLoop();
96    void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String&, PassRefPtrWillBeRawPtr<ScriptCallStack>, unsigned long);
97    void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String&, ScriptState*, PassRefPtrWillBeRawPtr<ScriptArguments>, unsigned long);
98
99    String preprocessEventListener(LocalFrame*, const String& source, const String& url, const String& functionName);
100    PassOwnPtr<ScriptSourceCode> preprocess(LocalFrame*, const ScriptSourceCode&);
101
102    // Part of the protocol.
103    virtual void enable(ErrorString*) OVERRIDE FINAL;
104    virtual void disable(ErrorString*) OVERRIDE FINAL;
105    virtual void setBreakpointsActive(ErrorString*, bool active) OVERRIDE FINAL;
106    virtual void setSkipAllPauses(ErrorString*, bool skipped, const bool* untilReload) OVERRIDE FINAL;
107
108    virtual void setBreakpointByUrl(ErrorString*, int lineNumber, const String* optionalURL, const String* optionalURLRegex, const int* optionalColumnNumber, const String* optionalCondition, const bool* isAntiBreakpoint, TypeBuilder::Debugger::BreakpointId*, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::Location> >& locations) OVERRIDE FINAL;
109    virtual void setBreakpoint(ErrorString*, const RefPtr<JSONObject>& location, const String* optionalCondition, TypeBuilder::Debugger::BreakpointId*, RefPtr<TypeBuilder::Debugger::Location>& actualLocation) OVERRIDE FINAL;
110    virtual void removeBreakpoint(ErrorString*, const String& breakpointId) OVERRIDE FINAL;
111    virtual void continueToLocation(ErrorString*, const RefPtr<JSONObject>& location, const bool* interstateLocationOpt) OVERRIDE FINAL;
112    virtual void getStepInPositions(ErrorString*, const String& callFrameId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::Location> >& positions) OVERRIDE FINAL;
113    virtual void getBacktrace(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >&, RefPtr<TypeBuilder::Debugger::StackTrace>&) OVERRIDE FINAL;
114
115    virtual void searchInContent(ErrorString*, const String& scriptId, const String& query, const bool* optionalCaseSensitive, const bool* optionalIsRegex, RefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchMatch> >&) OVERRIDE FINAL;
116    virtual void setScriptSource(ErrorString*, RefPtr<TypeBuilder::Debugger::SetScriptSourceError>&, const String& scriptId, const String& newContent, const bool* preview, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<JSONObject>& result, RefPtr<TypeBuilder::Debugger::StackTrace>& asyncStackTrace) OVERRIDE FINAL;
117    virtual void restartFrame(ErrorString*, const String& callFrameId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<JSONObject>& result, RefPtr<TypeBuilder::Debugger::StackTrace>& asyncStackTrace) OVERRIDE FINAL;
118    virtual void getScriptSource(ErrorString*, const String& scriptId, String* scriptSource) OVERRIDE FINAL;
119    virtual void getFunctionDetails(ErrorString*, const String& functionId, RefPtr<TypeBuilder::Debugger::FunctionDetails>&) OVERRIDE FINAL;
120    virtual void pause(ErrorString*) OVERRIDE FINAL;
121    virtual void resume(ErrorString*) OVERRIDE FINAL;
122    virtual void stepOver(ErrorString*) OVERRIDE FINAL;
123    virtual void stepInto(ErrorString*) OVERRIDE FINAL;
124    virtual void stepOut(ErrorString*) OVERRIDE FINAL;
125    virtual void setPauseOnExceptions(ErrorString*, const String& pauseState) OVERRIDE FINAL;
126    virtual void evaluateOnCallFrame(ErrorString*,
127        const String& callFrameId,
128        const String& expression,
129        const String* objectGroup,
130        const bool* includeCommandLineAPI,
131        const bool* doNotPauseOnExceptionsAndMuteConsole,
132        const bool* returnByValue,
133        const bool* generatePreview,
134        RefPtr<TypeBuilder::Runtime::RemoteObject>& result,
135        TypeBuilder::OptOutput<bool>* wasThrown) OVERRIDE FINAL;
136    virtual void compileScript(ErrorString*, const String& expression, const String& sourceURL, const int* executionContextId, TypeBuilder::OptOutput<TypeBuilder::Debugger::ScriptId>*, RefPtr<TypeBuilder::Debugger::ExceptionDetails>&) OVERRIDE;
137    virtual void runScript(ErrorString*, const TypeBuilder::Debugger::ScriptId&, const int* executionContextId, const String* objectGroup, const bool* doNotPauseOnExceptionsAndMuteConsole, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, RefPtr<TypeBuilder::Debugger::ExceptionDetails>&) OVERRIDE;
138    virtual void setOverlayMessage(ErrorString*, const String*) OVERRIDE;
139    virtual void setVariableValue(ErrorString*, int in_scopeNumber, const String& in_variableName, const RefPtr<JSONObject>& in_newValue, const String* in_callFrame, const String* in_functionObjectId) OVERRIDE FINAL;
140    virtual void skipStackFrames(ErrorString*, const String* pattern) OVERRIDE FINAL;
141    virtual void setAsyncCallStackDepth(ErrorString*, int depth) OVERRIDE FINAL;
142
143    void schedulePauseOnNextStatement(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data);
144    void didInstallTimer(ExecutionContext*, int timerId, int timeout, bool singleShot);
145    void didRemoveTimer(ExecutionContext*, int timerId);
146    bool willFireTimer(ExecutionContext*, int timerId);
147    void didFireTimer();
148    void didRequestAnimationFrame(Document*, int callbackId);
149    void didCancelAnimationFrame(Document*, int callbackId);
150    bool willFireAnimationFrame(Document*, int callbackId);
151    void didFireAnimationFrame();
152    void didEnqueueEvent(EventTarget*, Event*);
153    void didRemoveEvent(EventTarget*, Event*);
154    void willHandleEvent(EventTarget*, Event*, EventListener*, bool useCapture);
155    void didHandleEvent();
156    void willLoadXHR(XMLHttpRequest*, ThreadableLoaderClient*, const AtomicString& method, const KURL&, bool async, FormData* body, const HTTPHeaderMap& headers, bool includeCrendentials);
157    void didEnqueueMutationRecord(ExecutionContext*, MutationObserver*);
158    void didClearAllMutationRecords(ExecutionContext*, MutationObserver*);
159    void willDeliverMutationRecords(ExecutionContext*, MutationObserver*);
160    void didDeliverMutationRecords();
161    bool canBreakProgram();
162    void breakProgram(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data);
163    void scriptExecutionBlockedByCSP(const String& directiveText);
164
165    class Listener {
166    public:
167        virtual ~Listener() { }
168        virtual void debuggerWasEnabled() = 0;
169        virtual void debuggerWasDisabled() = 0;
170        virtual void stepInto() = 0;
171        virtual void didPause() = 0;
172    };
173    void setListener(Listener* listener) { m_listener = listener; }
174
175    bool enabled();
176
177    virtual ScriptDebugServer& scriptDebugServer() = 0;
178
179    void setBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource, const String& condition = String());
180    void removeBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource);
181
182protected:
183    explicit InspectorDebuggerAgent(InjectedScriptManager*);
184
185    virtual void startListeningScriptDebugServer() = 0;
186    virtual void stopListeningScriptDebugServer() = 0;
187    virtual void muteConsole() = 0;
188    virtual void unmuteConsole() = 0;
189    InjectedScriptManager* injectedScriptManager() { return m_injectedScriptManager; }
190    virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) = 0;
191
192    virtual void enable();
193    virtual void disable();
194    virtual SkipPauseRequest didPause(ScriptState*, const ScriptValue& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints) OVERRIDE FINAL;
195    virtual void didContinue() OVERRIDE FINAL;
196    void reset();
197    void pageDidCommitLoad();
198
199private:
200    SkipPauseRequest shouldSkipExceptionPause();
201    SkipPauseRequest shouldSkipStepPause();
202
203    void cancelPauseOnNextStatement();
204    void addMessageToConsole(MessageSource, MessageType);
205
206    PassRefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> > currentCallFrames();
207    PassRefPtr<TypeBuilder::Debugger::StackTrace> currentAsyncStackTrace();
208
209    virtual void didParseSource(const String& scriptId, const Script&) OVERRIDE FINAL;
210    virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage) OVERRIDE FINAL;
211
212    void setPauseOnExceptionsImpl(ErrorString*, int);
213
214    PassRefPtr<TypeBuilder::Debugger::Location> resolveBreakpoint(const String& breakpointId, const String& scriptId, const ScriptBreakpoint&, BreakpointSource);
215    void removeBreakpoint(const String& breakpointId);
216    void clear();
217    bool assertPaused(ErrorString*);
218    void clearBreakDetails();
219
220    String sourceMapURLForScript(const Script&);
221
222    String scriptURL(JavaScriptCallFrame*);
223
224    typedef HashMap<String, Script> ScriptsMap;
225    typedef HashMap<String, Vector<String> > BreakpointIdToDebugServerBreakpointIdsMap;
226    typedef HashMap<String, std::pair<String, BreakpointSource> > DebugServerBreakpointToBreakpointIdAndSourceMap;
227
228    InjectedScriptManager* m_injectedScriptManager;
229    InspectorFrontend::Debugger* m_frontend;
230    RefPtr<ScriptState> m_pausedScriptState;
231    ScriptValue m_currentCallStack;
232    ScriptsMap m_scripts;
233    BreakpointIdToDebugServerBreakpointIdsMap m_breakpointIdToDebugServerBreakpointIds;
234    DebugServerBreakpointToBreakpointIdAndSourceMap m_serverBreakpoints;
235    String m_continueToLocationBreakpointId;
236    InspectorFrontend::Debugger::Reason::Enum m_breakReason;
237    RefPtr<JSONObject> m_breakAuxData;
238    bool m_javaScriptPauseScheduled;
239    bool m_debuggerStepScheduled;
240    bool m_pausingOnNativeEvent;
241    Listener* m_listener;
242
243    int m_skippedStepInCount;
244    int m_minFrameCountForSkip;
245    bool m_skipAllPauses;
246    OwnPtr<ScriptRegexp> m_cachedSkipStackRegExp;
247    AsyncCallStackTracker m_asyncCallStackTracker;
248};
249
250} // namespace WebCore
251
252
253#endif // !defined(InspectorDebuggerAgent_h)
254