Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(224)

Side by Side Diff: third_party/WebKit/Source/platform/v8_inspector/V8ConsoleMessage.cpp

Issue 2035653006: [DevTools] Move Console to v8 inspector. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: all tests pass Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "platform/v8_inspector/V8ConsoleMessage.h"
6
7 #include "platform/v8_inspector/InspectedContext.h"
8 #include "platform/v8_inspector/V8ConsoleAgentImpl.h"
9 #include "platform/v8_inspector/V8DebuggerImpl.h"
10 #include "platform/v8_inspector/V8InspectorSessionImpl.h"
11 #include "platform/v8_inspector/V8StackTraceImpl.h"
12 #include "platform/v8_inspector/V8StringUtil.h"
13 #include "platform/v8_inspector/public/V8DebuggerClient.h"
14
15 namespace blink {
16
17 namespace {
18
19 String messageSourceValue(MessageSource source)
20 {
21 switch (source) {
22 case XMLMessageSource: return protocol::Console::ConsoleMessage::SourceEnum: :Xml;
23 case JSMessageSource: return protocol::Console::ConsoleMessage::SourceEnum:: Javascript;
24 case NetworkMessageSource: return protocol::Console::ConsoleMessage::SourceE num::Network;
25 case ConsoleAPIMessageSource: return protocol::Console::ConsoleMessage::Sour ceEnum::ConsoleApi;
26 case StorageMessageSource: return protocol::Console::ConsoleMessage::SourceE num::Storage;
27 case AppCacheMessageSource: return protocol::Console::ConsoleMessage::Source Enum::Appcache;
28 case RenderingMessageSource: return protocol::Console::ConsoleMessage::Sourc eEnum::Rendering;
29 case SecurityMessageSource: return protocol::Console::ConsoleMessage::Source Enum::Security;
30 case OtherMessageSource: return protocol::Console::ConsoleMessage::SourceEnu m::Other;
31 case DeprecationMessageSource: return protocol::Console::ConsoleMessage::Sou rceEnum::Deprecation;
32 }
33 return protocol::Console::ConsoleMessage::SourceEnum::Other;
34 }
35
36
37 String messageTypeValue(MessageType type)
38 {
39 switch (type) {
40 case LogMessageType: return protocol::Console::ConsoleMessage::TypeEnum::Log ;
41 case ClearMessageType: return protocol::Console::ConsoleMessage::TypeEnum::C lear;
42 case DirMessageType: return protocol::Console::ConsoleMessage::TypeEnum::Dir ;
43 case DirXMLMessageType: return protocol::Console::ConsoleMessage::TypeEnum:: Dirxml;
44 case TableMessageType: return protocol::Console::ConsoleMessage::TypeEnum::T able;
45 case TraceMessageType: return protocol::Console::ConsoleMessage::TypeEnum::T race;
46 case StartGroupMessageType: return protocol::Console::ConsoleMessage::TypeEn um::StartGroup;
47 case StartGroupCollapsedMessageType: return protocol::Console::ConsoleMessag e::TypeEnum::StartGroupCollapsed;
48 case EndGroupMessageType: return protocol::Console::ConsoleMessage::TypeEnum ::EndGroup;
49 case AssertMessageType: return protocol::Console::ConsoleMessage::TypeEnum:: Assert;
50 case TimeEndMessageType: return protocol::Console::ConsoleMessage::TypeEnum: :Log;
51 case CountMessageType: return protocol::Console::ConsoleMessage::TypeEnum::L og;
52 }
53 return protocol::Console::ConsoleMessage::TypeEnum::Log;
54 }
55
56 String messageLevelValue(MessageLevel level)
57 {
58 switch (level) {
59 case DebugMessageLevel: return protocol::Console::ConsoleMessage::LevelEnum: :Debug;
60 case LogMessageLevel: return protocol::Console::ConsoleMessage::LevelEnum::L og;
61 case WarningMessageLevel: return protocol::Console::ConsoleMessage::LevelEnu m::Warning;
62 case ErrorMessageLevel: return protocol::Console::ConsoleMessage::LevelEnum: :Error;
63 case InfoMessageLevel: return protocol::Console::ConsoleMessage::LevelEnum:: Info;
64 case RevokedErrorMessageLevel: return protocol::Console::ConsoleMessage::Lev elEnum::RevokedError;
65 }
66 return protocol::Console::ConsoleMessage::LevelEnum::Log;
67 }
68
69 const unsigned maxConsoleMessageCount = 1000;
70 const unsigned maxArrayItemsLimit = 10000;
71 const unsigned maxStackDepthLimit = 32;
72
73 class V8ValueStringBuilder {
74 public:
75 static String16 toString(v8::Local<v8::Value> value, v8::Isolate* isolate)
76 {
77 V8ValueStringBuilder builder(isolate);
78 if (!builder.append(value))
79 return String16();
80 return builder.toString();
81 }
82
83 private:
84 enum {
85 IgnoreNull = 1 << 0,
86 IgnoreUndefined = 1 << 1,
87 };
88
89 V8ValueStringBuilder(v8::Isolate* isolate)
90 : m_arrayLimit(maxArrayItemsLimit)
91 , m_isolate(isolate)
92 , m_tryCatch(isolate)
93 {
94 }
95
96 bool append(v8::Local<v8::Value> value, unsigned ignoreOptions = 0)
97 {
98 if (value.IsEmpty())
99 return true;
100 if ((ignoreOptions & IgnoreNull) && value->IsNull())
101 return true;
102 if ((ignoreOptions & IgnoreUndefined) && value->IsUndefined())
103 return true;
104 if (value->IsString())
105 return append(v8::Local<v8::String>::Cast(value));
106 if (value->IsStringObject())
107 return append(v8::Local<v8::StringObject>::Cast(value)->ValueOf());
108 if (value->IsSymbol())
109 return append(v8::Local<v8::Symbol>::Cast(value));
110 if (value->IsSymbolObject())
111 return append(v8::Local<v8::SymbolObject>::Cast(value)->ValueOf());
112 if (value->IsNumberObject()) {
113 m_builder.appendNumber(v8::Local<v8::NumberObject>::Cast(value)->Val ueOf());
114 return true;
115 }
116 if (value->IsBooleanObject()) {
117 m_builder.append(v8::Local<v8::BooleanObject>::Cast(value)->ValueOf( ) ? "true" : "false");
118 return true;
119 }
120 if (value->IsArray())
121 return append(v8::Local<v8::Array>::Cast(value));
122 if (value->IsProxy()) {
123 m_builder.append("[object Proxy]");
124 return true;
125 }
126 if (value->IsObject()
127 && !value->IsDate()
128 && !value->IsFunction()
129 && !value->IsNativeError()
130 && !value->IsRegExp()) {
131 v8::Local<v8::Object> object = v8::Local<v8::Object>::Cast(value);
132 v8::Local<v8::String> stringValue;
133 if (object->ObjectProtoToString(m_isolate->GetCurrentContext()).ToLo cal(&stringValue))
134 return append(stringValue);
135 }
136 v8::Local<v8::String> stringValue;
137 if (!value->ToString(m_isolate->GetCurrentContext()).ToLocal(&stringValu e))
138 return false;
139 return append(stringValue);
140 }
141
142 bool append(v8::Local<v8::Array> array)
143 {
144 if (m_visitedArrays.contains(array))
145 return true;
146 uint32_t length = array->Length();
147 if (length > m_arrayLimit)
148 return false;
149 if (m_visitedArrays.size() > maxStackDepthLimit)
150 return false;
151
152 bool result = true;
153 m_arrayLimit -= length;
154 m_visitedArrays.append(array);
155 for (uint32_t i = 0; i < length; ++i) {
156 if (i)
157 m_builder.append(',');
158 if (!append(array->Get(i), IgnoreNull | IgnoreUndefined)) {
159 result = false;
160 break;
161 }
162 }
163 m_visitedArrays.removeLast();
164 return result;
165 }
166
167 bool append(v8::Local<v8::Symbol> symbol)
168 {
169 m_builder.append("Symbol(");
170 bool result = append(symbol->Name(), IgnoreUndefined);
171 m_builder.append(')');
172 return result;
173 }
174
175 bool append(v8::Local<v8::String> string)
176 {
177 if (m_tryCatch.HasCaught())
178 return false;
179 if (!string.IsEmpty())
180 m_builder.append(toProtocolString(string));
181 return true;
182 }
183
184 String16 toString()
185 {
186 if (m_tryCatch.HasCaught())
187 return String16();
188 return m_builder.toString();
189 }
190
191 uint32_t m_arrayLimit;
192 v8::Isolate* m_isolate;
193 String16Builder m_builder;
194 Vector<v8::Local<v8::Array>> m_visitedArrays;
195 v8::TryCatch m_tryCatch;
196 };
197
198 } // namespace
199
200 V8ConsoleMessage::V8ConsoleMessage(
201 double timestampMS,
202 MessageSource source,
203 MessageLevel level,
204 const String16& message,
205 const String16& url,
206 unsigned lineNumber,
207 unsigned columnNumber,
208 std::unique_ptr<V8StackTrace> stackTrace,
209 int scriptId,
210 const String16& requestIdentifier)
211 : m_timestamp(timestampMS / 1000.0)
212 , m_source(source)
213 , m_level(level)
214 , m_message(message)
215 , m_url(url)
216 , m_lineNumber(lineNumber)
217 , m_columnNumber(columnNumber)
218 , m_stackTrace(std::move(stackTrace))
219 , m_scriptId(scriptId)
220 , m_requestIdentifier(requestIdentifier)
221 , m_contextId(0)
222 , m_type(LogMessageType)
223 , m_messageId(0)
224 , m_relatedMessageId(0)
225 {
226 }
227
228 V8ConsoleMessage::~V8ConsoleMessage()
229 {
230 }
231
232 std::unique_ptr<protocol::Console::ConsoleMessage> V8ConsoleMessage::buildInspec torObject(V8InspectorSessionImpl* session, bool generatePreview) const
233 {
234 std::unique_ptr<protocol::Console::ConsoleMessage> result =
235 protocol::Console::ConsoleMessage::create()
236 .setSource(messageSourceValue(m_source))
237 .setLevel(messageLevelValue(m_level))
238 .setText(m_message)
239 .setTimestamp(m_timestamp)
240 .build();
241 result->setType(messageTypeValue(m_type));
242 result->setLine(static_cast<int>(m_lineNumber));
243 result->setColumn(static_cast<int>(m_columnNumber));
244 if (m_scriptId)
245 result->setScriptId(String::number(m_scriptId));
246 result->setUrl(m_url);
247 if (m_source == NetworkMessageSource && !m_requestIdentifier.isEmpty())
248 result->setNetworkRequestId(m_requestIdentifier);
249 if (m_contextId)
250 result->setExecutionContextId(m_contextId);
251 appendArguments(result.get(), session, generatePreview);
252 if (m_stackTrace)
253 result->setStack(m_stackTrace->buildInspectorObject());
254 if (m_messageId)
255 result->setMessageId(m_messageId);
256 if (m_relatedMessageId)
257 result->setRelatedMessageId(m_relatedMessageId);
258 return result;
259 }
260
261 void V8ConsoleMessage::appendArguments(protocol::Console::ConsoleMessage* result , V8InspectorSessionImpl* session, bool generatePreview) const
262 {
263 if (!m_arguments.size() || !m_contextId)
264 return;
265 const V8DebuggerImpl::ContextByIdMap* contexts = session->debugger()->contex tGroup(session->contextGroupId());
266 if (!contexts || !contexts->contains(m_contextId))
267 return;
268
269 InspectedContext* inspectedContext = contexts->get(m_contextId);
270 v8::Isolate* isolate = inspectedContext->isolate();
271 v8::HandleScope handles(isolate);
272 v8::Local<v8::Context> context = inspectedContext->context();
273
274 std::unique_ptr<protocol::Array<protocol::Runtime::RemoteObject>> args = pro tocol::Array<protocol::Runtime::RemoteObject>::create();
275 if (m_type == TableMessageType && generatePreview) {
276 v8::Local<v8::Value> table = m_arguments[0]->Get(isolate);
277 v8::Local<v8::Value> columns = m_arguments.size() > 1 ? m_arguments[1]-> Get(isolate) : v8::Local<v8::Value>();
278 std::unique_ptr<protocol::Runtime::RemoteObject> wrapped = session->wrap Table(context, table, columns);
279 if (wrapped)
280 args->addItem(std::move(wrapped));
281 else
282 args = nullptr;
283 } else {
284 for (size_t i = 0; i < m_arguments.size(); ++i) {
285 std::unique_ptr<protocol::Runtime::RemoteObject> wrapped = session-> wrapObject(context, m_arguments[i]->Get(isolate), "console", generatePreview);
286 if (!wrapped) {
287 args = nullptr;
288 break;
289 }
290 args->addItem(std::move(wrapped));
291 }
292 }
293 if (args)
294 result->setParameters(std::move(args));
295 }
296
297 unsigned V8ConsoleMessage::argumentCount() const
298 {
299 return m_arguments.size();
300 }
301
302 MessageType V8ConsoleMessage::type() const
303 {
304 return m_type;
305 }
306
307 // static
308 std::unique_ptr<V8ConsoleMessage> V8ConsoleMessage::createForConsoleAPI(double t imestampMS, MessageType type, MessageLevel level, const String16& messageText, p rotocol::Vector<v8::Local<v8::Value>>* arguments, std::unique_ptr<V8StackTrace> stackTrace, InspectedContext* context)
309 {
310 String16 url;
311 unsigned lineNumber = 0;
312 unsigned columnNumber = 0;
313 if (stackTrace && !stackTrace->isEmpty()) {
314 url = stackTrace->topSourceURL();
315 lineNumber = stackTrace->topLineNumber();
316 columnNumber = stackTrace->topColumnNumber();
317 }
318
319 String16 actualMessage = messageText;
320
321 Arguments messageArguments;
322 if (arguments) {
kozy 2016/06/23 22:28:43 && arguments.size()
dgozman 2016/06/28 01:43:48 Done.
323 for (size_t i = 0; i < arguments->size(); ++i)
324 messageArguments.append(wrapUnique(new v8::Global<v8::Value>(context ->isolate(), arguments->at(i))));
325 if (actualMessage.isEmpty() && messageArguments.size())
326 actualMessage = V8ValueStringBuilder::toString(messageArguments.at(0 )->Get(context->isolate()), context->isolate());
327 }
328
329 std::unique_ptr<V8ConsoleMessage> message = wrapUnique(new V8ConsoleMessage( timestampMS, ConsoleAPIMessageSource, level, actualMessage, url, lineNumber, col umnNumber, std::move(stackTrace), 0, String16()));
kozy 2016/06/23 22:28:43 0 /* scriptId */, String16() /* requestIdentifier
dgozman 2016/06/28 01:43:48 Done.
330 message->m_type = type;
331 if (messageArguments.size()) {
332 message->m_contextId = context->contextId();
333 message->m_arguments.swap(messageArguments);
334 }
335
336 context->debugger()->client()->messageAddedToConsole(context->contextGroupId (), message->m_source, message->m_level, message->m_message, message->m_url, mes sage->m_lineNumber, message->m_columnNumber, message->m_stackTrace.get());
337 return message;
338 }
339
340 void V8ConsoleMessage::contextDestroyed(int contextId)
341 {
342 if (contextId != m_contextId)
343 return;
344 m_contextId = 0;
345 if (m_message.isEmpty())
346 m_message = "<message collected>";
347 Arguments empty;
348 m_arguments.swap(empty);
349 }
350
351 void V8ConsoleMessage::assignId(unsigned id)
352 {
353 m_messageId = id;
354 }
355
356 void V8ConsoleMessage::assignRelatedId(unsigned id)
357 {
358 m_relatedMessageId = id;
359 }
360
361 void V8ConsoleMessage::addArguments(v8::Isolate* isolate, int contextId, protoco l::Vector<v8::Local<v8::Value>>* arguments)
362 {
363 if (!arguments || !contextId)
364 return;
365 m_contextId = contextId;
366 for (size_t i = 0; i < arguments->size(); ++i)
367 m_arguments.append(wrapUnique(new v8::Global<v8::Value>(isolate, argumen ts->at(i))));
368 }
369
370 // ------------------------ V8ConsoleMessageStorage ----------------------------
371
372 V8ConsoleMessageStorage::V8ConsoleMessageStorage(V8DebuggerImpl* debugger, int c ontextGroupId)
373 : m_debugger(debugger)
374 , m_contextGroupId(contextGroupId)
375 , m_expiredCount(0)
376 {
377 }
378
379
kozy 2016/06/23 22:28:43 style: extra blank line
dgozman 2016/06/28 01:43:48 Done.
380 V8ConsoleMessageStorage::~V8ConsoleMessageStorage()
381 {
382 clear();
383 }
384
385 void V8ConsoleMessageStorage::addMessage(std::unique_ptr<V8ConsoleMessage> messa ge)
386 {
387 if (message->type() == ClearMessageType)
388 clear();
389
390 V8InspectorSessionImpl* session = m_debugger->sessionForContextGroup(m_conte xtGroupId);
391 if (session)
392 session->consoleAgent()->messageAdded(message.get());
393
394 DCHECK(m_messages.size() <= maxConsoleMessageCount);
395 if (m_messages.size() == maxConsoleMessageCount) {
396 ++m_expiredCount;
397 m_messages.pop_front();
398 }
399 m_messages.push_back(std::move(message));
400 }
401
402 void V8ConsoleMessageStorage::clear()
403 {
404 m_messages.clear();
405 m_expiredCount = 0;
406 V8InspectorSessionImpl* session = m_debugger->sessionForContextGroup(m_conte xtGroupId);
407 if (session) {
408 session->consoleAgent()->reset();
409 session->releaseObjectGroup("console");
410 session->client()->consoleCleared();
411 }
412 }
413
414 void V8ConsoleMessageStorage::contextDestroyed(int contextId)
415 {
416 for (size_t i = 0; i < m_messages.size(); ++i)
417 m_messages[i]->contextDestroyed(contextId);
418 }
419
420 protocol::Vector<unsigned> V8ConsoleMessageStorage::consoleMessageArgumentCounts ()
421 {
422 protocol::Vector<unsigned> result(m_messages.size());
423 for (size_t i = 0; i < m_messages.size(); ++i)
424 result[i] = m_messages[i]->argumentCount();
425 return result;
426 }
427
428 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698