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#if ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
34#include "ConsoleAPITypes.h"
35#include "ConsoleTypes.h"
36#include "InjectedScript.h"
37#include "InspectorBaseAgent.h"
38#include "InspectorFrontend.h"
39#include "ScriptBreakpoint.h"
40#include "ScriptDebugListener.h"
41#include "ScriptState.h"
42#include <wtf/Forward.h>
43#include <wtf/HashMap.h>
44#include <wtf/PassOwnPtr.h>
45#include <wtf/PassRefPtr.h>
46#include <wtf/Vector.h>
47#include <wtf/text/StringHash.h>
48
49namespace WebCore {
50
51class InjectedScriptManager;
52class InspectorFrontend;
53class InspectorArray;
54class InspectorObject;
55class InspectorState;
56class InspectorValue;
57class InstrumentingAgents;
58class ScriptDebugServer;
59class ScriptValue;
60
61typedef String ErrorString;
62
63class InspectorDebuggerAgent : public InspectorBaseAgent<InspectorDebuggerAgent>, public ScriptDebugListener, public InspectorBackendDispatcher::DebuggerCommandHandler {
64    WTF_MAKE_NONCOPYABLE(InspectorDebuggerAgent); WTF_MAKE_FAST_ALLOCATED;
65public:
66    static const char* backtraceObjectGroup;
67
68    virtual ~InspectorDebuggerAgent();
69
70    virtual void causesRecompilation(ErrorString*, bool*);
71    virtual void canSetScriptSource(ErrorString*, bool*);
72    virtual void supportsSeparateScriptCompilationAndExecution(ErrorString*, bool*);
73
74    virtual void setFrontend(InspectorFrontend*);
75    virtual void clearFrontend();
76    virtual void restore();
77
78    bool isPaused();
79    bool runningNestedMessageLoop();
80    void addMessageToConsole(MessageSource, MessageType);
81
82    // Part of the protocol.
83    virtual void enable(ErrorString*);
84    virtual void disable(ErrorString*);
85    virtual void setBreakpointsActive(ErrorString*, bool active);
86
87    virtual void setBreakpointByUrl(ErrorString*, int lineNumber, const String* optionalURL, const String* optionalURLRegex, const int* optionalColumnNumber, const String* optionalCondition, TypeBuilder::Debugger::BreakpointId*, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::Location> >& locations);
88    virtual void setBreakpoint(ErrorString*, const RefPtr<InspectorObject>& location, const String* optionalCondition, TypeBuilder::Debugger::BreakpointId*, RefPtr<TypeBuilder::Debugger::Location>& actualLocation);
89    virtual void removeBreakpoint(ErrorString*, const String& breakpointId);
90    virtual void continueToLocation(ErrorString*, const RefPtr<InspectorObject>& location);
91
92    virtual void searchInContent(ErrorString*, const String& scriptId, const String& query, const bool* optionalCaseSensitive, const bool* optionalIsRegex, RefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchMatch> >&);
93    virtual void setScriptSource(ErrorString*, const String& scriptId, const String& newContent, const bool* preview, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<InspectorObject>& result);
94    virtual void restartFrame(ErrorString*, const String& callFrameId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<InspectorObject>& result);
95    virtual void getScriptSource(ErrorString*, const String& scriptId, String* scriptSource);
96    virtual void getFunctionDetails(ErrorString*, const String& functionId, RefPtr<TypeBuilder::Debugger::FunctionDetails>&);
97    virtual void pause(ErrorString*);
98    virtual void resume(ErrorString*);
99    virtual void stepOver(ErrorString*);
100    virtual void stepInto(ErrorString*);
101    virtual void stepOut(ErrorString*);
102    virtual void setPauseOnExceptions(ErrorString*, const String& pauseState);
103    virtual void evaluateOnCallFrame(ErrorString*,
104                             const String& callFrameId,
105                             const String& expression,
106                             const String* objectGroup,
107                             const bool* includeCommandLineAPI,
108                             const bool* doNotPauseOnExceptionsAndMuteConsole,
109                             const bool* returnByValue,
110                             const bool* generatePreview,
111                             RefPtr<TypeBuilder::Runtime::RemoteObject>& result,
112                             TypeBuilder::OptOutput<bool>* wasThrown);
113    void compileScript(ErrorString*, const String& expression, const String& sourceURL, TypeBuilder::OptOutput<TypeBuilder::Debugger::ScriptId>*, TypeBuilder::OptOutput<String>* syntaxErrorMessage);
114    void runScript(ErrorString*, const TypeBuilder::Debugger::ScriptId&, const int* executionContextId, const String* objectGroup, const bool* doNotPauseOnExceptionsAndMuteConsole, RefPtr<TypeBuilder::Runtime::RemoteObject>& result, TypeBuilder::OptOutput<bool>* wasThrown);
115    virtual void setOverlayMessage(ErrorString*, const String*);
116    virtual void setVariableValue(ErrorString*, int in_scopeNumber, const String& in_variableName, const RefPtr<InspectorObject>& in_newValue, const String* in_callFrame, const String* in_functionObjectId);
117
118    void schedulePauseOnNextStatement(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<InspectorObject> data);
119    void cancelPauseOnNextStatement();
120    void breakProgram(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<InspectorObject> data);
121    virtual void scriptExecutionBlockedByCSP(const String& directiveText);
122
123    class Listener {
124    public:
125        virtual ~Listener() { }
126        virtual void debuggerWasEnabled() = 0;
127        virtual void debuggerWasDisabled() = 0;
128        virtual void stepInto() = 0;
129        virtual void didPause() = 0;
130    };
131    void setListener(Listener* listener) { m_listener = listener; }
132
133    virtual ScriptDebugServer& scriptDebugServer() = 0;
134
135protected:
136    InspectorDebuggerAgent(InstrumentingAgents*, InspectorCompositeState*, InjectedScriptManager*);
137
138    virtual void startListeningScriptDebugServer() = 0;
139    virtual void stopListeningScriptDebugServer() = 0;
140    virtual void muteConsole() = 0;
141    virtual void unmuteConsole() = 0;
142    InjectedScriptManager* injectedScriptManager() { return m_injectedScriptManager; }
143    virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) = 0;
144
145    virtual void enable();
146    virtual void disable();
147    virtual void didPause(ScriptState*, const ScriptValue& callFrames, const ScriptValue& exception);
148    virtual void didContinue();
149    void reset();
150
151private:
152    bool enabled();
153
154    PassRefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> > currentCallFrames();
155
156    virtual void didParseSource(const String& scriptId, const Script&);
157    virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage);
158
159    void setPauseOnExceptionsImpl(ErrorString*, int);
160
161    PassRefPtr<TypeBuilder::Debugger::Location> resolveBreakpoint(const String& breakpointId, const String& scriptId, const ScriptBreakpoint&);
162    void clear();
163    bool assertPaused(ErrorString*);
164    void clearBreakDetails();
165
166    String sourceMapURLForScript(const Script&);
167
168    typedef HashMap<String, Script> ScriptsMap;
169    typedef HashMap<String, Vector<String> > BreakpointIdToDebugServerBreakpointIdsMap;
170
171    InjectedScriptManager* m_injectedScriptManager;
172    InspectorFrontend::Debugger* m_frontend;
173    ScriptState* m_pausedScriptState;
174    ScriptValue m_currentCallStack;
175    ScriptsMap m_scripts;
176    BreakpointIdToDebugServerBreakpointIdsMap m_breakpointIdToDebugServerBreakpointIds;
177    String m_continueToLocationBreakpointId;
178    InspectorFrontend::Debugger::Reason::Enum m_breakReason;
179    RefPtr<InspectorObject> m_breakAuxData;
180    bool m_javaScriptPauseScheduled;
181    Listener* m_listener;
182};
183
184} // namespace WebCore
185
186#endif // ENABLE(JAVASCRIPT_DEBUGGER) && ENABLE(INSPECTOR)
187
188#endif // !defined(InspectorDebuggerAgent_h)
189