]> git.saurik.com Git - apple/javascriptcore.git/blame - inspector/ConsoleMessage.cpp
JavaScriptCore-7601.1.46.3.tar.gz
[apple/javascriptcore.git] / inspector / ConsoleMessage.cpp
CommitLineData
81345200
A
1/*
2 * Copyright (C) 2007, 2008, 2014 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 Matt Lilek <webkit@mattlilek.com>
4 * Copyright (C) 2009, 2010 Google Inc. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of
16 * its contributors may be used to endorse or promote products derived
17 * from this software without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31#include "config.h"
32#include "ConsoleMessage.h"
33
81345200
A
34#include "IdentifiersFactory.h"
35#include "InjectedScript.h"
36#include "InjectedScriptManager.h"
37#include "InspectorValues.h"
38#include "ScriptArguments.h"
39#include "ScriptCallFrame.h"
40#include "ScriptCallStack.h"
41#include "ScriptCallStackFactory.h"
42#include "ScriptValue.h"
43
44namespace Inspector {
45
46ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, unsigned long requestIdentifier)
47 : m_source(source)
48 , m_type(type)
49 , m_level(level)
50 , m_message(message)
51 , m_url()
52 , m_line(0)
53 , m_column(0)
54 , m_repeatCount(1)
55 , m_requestId(IdentifiersFactory::requestId(requestIdentifier))
56{
57}
58
59ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, const String& url, unsigned line, unsigned column, JSC::ExecState* state, unsigned long requestIdentifier)
60 : m_source(source)
61 , m_type(type)
62 , m_level(level)
63 , m_message(message)
64 , m_url(url)
65 , m_line(line)
66 , m_column(column)
67 , m_repeatCount(1)
68 , m_requestId(IdentifiersFactory::requestId(requestIdentifier))
69{
70 autogenerateMetadata(state);
71}
72
73ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptCallStack> callStack, unsigned long requestIdentifier)
74 : m_source(source)
75 , m_type(type)
76 , m_level(level)
77 , m_message(message)
78 , m_url()
79 , m_line(0)
80 , m_column(0)
81 , m_repeatCount(1)
82 , m_requestId(IdentifiersFactory::requestId(requestIdentifier))
83{
84 m_callStack = callStack;
85
86 const ScriptCallFrame* frame = m_callStack ? m_callStack->firstNonNativeCallFrame() : nullptr;
87 if (frame) {
88 m_url = frame->sourceURL();
89 m_line = frame->lineNumber();
90 m_column = frame->columnNumber();
91 }
92}
93
94ConsoleMessage::ConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, PassRefPtr<ScriptArguments> arguments, JSC::ExecState* state, unsigned long requestIdentifier)
95 : m_source(source)
96 , m_type(type)
97 , m_level(level)
98 , m_message(message)
99 , m_arguments(arguments)
100 , m_url()
101 , m_line(0)
102 , m_column(0)
103 , m_repeatCount(1)
104 , m_requestId(IdentifiersFactory::requestId(requestIdentifier))
105{
106 autogenerateMetadata(state);
107}
108
109ConsoleMessage::~ConsoleMessage()
110{
111}
112
113void ConsoleMessage::autogenerateMetadata(JSC::ExecState* state)
114{
115 if (!state)
116 return;
117
118 if (m_type == MessageType::EndGroup)
119 return;
120
121 // FIXME: Should this really be using "for console" in the generic ConsoleMessage autogeneration? This can skip the first frame.
122 m_callStack = createScriptCallStackForConsole(state, ScriptCallStack::maxCallStackSizeToCapture);
123
124 if (const ScriptCallFrame* frame = m_callStack->firstNonNativeCallFrame()) {
125 m_url = frame->sourceURL();
126 m_line = frame->lineNumber();
127 m_column = frame->columnNumber();
128 return;
129 }
130}
131
ed1e77d3 132static Inspector::Protocol::Console::ConsoleMessage::Source messageSourceValue(MessageSource source)
81345200
A
133{
134 switch (source) {
ed1e77d3
A
135 case MessageSource::XML: return Inspector::Protocol::Console::ConsoleMessage::Source::XML;
136 case MessageSource::JS: return Inspector::Protocol::Console::ConsoleMessage::Source::Javascript;
137 case MessageSource::Network: return Inspector::Protocol::Console::ConsoleMessage::Source::Network;
138 case MessageSource::ConsoleAPI: return Inspector::Protocol::Console::ConsoleMessage::Source::ConsoleAPI;
139 case MessageSource::Storage: return Inspector::Protocol::Console::ConsoleMessage::Source::Storage;
140 case MessageSource::AppCache: return Inspector::Protocol::Console::ConsoleMessage::Source::Appcache;
141 case MessageSource::Rendering: return Inspector::Protocol::Console::ConsoleMessage::Source::Rendering;
142 case MessageSource::CSS: return Inspector::Protocol::Console::ConsoleMessage::Source::CSS;
143 case MessageSource::Security: return Inspector::Protocol::Console::ConsoleMessage::Source::Security;
144 case MessageSource::ContentBlocker: return Inspector::Protocol::Console::ConsoleMessage::Source::ContentBlocker;
145 case MessageSource::Other: return Inspector::Protocol::Console::ConsoleMessage::Source::Other;
81345200 146 }
ed1e77d3 147 return Inspector::Protocol::Console::ConsoleMessage::Source::Other;
81345200
A
148}
149
ed1e77d3 150static Inspector::Protocol::Console::ConsoleMessage::Type messageTypeValue(MessageType type)
81345200
A
151{
152 switch (type) {
ed1e77d3
A
153 case MessageType::Log: return Inspector::Protocol::Console::ConsoleMessage::Type::Log;
154 case MessageType::Clear: return Inspector::Protocol::Console::ConsoleMessage::Type::Clear;
155 case MessageType::Dir: return Inspector::Protocol::Console::ConsoleMessage::Type::Dir;
156 case MessageType::DirXML: return Inspector::Protocol::Console::ConsoleMessage::Type::DirXML;
157 case MessageType::Table: return Inspector::Protocol::Console::ConsoleMessage::Type::Table;
158 case MessageType::Trace: return Inspector::Protocol::Console::ConsoleMessage::Type::Trace;
159 case MessageType::StartGroup: return Inspector::Protocol::Console::ConsoleMessage::Type::StartGroup;
160 case MessageType::StartGroupCollapsed: return Inspector::Protocol::Console::ConsoleMessage::Type::StartGroupCollapsed;
161 case MessageType::EndGroup: return Inspector::Protocol::Console::ConsoleMessage::Type::EndGroup;
162 case MessageType::Assert: return Inspector::Protocol::Console::ConsoleMessage::Type::Assert;
163 case MessageType::Timing: return Inspector::Protocol::Console::ConsoleMessage::Type::Timing;
164 case MessageType::Profile: return Inspector::Protocol::Console::ConsoleMessage::Type::Profile;
165 case MessageType::ProfileEnd: return Inspector::Protocol::Console::ConsoleMessage::Type::ProfileEnd;
81345200 166 }
ed1e77d3 167 return Inspector::Protocol::Console::ConsoleMessage::Type::Log;
81345200
A
168}
169
ed1e77d3 170static Inspector::Protocol::Console::ConsoleMessage::Level messageLevelValue(MessageLevel level)
81345200
A
171{
172 switch (level) {
ed1e77d3
A
173 case MessageLevel::Log: return Inspector::Protocol::Console::ConsoleMessage::Level::Log;
174 case MessageLevel::Info: return Inspector::Protocol::Console::ConsoleMessage::Level::Info;
175 case MessageLevel::Warning: return Inspector::Protocol::Console::ConsoleMessage::Level::Warning;
176 case MessageLevel::Error: return Inspector::Protocol::Console::ConsoleMessage::Level::Error;
177 case MessageLevel::Debug: return Inspector::Protocol::Console::ConsoleMessage::Level::Debug;
81345200 178 }
ed1e77d3 179 return Inspector::Protocol::Console::ConsoleMessage::Level::Log;
81345200
A
180}
181
ed1e77d3 182void ConsoleMessage::addToFrontend(ConsoleFrontendDispatcher* consoleFrontendDispatcher, InjectedScriptManager* injectedScriptManager, bool generatePreview)
81345200 183{
ed1e77d3 184 Ref<Inspector::Protocol::Console::ConsoleMessage> jsonObj = Inspector::Protocol::Console::ConsoleMessage::create()
81345200
A
185 .setSource(messageSourceValue(m_source))
186 .setLevel(messageLevelValue(m_level))
ed1e77d3
A
187 .setText(m_message)
188 .release();
81345200
A
189
190 // FIXME: only send out type for ConsoleAPI source messages.
191 jsonObj->setType(messageTypeValue(m_type));
192 jsonObj->setLine(static_cast<int>(m_line));
193 jsonObj->setColumn(static_cast<int>(m_column));
194 jsonObj->setUrl(m_url);
195 jsonObj->setRepeatCount(static_cast<int>(m_repeatCount));
196
197 if (m_source == MessageSource::Network && !m_requestId.isEmpty())
198 jsonObj->setNetworkRequestId(m_requestId);
199
200 if (m_arguments && m_arguments->argumentCount()) {
201 InjectedScript injectedScript = injectedScriptManager->injectedScriptFor(m_arguments->globalState());
202 if (!injectedScript.hasNoValue()) {
ed1e77d3 203 Ref<Inspector::Protocol::Array<Inspector::Protocol::Runtime::RemoteObject>> jsonArgs = Inspector::Protocol::Array<Inspector::Protocol::Runtime::RemoteObject>::create();
81345200
A
204 if (m_type == MessageType::Table && generatePreview && m_arguments->argumentCount()) {
205 Deprecated::ScriptValue table = m_arguments->argumentAt(0);
206 Deprecated::ScriptValue columns = m_arguments->argumentCount() > 1 ? m_arguments->argumentAt(1) : Deprecated::ScriptValue();
ed1e77d3 207 RefPtr<Inspector::Protocol::Runtime::RemoteObject> inspectorValue = injectedScript.wrapTable(table, columns);
81345200
A
208 if (!inspectorValue) {
209 ASSERT_NOT_REACHED();
210 return;
211 }
ed1e77d3
A
212 jsonArgs->addItem(inspectorValue.copyRef());
213 if (m_arguments->argumentCount() > 1)
214 jsonArgs->addItem(injectedScript.wrapObject(columns, ASCIILiteral("console"), true));
81345200
A
215 } else {
216 for (unsigned i = 0; i < m_arguments->argumentCount(); ++i) {
ed1e77d3 217 RefPtr<Inspector::Protocol::Runtime::RemoteObject> inspectorValue = injectedScript.wrapObject(m_arguments->argumentAt(i), ASCIILiteral("console"), generatePreview);
81345200
A
218 if (!inspectorValue) {
219 ASSERT_NOT_REACHED();
220 return;
221 }
ed1e77d3 222 jsonArgs->addItem(inspectorValue.copyRef());
81345200
A
223 }
224 }
ed1e77d3 225 jsonObj->setParameters(WTF::move(jsonArgs));
81345200
A
226 }
227 }
228
229 if (m_callStack)
230 jsonObj->setStackTrace(m_callStack->buildInspectorArray());
231
ed1e77d3 232 consoleFrontendDispatcher->messageAdded(WTF::move(jsonObj));
81345200
A
233}
234
ed1e77d3 235void ConsoleMessage::updateRepeatCountInConsole(ConsoleFrontendDispatcher* consoleFrontendDispatcher)
81345200
A
236{
237 consoleFrontendDispatcher->messageRepeatCountUpdated(m_repeatCount);
238}
239
240bool ConsoleMessage::isEqual(ConsoleMessage* msg) const
241{
242 if (m_arguments) {
243 if (!m_arguments->isEqual(msg->m_arguments.get()))
244 return false;
245
246 // Never treat objects as equal - their properties might change over time.
247 for (size_t i = 0; i < m_arguments->argumentCount(); ++i) {
248 if (m_arguments->argumentAt(i).isObject())
249 return false;
250 }
251 } else if (msg->m_arguments)
252 return false;
253
254 if (m_callStack) {
255 if (!m_callStack->isEqual(msg->m_callStack.get()))
256 return false;
257 } else if (msg->m_callStack)
258 return false;
259
260 return msg->m_source == m_source
261 && msg->m_type == m_type
262 && msg->m_level == m_level
263 && msg->m_message == m_message
264 && msg->m_line == m_line
265 && msg->m_column == m_column
266 && msg->m_url == m_url
267 && msg->m_requestId == m_requestId;
268}
269
270void ConsoleMessage::clear()
271{
272 if (!m_message)
273 m_message = ASCIILiteral("<message collected>");
274
275 if (m_arguments)
ed1e77d3 276 m_arguments = nullptr;
81345200
A
277}
278
279JSC::ExecState* ConsoleMessage::scriptState() const
280{
281 if (m_arguments)
282 return m_arguments->globalState();
283
284 return nullptr;
285}
286
287unsigned ConsoleMessage::argumentCount() const
288{
289 if (m_arguments)
290 return m_arguments->argumentCount();
291
292 return 0;
293}
294
295} // namespace Inspector