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/core/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/PromiseTracker.h"
41#include "core/inspector/ScriptBreakpoint.h"
42#include "core/inspector/ScriptDebugListener.h"
43#include "wtf/Forward.h"
44#include "wtf/HashMap.h"
45#include "wtf/PassRefPtr.h"
46#include "wtf/Vector.h"
47#include "wtf/text/StringHash.h"
48
49namespace blink {
50
51class ConsoleMessage;
52class Document;
53class Event;
54class EventListener;
55class EventTarget;
56class ExecutionContextTask;
57class FormData;
58class HTTPHeaderMap;
59class InjectedScriptManager;
60class InspectorFrontend;
61class InstrumentingAgents;
62class JavaScriptCallFrame;
63class JSONObject;
64class KURL;
65class MutationObserver;
66class ScriptArguments;
67class ScriptAsyncCallStack;
68class ScriptCallStack;
69class ScriptDebugServer;
70class ScriptRegexp;
71class ScriptSourceCode;
72class ScriptValue;
73class ThreadableLoaderClient;
74class XMLHttpRequest;
75
76typedef String ErrorString;
77
78class InspectorDebuggerAgent : public InspectorBaseAgent<InspectorDebuggerAgent>, public ScriptDebugListener, public InspectorBackendDispatcher::DebuggerCommandHandler {
79    WTF_MAKE_NONCOPYABLE(InspectorDebuggerAgent);
80    WTF_MAKE_FAST_ALLOCATED_WILL_BE_REMOVED;
81public:
82    enum BreakpointSource {
83        UserBreakpointSource,
84        DebugCommandBreakpointSource,
85        MonitorCommandBreakpointSource
86    };
87
88    static const char backtraceObjectGroup[];
89
90    virtual ~InspectorDebuggerAgent();
91    virtual void trace(Visitor*);
92
93    virtual void canSetScriptSource(ErrorString*, bool* result) OVERRIDE FINAL { *result = true; }
94
95    virtual void init() OVERRIDE FINAL;
96    virtual void setFrontend(InspectorFrontend*) OVERRIDE FINAL;
97    virtual void clearFrontend() OVERRIDE FINAL;
98    virtual void restore() OVERRIDE FINAL;
99
100    bool isPaused();
101    bool runningNestedMessageLoop();
102    void addMessageToConsole(ConsoleMessage*);
103
104    String preprocessEventListener(LocalFrame*, const String& source, const String& url, const String& functionName);
105    PassOwnPtr<ScriptSourceCode> preprocess(LocalFrame*, const ScriptSourceCode&);
106
107    // Part of the protocol.
108    virtual void enable(ErrorString*) OVERRIDE FINAL;
109    virtual void disable(ErrorString*) OVERRIDE FINAL;
110    virtual void setBreakpointsActive(ErrorString*, bool active) OVERRIDE FINAL;
111    virtual void setSkipAllPauses(ErrorString*, bool skipped, const bool* untilReload) OVERRIDE FINAL;
112
113    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;
114    virtual void setBreakpoint(ErrorString*, const RefPtr<JSONObject>& location, const String* optionalCondition, TypeBuilder::Debugger::BreakpointId*, RefPtr<TypeBuilder::Debugger::Location>& actualLocation) OVERRIDE FINAL;
115    virtual void removeBreakpoint(ErrorString*, const String& breakpointId) OVERRIDE FINAL;
116    virtual void continueToLocation(ErrorString*, const RefPtr<JSONObject>& location, const bool* interstateLocationOpt) OVERRIDE FINAL;
117    virtual void getStepInPositions(ErrorString*, const String& callFrameId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::Location> >& positions) OVERRIDE FINAL;
118    virtual void getBacktrace(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >&, RefPtr<TypeBuilder::Debugger::StackTrace>&) OVERRIDE FINAL;
119
120    virtual void searchInContent(ErrorString*, const String& scriptId, const String& query, const bool* optionalCaseSensitive, const bool* optionalIsRegex, RefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchMatch> >&) OVERRIDE FINAL;
121    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;
122    virtual void restartFrame(ErrorString*, const String& callFrameId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<JSONObject>& result, RefPtr<TypeBuilder::Debugger::StackTrace>& asyncStackTrace) OVERRIDE FINAL;
123    virtual void getScriptSource(ErrorString*, const String& scriptId, String* scriptSource) OVERRIDE FINAL;
124    virtual void getFunctionDetails(ErrorString*, const String& functionId, RefPtr<TypeBuilder::Debugger::FunctionDetails>&) OVERRIDE FINAL;
125    virtual void getCollectionEntries(ErrorString*, const String& objectId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CollectionEntry> >&) OVERRIDE FINAL;
126    virtual void pause(ErrorString*) OVERRIDE FINAL;
127    virtual void resume(ErrorString*) OVERRIDE FINAL;
128    virtual void stepOver(ErrorString*) OVERRIDE FINAL;
129    virtual void stepInto(ErrorString*) OVERRIDE FINAL;
130    virtual void stepOut(ErrorString*) OVERRIDE FINAL;
131    virtual void setPauseOnExceptions(ErrorString*, const String& pauseState) OVERRIDE FINAL;
132    virtual void evaluateOnCallFrame(ErrorString*,
133        const String& callFrameId,
134        const String& expression,
135        const String* objectGroup,
136        const bool* includeCommandLineAPI,
137        const bool* doNotPauseOnExceptionsAndMuteConsole,
138        const bool* returnByValue,
139        const bool* generatePreview,
140        RefPtr<TypeBuilder::Runtime::RemoteObject>& result,
141        TypeBuilder::OptOutput<bool>* wasThrown,
142        RefPtr<TypeBuilder::Debugger::ExceptionDetails>&) OVERRIDE FINAL;
143    virtual void compileScript(ErrorString*, const String& expression, const String& sourceURL, const int* executionContextId, TypeBuilder::OptOutput<TypeBuilder::Debugger::ScriptId>*, RefPtr<TypeBuilder::Debugger::ExceptionDetails>&) OVERRIDE;
144    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;
145    virtual void setOverlayMessage(ErrorString*, const String*) OVERRIDE;
146    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;
147    virtual void skipStackFrames(ErrorString*, const String* pattern, const bool* skipContentScripts) OVERRIDE FINAL;
148    virtual void setAsyncCallStackDepth(ErrorString*, int depth) OVERRIDE FINAL;
149    virtual void enablePromiseTracker(ErrorString*) OVERRIDE FINAL;
150    virtual void disablePromiseTracker(ErrorString*) OVERRIDE FINAL;
151    virtual void getPromises(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::PromiseDetails> >& promises) OVERRIDE FINAL;
152    virtual void getPromiseById(ErrorString*, int promiseId, const String* objectGroup, RefPtr<TypeBuilder::Runtime::RemoteObject>& promise) OVERRIDE FINAL;
153
154    void schedulePauseOnNextStatement(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data);
155    void didInstallTimer(ExecutionContext*, int timerId, int timeout, bool singleShot);
156    void didRemoveTimer(ExecutionContext*, int timerId);
157    bool willFireTimer(ExecutionContext*, int timerId);
158    void didFireTimer();
159    void didRequestAnimationFrame(Document*, int callbackId);
160    void didCancelAnimationFrame(Document*, int callbackId);
161    bool willFireAnimationFrame(Document*, int callbackId);
162    void didFireAnimationFrame();
163    void didEnqueueEvent(EventTarget*, Event*);
164    void didRemoveEvent(EventTarget*, Event*);
165    void willHandleEvent(EventTarget*, Event*, EventListener*, bool useCapture);
166    void didHandleEvent();
167    void willLoadXHR(XMLHttpRequest*, ThreadableLoaderClient*, const AtomicString& method, const KURL&, bool async, PassRefPtr<FormData> body, const HTTPHeaderMap& headers, bool includeCrendentials);
168    void didDispatchXHRLoadendEvent(XMLHttpRequest*);
169    void didEnqueueMutationRecord(ExecutionContext*, MutationObserver*);
170    void didClearAllMutationRecords(ExecutionContext*, MutationObserver*);
171    void willDeliverMutationRecords(ExecutionContext*, MutationObserver*);
172    void didDeliverMutationRecords();
173    void didPostExecutionContextTask(ExecutionContext*, ExecutionContextTask*);
174    void didKillAllExecutionContextTasks(ExecutionContext*);
175    void willPerformExecutionContextTask(ExecutionContext*, ExecutionContextTask*);
176    void didPerformExecutionContextTask();
177    int traceAsyncOperationStarting(ExecutionContext*, const String& operationName, int prevOperationId = 0);
178    void traceAsyncOperationCompleted(ExecutionContext*, int operationId);
179    void traceAsyncOperationCompletedCallbackStarting(ExecutionContext*, int operationId);
180    void traceAsyncCallbackStarting(ExecutionContext*, int operationId);
181    void traceAsyncCallbackCompleted();
182    bool canBreakProgram();
183    void breakProgram(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data);
184    void scriptExecutionBlockedByCSP(const String& directiveText);
185
186    class Listener : public WillBeGarbageCollectedMixin {
187    public:
188        virtual ~Listener() { }
189        virtual void debuggerWasEnabled() = 0;
190        virtual void debuggerWasDisabled() = 0;
191        virtual void stepInto() = 0;
192        virtual void didPause() = 0;
193        virtual bool canPauseOnPromiseEvent() = 0;
194        virtual void didCreatePromise() = 0;
195        virtual void didResolvePromise() = 0;
196        virtual void didRejectPromise() = 0;
197    };
198    void setListener(Listener* listener) { m_listener = listener; }
199
200    bool enabled();
201
202    virtual ScriptDebugServer& scriptDebugServer() = 0;
203
204    void setBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource, const String& condition = String());
205    void removeBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource);
206
207    PassRefPtrWillBeRawPtr<ScriptAsyncCallStack> currentAsyncStackTraceForConsole();
208
209protected:
210    explicit InspectorDebuggerAgent(InjectedScriptManager*);
211
212    virtual void startListeningScriptDebugServer() = 0;
213    virtual void stopListeningScriptDebugServer() = 0;
214    virtual void muteConsole() = 0;
215    virtual void unmuteConsole() = 0;
216    InjectedScriptManager* injectedScriptManager() { return m_injectedScriptManager; }
217    virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) = 0;
218
219    virtual void enable();
220    virtual void disable();
221    virtual SkipPauseRequest didPause(ScriptState*, const ScriptValue& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints) OVERRIDE FINAL;
222    virtual void didContinue() OVERRIDE FINAL;
223    void reset();
224    void pageDidCommitLoad();
225
226private:
227    SkipPauseRequest shouldSkipExceptionPause();
228    SkipPauseRequest shouldSkipStepPause();
229    bool isTopCallFrameInFramework();
230
231    void cancelPauseOnNextStatement();
232    void addMessageToConsole(MessageSource, MessageType);
233
234    PassRefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> > currentCallFrames();
235    PassRefPtr<TypeBuilder::Debugger::StackTrace> currentAsyncStackTrace();
236
237    virtual void didParseSource(const String& scriptId, const Script&, CompileResult) OVERRIDE FINAL;
238    virtual bool v8AsyncTaskEventsEnabled() const OVERRIDE FINAL;
239    virtual void didReceiveV8AsyncTaskEvent(ExecutionContext*, const String& eventType, const String& eventName, int id) OVERRIDE FINAL;
240    virtual bool v8PromiseEventsEnabled() const OVERRIDE FINAL;
241    virtual void didReceiveV8PromiseEvent(ScriptState*, v8::Handle<v8::Object> promise, v8::Handle<v8::Value> parentPromise, int status) OVERRIDE FINAL;
242
243    void setPauseOnExceptionsImpl(ErrorString*, int);
244
245    PassRefPtr<TypeBuilder::Debugger::Location> resolveBreakpoint(const String& breakpointId, const String& scriptId, const ScriptBreakpoint&, BreakpointSource);
246    void removeBreakpoint(const String& breakpointId);
247    void clear();
248    bool assertPaused(ErrorString*);
249    void clearBreakDetails();
250
251    String sourceMapURLForScript(const Script&, CompileResult);
252
253    PassRefPtrWillBeRawPtr<JavaScriptCallFrame> topCallFrameSkipUnknownSources(String* scriptURL, bool* isBlackboxed);
254    AsyncCallStackTracker& asyncCallStackTracker() const { return *m_asyncCallStackTracker; };
255    PromiseTracker& promiseTracker() const { return *m_promiseTracker; }
256
257    typedef HashMap<String, Script> ScriptsMap;
258    typedef HashMap<String, Vector<String> > BreakpointIdToDebugServerBreakpointIdsMap;
259    typedef HashMap<String, std::pair<String, BreakpointSource> > DebugServerBreakpointToBreakpointIdAndSourceMap;
260
261    RawPtrWillBeMember<InjectedScriptManager> m_injectedScriptManager;
262    InspectorFrontend::Debugger* m_frontend;
263    RefPtr<ScriptState> m_pausedScriptState;
264    ScriptValue m_currentCallStack;
265    ScriptsMap m_scripts;
266    BreakpointIdToDebugServerBreakpointIdsMap m_breakpointIdToDebugServerBreakpointIds;
267    DebugServerBreakpointToBreakpointIdAndSourceMap m_serverBreakpoints;
268    String m_continueToLocationBreakpointId;
269    InspectorFrontend::Debugger::Reason::Enum m_breakReason;
270    RefPtr<JSONObject> m_breakAuxData;
271    bool m_javaScriptPauseScheduled;
272    bool m_debuggerStepScheduled;
273    bool m_steppingFromFramework;
274    bool m_pausingOnNativeEvent;
275    RawPtrWillBeMember<Listener> m_listener;
276
277    int m_skippedStepInCount;
278    int m_minFrameCountForSkip;
279    bool m_skipAllPauses;
280    bool m_skipContentScripts;
281    OwnPtr<ScriptRegexp> m_cachedSkipStackRegExp;
282    OwnPtrWillBeMember<AsyncCallStackTracker> m_asyncCallStackTracker;
283    OwnPtrWillBeMember<PromiseTracker> m_promiseTracker;
284};
285
286} // namespace blink
287
288
289#endif // !defined(InspectorDebuggerAgent_h)
290