2 * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 #include "ConsoleClient.h"
29 #include "ScriptArguments.h"
30 #include "ScriptCallStack.h"
31 #include "ScriptCallStackFactory.h"
32 #include "ScriptValue.h"
33 #include <wtf/Assertions.h>
34 #include <wtf/text/CString.h>
35 #include <wtf/text/StringBuilder.h>
36 #include <wtf/text/WTFString.h>
38 using namespace Inspector
;
42 static void appendURLAndPosition(StringBuilder
& builder
, const String
& url
, unsigned lineNumber
, unsigned columnNumber
)
51 builder
.appendNumber(lineNumber
);
54 if (columnNumber
> 0) {
56 builder
.appendNumber(columnNumber
);
60 static void appendMessagePrefix(StringBuilder
& builder
, MessageSource source
, MessageType type
, MessageLevel level
)
62 const char* sourceString
;
64 case MessageSource::XML
:
67 case MessageSource::JS
:
70 case MessageSource::Network
:
71 sourceString
= "NETWORK";
73 case MessageSource::ConsoleAPI
:
74 sourceString
= "CONSOLE";
76 case MessageSource::Storage
:
77 sourceString
= "STORAGE";
79 case MessageSource::AppCache
:
80 sourceString
= "APPCACHE";
82 case MessageSource::Rendering
:
83 sourceString
= "RENDERING";
85 case MessageSource::CSS
:
88 case MessageSource::Security
:
89 sourceString
= "SECURITY";
91 case MessageSource::Other
:
92 sourceString
= "OTHER";
96 sourceString
= "UNKNOWN";
100 const char* levelString
;
102 case MessageLevel::Debug
:
103 levelString
= "DEBUG";
105 case MessageLevel::Log
:
108 case MessageLevel::Info
:
109 levelString
= "INFO";
111 case MessageLevel::Warning
:
112 levelString
= "WARN";
114 case MessageLevel::Error
:
115 levelString
= "ERROR";
118 ASSERT_NOT_REACHED();
119 levelString
= "UNKNOWN";
123 if (type
== MessageType::Trace
)
124 levelString
= "TRACE";
125 else if (type
== MessageType::Table
)
126 levelString
= "TABLE";
128 builder
.append(sourceString
);
130 builder
.append(levelString
);
133 void ConsoleClient::printConsoleMessage(MessageSource source
, MessageType type
, MessageLevel level
, const String
& message
, const String
& url
, unsigned lineNumber
, unsigned columnNumber
)
135 StringBuilder builder
;
137 if (!url
.isEmpty()) {
138 appendURLAndPosition(builder
, url
, lineNumber
, columnNumber
);
139 builder
.appendLiteral(": ");
142 appendMessagePrefix(builder
, source
, type
, level
);
144 builder
.append(message
);
146 WTFLogAlways("%s", builder
.toString().utf8().data());
149 void ConsoleClient::printConsoleMessageWithArguments(MessageSource source
, MessageType type
, MessageLevel level
, JSC::ExecState
* exec
, RefPtr
<ScriptArguments
>&& prpArguments
)
151 RefPtr
<ScriptArguments
> arguments
= prpArguments
;
153 bool isTraceMessage
= type
== MessageType::Trace
;
154 size_t stackSize
= isTraceMessage
? ScriptCallStack::maxCallStackSizeToCapture
: 1;
155 RefPtr
<ScriptCallStack
> callStack(createScriptCallStackForConsole(exec
, stackSize
));
156 const ScriptCallFrame
& lastCaller
= callStack
->at(0);
158 StringBuilder builder
;
160 if (!lastCaller
.sourceURL().isEmpty()) {
161 appendURLAndPosition(builder
, lastCaller
.sourceURL(), lastCaller
.lineNumber(), lastCaller
.columnNumber());
162 builder
.appendLiteral(": ");
165 appendMessagePrefix(builder
, source
, type
, level
);
166 for (size_t i
= 0; i
< arguments
->argumentCount(); ++i
) {
167 String argAsString
= arguments
->argumentAt(i
).toString(arguments
->globalState());
169 builder
.append(argAsString
.utf8().data());
172 WTFLogAlways("%s", builder
.toString().utf8().data());
174 if (isTraceMessage
) {
175 for (size_t i
= 0; i
< callStack
->size(); ++i
) {
176 const ScriptCallFrame
& callFrame
= callStack
->at(i
);
177 String functionName
= String(callFrame
.functionName());
178 if (functionName
.isEmpty())
179 functionName
= ASCIILiteral("(unknown)");
181 StringBuilder callFrameBuilder
;
182 callFrameBuilder
.appendNumber(static_cast<unsigned long>(i
));
183 callFrameBuilder
.appendLiteral(": ");
184 callFrameBuilder
.append(functionName
);
185 callFrameBuilder
.append('(');
186 appendURLAndPosition(callFrameBuilder
, callFrame
.sourceURL(), callFrame
.lineNumber(), callFrame
.columnNumber());
187 callFrameBuilder
.append(')');
189 WTFLogAlways("%s", callFrameBuilder
.toString().utf8().data());
194 void ConsoleClient::internalMessageWithTypeAndLevel(MessageType type
, MessageLevel level
, JSC::ExecState
* exec
, RefPtr
<ScriptArguments
>&& prpArguments
, ArgumentRequirement argumentRequirement
)
196 RefPtr
<ScriptArguments
> arguments
= prpArguments
;
197 if (argumentRequirement
== ArgumentRequired
&& !arguments
->argumentCount())
200 messageWithTypeAndLevel(type
, level
, exec
, arguments
.release());
203 void ConsoleClient::logWithLevel(ExecState
* exec
, RefPtr
<ScriptArguments
>&& arguments
, MessageLevel level
)
205 internalMessageWithTypeAndLevel(MessageType::Log
, level
, exec
, WTF::move(arguments
), ArgumentRequired
);
208 void ConsoleClient::clear(ExecState
* exec
, RefPtr
<ScriptArguments
>&& arguments
)
210 internalMessageWithTypeAndLevel(MessageType::Clear
, MessageLevel::Log
, exec
, WTF::move(arguments
), ArgumentNotRequired
);
213 void ConsoleClient::dir(ExecState
* exec
, RefPtr
<ScriptArguments
>&& arguments
)
215 internalMessageWithTypeAndLevel(MessageType::Dir
, MessageLevel::Log
, exec
, WTF::move(arguments
), ArgumentRequired
);
218 void ConsoleClient::dirXML(ExecState
* exec
, RefPtr
<ScriptArguments
>&& arguments
)
220 internalMessageWithTypeAndLevel(MessageType::DirXML
, MessageLevel::Log
, exec
, WTF::move(arguments
), ArgumentRequired
);
223 void ConsoleClient::table(ExecState
* exec
, RefPtr
<ScriptArguments
>&& arguments
)
225 internalMessageWithTypeAndLevel(MessageType::Table
, MessageLevel::Log
, exec
, WTF::move(arguments
), ArgumentRequired
);
228 void ConsoleClient::trace(ExecState
* exec
, RefPtr
<ScriptArguments
>&& arguments
)
230 internalMessageWithTypeAndLevel(MessageType::Trace
, MessageLevel::Log
, exec
, WTF::move(arguments
), ArgumentNotRequired
);
233 void ConsoleClient::assertCondition(ExecState
* exec
, RefPtr
<ScriptArguments
>&& arguments
, bool condition
)
238 internalMessageWithTypeAndLevel(MessageType::Assert
, MessageLevel::Error
, exec
, WTF::move(arguments
), ArgumentNotRequired
);
241 void ConsoleClient::group(ExecState
* exec
, RefPtr
<ScriptArguments
>&& arguments
)
243 internalMessageWithTypeAndLevel(MessageType::StartGroup
, MessageLevel::Log
, exec
, WTF::move(arguments
), ArgumentNotRequired
);
246 void ConsoleClient::groupCollapsed(ExecState
* exec
, RefPtr
<ScriptArguments
>&& arguments
)
248 internalMessageWithTypeAndLevel(MessageType::StartGroupCollapsed
, MessageLevel::Log
, exec
, WTF::move(arguments
), ArgumentNotRequired
);
251 void ConsoleClient::groupEnd(ExecState
* exec
, RefPtr
<ScriptArguments
>&& arguments
)
253 internalMessageWithTypeAndLevel(MessageType::EndGroup
, MessageLevel::Log
, exec
, WTF::move(arguments
), ArgumentNotRequired
);