Home | History | Annotate | Download | only in inspector
      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 "InspectorFrontend.h"
     34 #include "bindings/v8/ScriptState.h"
     35 #include "core/inspector/AsyncCallStackTracker.h"
     36 #include "core/inspector/ConsoleAPITypes.h"
     37 #include "core/inspector/InjectedScript.h"
     38 #include "core/inspector/InspectorBaseAgent.h"
     39 #include "core/inspector/ScriptBreakpoint.h"
     40 #include "core/inspector/ScriptDebugListener.h"
     41 #include "core/frame/ConsoleTypes.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 
     48 namespace WebCore {
     49 
     50 class Document;
     51 class InjectedScriptManager;
     52 class InspectorFrontend;
     53 class InstrumentingAgents;
     54 class JSONObject;
     55 class ScriptArguments;
     56 class ScriptCallStack;
     57 class ScriptDebugServer;
     58 class ScriptSourceCode;
     59 class ScriptValue;
     60 class ScriptRegexp;
     61 
     62 typedef String ErrorString;
     63 
     64 class InspectorDebuggerAgent : public InspectorBaseAgent<InspectorDebuggerAgent>, public ScriptDebugListener, public InspectorBackendDispatcher::DebuggerCommandHandler {
     65     WTF_MAKE_NONCOPYABLE(InspectorDebuggerAgent); WTF_MAKE_FAST_ALLOCATED;
     66 public:
     67     enum BreakpointSource {
     68         UserBreakpointSource,
     69         DebugCommandBreakpointSource,
     70         MonitorCommandBreakpointSource
     71     };
     72 
     73     static const char backtraceObjectGroup[];
     74 
     75     virtual ~InspectorDebuggerAgent();
     76 
     77     virtual void canSetScriptSource(ErrorString*, bool* result) { *result = true; }
     78 
     79     virtual void setFrontend(InspectorFrontend*);
     80     virtual void clearFrontend();
     81     virtual void restore();
     82 
     83     bool isPaused();
     84     bool runningNestedMessageLoop();
     85     void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String&, PassRefPtr<ScriptCallStack>, unsigned long);
     86     void addMessageToConsole(MessageSource, MessageType, MessageLevel, const String&, ScriptState*, PassRefPtr<ScriptArguments>, unsigned long);
     87 
     88     String preprocessEventListener(Frame*, const String& source, const String& url, const String& functionName);
     89     PassOwnPtr<ScriptSourceCode> preprocess(Frame*, const ScriptSourceCode&);
     90 
     91     // Part of the protocol.
     92     virtual void enable(ErrorString*);
     93     virtual void disable(ErrorString*);
     94     virtual void setBreakpointsActive(ErrorString*, bool active);
     95     virtual void setSkipAllPauses(ErrorString*, bool skipped, const bool* untilReload);
     96 
     97     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);
     98     virtual void setBreakpoint(ErrorString*, const RefPtr<JSONObject>& location, const String* optionalCondition, TypeBuilder::Debugger::BreakpointId*, RefPtr<TypeBuilder::Debugger::Location>& actualLocation);
     99     virtual void removeBreakpoint(ErrorString*, const String& breakpointId);
    100     virtual void continueToLocation(ErrorString*, const RefPtr<JSONObject>& location, const bool* interstateLocationOpt);
    101     virtual void getStepInPositions(ErrorString*, const String& callFrameId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::Location> >& positions);
    102     virtual void getBacktrace(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >&, RefPtr<TypeBuilder::Debugger::StackTrace>&);
    103 
    104     virtual void searchInContent(ErrorString*, const String& scriptId, const String& query, const bool* optionalCaseSensitive, const bool* optionalIsRegex, RefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchMatch> >&);
    105     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);
    106     virtual void restartFrame(ErrorString*, const String& callFrameId, RefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> >& newCallFrames, RefPtr<JSONObject>& result, RefPtr<TypeBuilder::Debugger::StackTrace>& asyncStackTrace);
    107     virtual void getScriptSource(ErrorString*, const String& scriptId, String* scriptSource);
    108     virtual void getFunctionDetails(ErrorString*, const String& functionId, RefPtr<TypeBuilder::Debugger::FunctionDetails>&);
    109     virtual void pause(ErrorString*);
    110     virtual void resume(ErrorString*);
    111     virtual void stepOver(ErrorString*, const String* callFrameId);
    112     virtual void stepInto(ErrorString*);
    113     virtual void stepOut(ErrorString*, const String* callFrameId);
    114     virtual void setPauseOnExceptions(ErrorString*, const String& pauseState);
    115     virtual void evaluateOnCallFrame(ErrorString*,
    116                              const String& callFrameId,
    117                              const String& expression,
    118                              const String* objectGroup,
    119                              const bool* includeCommandLineAPI,
    120                              const bool* doNotPauseOnExceptionsAndMuteConsole,
    121                              const bool* returnByValue,
    122                              const bool* generatePreview,
    123                              RefPtr<TypeBuilder::Runtime::RemoteObject>& result,
    124                              TypeBuilder::OptOutput<bool>* wasThrown);
    125     void compileScript(ErrorString*, const String& expression, const String& sourceURL, TypeBuilder::OptOutput<TypeBuilder::Debugger::ScriptId>*, TypeBuilder::OptOutput<String>* syntaxErrorMessage);
    126     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);
    127     virtual void setOverlayMessage(ErrorString*, const String*);
    128     virtual void setVariableValue(ErrorString*, int in_scopeNumber, const String& in_variableName, const RefPtr<JSONObject>& in_newValue, const String* in_callFrame, const String* in_functionObjectId);
    129     virtual void skipStackFrames(ErrorString*, const String* pattern);
    130     virtual void setAsyncCallStackDepth(ErrorString*, int depth);
    131 
    132     void schedulePauseOnNextStatement(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data);
    133     void didInstallTimer(ExecutionContext*, int timerId, int timeout, bool singleShot);
    134     void didRemoveTimer(ExecutionContext*, int timerId);
    135     bool willFireTimer(ExecutionContext*, int timerId);
    136     void didFireTimer();
    137     void didRequestAnimationFrame(Document*, int callbackId);
    138     void didCancelAnimationFrame(Document*, int callbackId);
    139     bool willFireAnimationFrame(Document*, int callbackId);
    140     void didFireAnimationFrame();
    141     void didHandleEvent();
    142     bool canBreakProgram();
    143     void breakProgram(InspectorFrontend::Debugger::Reason::Enum breakReason, PassRefPtr<JSONObject> data);
    144     virtual void scriptExecutionBlockedByCSP(const String& directiveText);
    145 
    146     class Listener {
    147     public:
    148         virtual ~Listener() { }
    149         virtual void debuggerWasEnabled() = 0;
    150         virtual void debuggerWasDisabled() = 0;
    151         virtual void stepInto() = 0;
    152         virtual void didPause() = 0;
    153     };
    154     void setListener(Listener* listener) { m_listener = listener; }
    155 
    156     virtual ScriptDebugServer& scriptDebugServer() = 0;
    157 
    158     void setBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource, const String& condition = String());
    159     void removeBreakpoint(const String& scriptId, int lineNumber, int columnNumber, BreakpointSource);
    160 
    161     SkipPauseRequest shouldSkipExceptionPause(RefPtr<JavaScriptCallFrame>& topFrame);
    162     SkipPauseRequest shouldSkipBreakpointPause(RefPtr<JavaScriptCallFrame>& topFrame);
    163     SkipPauseRequest shouldSkipStepPause(RefPtr<JavaScriptCallFrame>& topFrame);
    164 
    165 protected:
    166     InspectorDebuggerAgent(InstrumentingAgents*, InspectorCompositeState*, InjectedScriptManager*);
    167 
    168     virtual void startListeningScriptDebugServer() = 0;
    169     virtual void stopListeningScriptDebugServer() = 0;
    170     virtual void muteConsole() = 0;
    171     virtual void unmuteConsole() = 0;
    172     InjectedScriptManager* injectedScriptManager() { return m_injectedScriptManager; }
    173     virtual InjectedScript injectedScriptForEval(ErrorString*, const int* executionContextId) = 0;
    174 
    175     virtual void enable();
    176     virtual void disable();
    177     virtual void didPause(ScriptState*, const ScriptValue& callFrames, const ScriptValue& exception, const Vector<String>& hitBreakpoints);
    178     virtual void didContinue();
    179     void reset();
    180     void pageDidCommitLoad();
    181 
    182 private:
    183     void cancelPauseOnNextStatement();
    184     void addMessageToConsole(MessageSource, MessageType);
    185 
    186     bool enabled();
    187 
    188     PassRefPtr<TypeBuilder::Array<TypeBuilder::Debugger::CallFrame> > currentCallFrames();
    189     PassRefPtr<TypeBuilder::Debugger::StackTrace> currentAsyncStackTrace();
    190 
    191     virtual void didParseSource(const String& scriptId, const Script&);
    192     virtual void failedToParseSource(const String& url, const String& data, int firstLine, int errorLine, const String& errorMessage);
    193 
    194     void setPauseOnExceptionsImpl(ErrorString*, int);
    195 
    196     PassRefPtr<TypeBuilder::Debugger::Location> resolveBreakpoint(const String& breakpointId, const String& scriptId, const ScriptBreakpoint&, BreakpointSource);
    197     void removeBreakpoint(const String& breakpointId);
    198     void clear();
    199     bool assertPaused(ErrorString*);
    200     void clearBreakDetails();
    201 
    202     String sourceMapURLForScript(const Script&);
    203 
    204     String scriptURL(JavaScriptCallFrame*);
    205 
    206     ScriptValue resolveCallFrame(ErrorString*, const String* callFrameId);
    207 
    208     typedef HashMap<String, Script> ScriptsMap;
    209     typedef HashMap<String, Vector<String> > BreakpointIdToDebugServerBreakpointIdsMap;
    210     typedef HashMap<String, std::pair<String, BreakpointSource> > DebugServerBreakpointToBreakpointIdAndSourceMap;
    211 
    212     InjectedScriptManager* m_injectedScriptManager;
    213     InspectorFrontend::Debugger* m_frontend;
    214     ScriptState* m_pausedScriptState;
    215     ScriptValue m_currentCallStack;
    216     ScriptsMap m_scripts;
    217     BreakpointIdToDebugServerBreakpointIdsMap m_breakpointIdToDebugServerBreakpointIds;
    218     DebugServerBreakpointToBreakpointIdAndSourceMap m_serverBreakpoints;
    219     String m_continueToLocationBreakpointId;
    220     InspectorFrontend::Debugger::Reason::Enum m_breakReason;
    221     RefPtr<JSONObject> m_breakAuxData;
    222     bool m_javaScriptPauseScheduled;
    223     Listener* m_listener;
    224 
    225     int m_skipStepInCount;
    226     bool m_skipAllPauses;
    227     OwnPtr<ScriptRegexp> m_cachedSkipStackRegExp;
    228     AsyncCallStackTracker m_asyncCallStackTracker;
    229 };
    230 
    231 } // namespace WebCore
    232 
    233 
    234 #endif // !defined(InspectorDebuggerAgent_h)
    235