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::Warning
:
109 levelString
= "WARN";
111 case MessageLevel::Error
:
112 levelString
= "ERROR";
115 ASSERT_NOT_REACHED();
116 levelString
= "UNKNOWN";
120 if (type
== MessageType::Trace
)
121 levelString
= "TRACE";
123 builder
.append(sourceString
);
125 builder
.append(levelString
);
128 void ConsoleClient::printConsoleMessage(MessageSource source
, MessageType type
, MessageLevel level
, const String
& message
, const String
& url
, unsigned lineNumber
, unsigned columnNumber
)
130 StringBuilder builder
;
132 if (!url
.isEmpty()) {
133 appendURLAndPosition(builder
, url
, lineNumber
, columnNumber
);
134 builder
.appendLiteral(": ");
137 appendMessagePrefix(builder
, source
, type
, level
);
139 builder
.append(message
);
141 WTFLogAlways("%s", builder
.toString().utf8().data());
144 void ConsoleClient::printConsoleMessageWithArguments(MessageSource source
, MessageType type
, MessageLevel level
, JSC::ExecState
* exec
, PassRefPtr
<ScriptArguments
> prpArguments
)
146 RefPtr
<ScriptArguments
> arguments
= prpArguments
;
148 bool isTraceMessage
= type
== MessageType::Trace
;
149 size_t stackSize
= isTraceMessage
? ScriptCallStack::maxCallStackSizeToCapture
: 1;
150 RefPtr
<ScriptCallStack
> callStack(createScriptCallStackForConsole(exec
, stackSize
));
151 const ScriptCallFrame
& lastCaller
= callStack
->at(0);
153 StringBuilder builder
;
155 if (!lastCaller
.sourceURL().isEmpty()) {
156 appendURLAndPosition(builder
, lastCaller
.sourceURL(), lastCaller
.lineNumber(), lastCaller
.columnNumber());
157 builder
.appendLiteral(": ");
160 appendMessagePrefix(builder
, source
, type
, level
);
161 for (size_t i
= 0; i
< arguments
->argumentCount(); ++i
) {
162 String argAsString
= arguments
->argumentAt(i
).toString(arguments
->globalState());
164 builder
.append(argAsString
.utf8().data());
167 WTFLogAlways("%s", builder
.toString().utf8().data());
169 if (isTraceMessage
) {
170 for (size_t i
= 0; i
< callStack
->size(); ++i
) {
171 const ScriptCallFrame
& callFrame
= callStack
->at(i
);
172 String functionName
= String(callFrame
.functionName());
173 if (functionName
.isEmpty())
174 functionName
= ASCIILiteral("(unknown)");
176 StringBuilder callFrameBuilder
;
177 callFrameBuilder
.appendNumber(static_cast<unsigned long>(i
));
178 callFrameBuilder
.appendLiteral(": ");
179 callFrameBuilder
.append(functionName
);
180 callFrameBuilder
.append('(');
181 appendURLAndPosition(callFrameBuilder
, callFrame
.sourceURL(), callFrame
.lineNumber(), callFrame
.columnNumber());
182 callFrameBuilder
.append(')');
184 WTFLogAlways("%s", callFrameBuilder
.toString().utf8().data());
189 void ConsoleClient::internalMessageWithTypeAndLevel(MessageType type
, MessageLevel level
, JSC::ExecState
* exec
, PassRefPtr
<ScriptArguments
> prpArguments
, ArgumentRequirement argumentRequirement
)
191 RefPtr
<ScriptArguments
> arguments
= prpArguments
;
192 if (argumentRequirement
== ArgumentRequired
&& !arguments
->argumentCount())
195 messageWithTypeAndLevel(type
, level
, exec
, arguments
.release());
198 void ConsoleClient::logWithLevel(ExecState
* exec
, PassRefPtr
<ScriptArguments
> arguments
, MessageLevel level
)
200 internalMessageWithTypeAndLevel(MessageType::Log
, level
, exec
, arguments
, ArgumentRequired
);
203 void ConsoleClient::clear(ExecState
* exec
, PassRefPtr
<ScriptArguments
> arguments
)
205 internalMessageWithTypeAndLevel(MessageType::Clear
, MessageLevel::Log
, exec
, arguments
, ArgumentNotRequired
);
208 void ConsoleClient::dir(ExecState
* exec
, PassRefPtr
<ScriptArguments
> arguments
)
210 internalMessageWithTypeAndLevel(MessageType::Dir
, MessageLevel::Log
, exec
, arguments
, ArgumentRequired
);
213 void ConsoleClient::dirXML(ExecState
* exec
, PassRefPtr
<ScriptArguments
> arguments
)
215 internalMessageWithTypeAndLevel(MessageType::DirXML
, MessageLevel::Log
, exec
, arguments
, ArgumentRequired
);
218 void ConsoleClient::table(ExecState
* exec
, PassRefPtr
<ScriptArguments
> arguments
)
220 internalMessageWithTypeAndLevel(MessageType::Table
, MessageLevel::Log
, exec
, arguments
, ArgumentRequired
);
223 void ConsoleClient::trace(ExecState
* exec
, PassRefPtr
<ScriptArguments
> arguments
)
225 internalMessageWithTypeAndLevel(MessageType::Trace
, MessageLevel::Log
, exec
, arguments
, ArgumentNotRequired
);
228 void ConsoleClient::assertCondition(ExecState
* exec
, PassRefPtr
<ScriptArguments
> arguments
, bool condition
)
233 internalMessageWithTypeAndLevel(MessageType::Assert
, MessageLevel::Error
, exec
, arguments
, ArgumentNotRequired
);
236 void ConsoleClient::group(ExecState
* exec
, PassRefPtr
<ScriptArguments
> arguments
)
238 internalMessageWithTypeAndLevel(MessageType::StartGroup
, MessageLevel::Log
, exec
, arguments
, ArgumentNotRequired
);
241 void ConsoleClient::groupCollapsed(ExecState
* exec
, PassRefPtr
<ScriptArguments
> arguments
)
243 internalMessageWithTypeAndLevel(MessageType::StartGroupCollapsed
, MessageLevel::Log
, exec
, arguments
, ArgumentNotRequired
);
246 void ConsoleClient::groupEnd(ExecState
* exec
, PassRefPtr
<ScriptArguments
> arguments
)
248 internalMessageWithTypeAndLevel(MessageType::EndGroup
, MessageLevel::Log
, exec
, arguments
, ArgumentNotRequired
);