]>
Commit | Line | Data |
---|---|---|
81345200 A |
1 | /* |
2 | * Copyright (C) 2013, 2014 Apple Inc. All rights reserved. | |
3 | * | |
4 | * Redistribution and use in source and binary forms, with or without | |
5 | * modification, are permitted provided that the following conditions | |
6 | * are met: | |
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. | |
12 | * | |
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. | |
24 | */ | |
25 | ||
26 | #include "config.h" | |
27 | #include "ConsoleClient.h" | |
28 | ||
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> | |
37 | ||
38 | using namespace Inspector; | |
39 | ||
40 | namespace JSC { | |
41 | ||
42 | static void appendURLAndPosition(StringBuilder& builder, const String& url, unsigned lineNumber, unsigned columnNumber) | |
43 | { | |
44 | if (url.isEmpty()) | |
45 | return; | |
46 | ||
47 | builder.append(url); | |
48 | ||
49 | if (lineNumber > 0) { | |
50 | builder.append(':'); | |
51 | builder.appendNumber(lineNumber); | |
52 | } | |
53 | ||
54 | if (columnNumber > 0) { | |
55 | builder.append(':'); | |
56 | builder.appendNumber(columnNumber); | |
57 | } | |
58 | } | |
59 | ||
60 | static void appendMessagePrefix(StringBuilder& builder, MessageSource source, MessageType type, MessageLevel level) | |
61 | { | |
62 | const char* sourceString; | |
63 | switch (source) { | |
64 | case MessageSource::XML: | |
65 | sourceString = "XML"; | |
66 | break; | |
67 | case MessageSource::JS: | |
68 | sourceString = "JS"; | |
69 | break; | |
70 | case MessageSource::Network: | |
71 | sourceString = "NETWORK"; | |
72 | break; | |
73 | case MessageSource::ConsoleAPI: | |
74 | sourceString = "CONSOLE"; | |
75 | break; | |
76 | case MessageSource::Storage: | |
77 | sourceString = "STORAGE"; | |
78 | break; | |
79 | case MessageSource::AppCache: | |
80 | sourceString = "APPCACHE"; | |
81 | break; | |
82 | case MessageSource::Rendering: | |
83 | sourceString = "RENDERING"; | |
84 | break; | |
85 | case MessageSource::CSS: | |
86 | sourceString = "CSS"; | |
87 | break; | |
88 | case MessageSource::Security: | |
89 | sourceString = "SECURITY"; | |
90 | break; | |
91 | case MessageSource::Other: | |
92 | sourceString = "OTHER"; | |
93 | break; | |
94 | default: | |
95 | ASSERT_NOT_REACHED(); | |
96 | sourceString = "UNKNOWN"; | |
97 | break; | |
98 | } | |
99 | ||
100 | const char* levelString; | |
101 | switch (level) { | |
102 | case MessageLevel::Debug: | |
103 | levelString = "DEBUG"; | |
104 | break; | |
105 | case MessageLevel::Log: | |
106 | levelString = "LOG"; | |
107 | break; | |
ed1e77d3 A |
108 | case MessageLevel::Info: |
109 | levelString = "INFO"; | |
110 | break; | |
81345200 A |
111 | case MessageLevel::Warning: |
112 | levelString = "WARN"; | |
113 | break; | |
114 | case MessageLevel::Error: | |
115 | levelString = "ERROR"; | |
116 | break; | |
117 | default: | |
118 | ASSERT_NOT_REACHED(); | |
119 | levelString = "UNKNOWN"; | |
120 | break; | |
121 | } | |
122 | ||
123 | if (type == MessageType::Trace) | |
124 | levelString = "TRACE"; | |
ed1e77d3 A |
125 | else if (type == MessageType::Table) |
126 | levelString = "TABLE"; | |
81345200 A |
127 | |
128 | builder.append(sourceString); | |
129 | builder.append(' '); | |
130 | builder.append(levelString); | |
131 | } | |
132 | ||
133 | void ConsoleClient::printConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, const String& url, unsigned lineNumber, unsigned columnNumber) | |
134 | { | |
135 | StringBuilder builder; | |
136 | ||
137 | if (!url.isEmpty()) { | |
138 | appendURLAndPosition(builder, url, lineNumber, columnNumber); | |
139 | builder.appendLiteral(": "); | |
140 | } | |
141 | ||
142 | appendMessagePrefix(builder, source, type, level); | |
143 | builder.append(' '); | |
144 | builder.append(message); | |
145 | ||
146 | WTFLogAlways("%s", builder.toString().utf8().data()); | |
147 | } | |
148 | ||
ed1e77d3 | 149 | void ConsoleClient::printConsoleMessageWithArguments(MessageSource source, MessageType type, MessageLevel level, JSC::ExecState* exec, RefPtr<ScriptArguments>&& prpArguments) |
81345200 A |
150 | { |
151 | RefPtr<ScriptArguments> arguments = prpArguments; | |
152 | ||
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); | |
157 | ||
158 | StringBuilder builder; | |
159 | ||
160 | if (!lastCaller.sourceURL().isEmpty()) { | |
161 | appendURLAndPosition(builder, lastCaller.sourceURL(), lastCaller.lineNumber(), lastCaller.columnNumber()); | |
162 | builder.appendLiteral(": "); | |
163 | } | |
164 | ||
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()); | |
168 | builder.append(' '); | |
169 | builder.append(argAsString.utf8().data()); | |
170 | } | |
171 | ||
172 | WTFLogAlways("%s", builder.toString().utf8().data()); | |
173 | ||
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)"); | |
180 | ||
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(')'); | |
188 | ||
189 | WTFLogAlways("%s", callFrameBuilder.toString().utf8().data()); | |
190 | } | |
191 | } | |
192 | } | |
193 | ||
ed1e77d3 | 194 | void ConsoleClient::internalMessageWithTypeAndLevel(MessageType type, MessageLevel level, JSC::ExecState* exec, RefPtr<ScriptArguments>&& prpArguments, ArgumentRequirement argumentRequirement) |
81345200 A |
195 | { |
196 | RefPtr<ScriptArguments> arguments = prpArguments; | |
197 | if (argumentRequirement == ArgumentRequired && !arguments->argumentCount()) | |
198 | return; | |
199 | ||
200 | messageWithTypeAndLevel(type, level, exec, arguments.release()); | |
201 | } | |
202 | ||
ed1e77d3 | 203 | void ConsoleClient::logWithLevel(ExecState* exec, RefPtr<ScriptArguments>&& arguments, MessageLevel level) |
81345200 | 204 | { |
ed1e77d3 | 205 | internalMessageWithTypeAndLevel(MessageType::Log, level, exec, WTF::move(arguments), ArgumentRequired); |
81345200 A |
206 | } |
207 | ||
ed1e77d3 | 208 | void ConsoleClient::clear(ExecState* exec, RefPtr<ScriptArguments>&& arguments) |
81345200 | 209 | { |
ed1e77d3 | 210 | internalMessageWithTypeAndLevel(MessageType::Clear, MessageLevel::Log, exec, WTF::move(arguments), ArgumentNotRequired); |
81345200 A |
211 | } |
212 | ||
ed1e77d3 | 213 | void ConsoleClient::dir(ExecState* exec, RefPtr<ScriptArguments>&& arguments) |
81345200 | 214 | { |
ed1e77d3 | 215 | internalMessageWithTypeAndLevel(MessageType::Dir, MessageLevel::Log, exec, WTF::move(arguments), ArgumentRequired); |
81345200 A |
216 | } |
217 | ||
ed1e77d3 | 218 | void ConsoleClient::dirXML(ExecState* exec, RefPtr<ScriptArguments>&& arguments) |
81345200 | 219 | { |
ed1e77d3 | 220 | internalMessageWithTypeAndLevel(MessageType::DirXML, MessageLevel::Log, exec, WTF::move(arguments), ArgumentRequired); |
81345200 A |
221 | } |
222 | ||
ed1e77d3 | 223 | void ConsoleClient::table(ExecState* exec, RefPtr<ScriptArguments>&& arguments) |
81345200 | 224 | { |
ed1e77d3 | 225 | internalMessageWithTypeAndLevel(MessageType::Table, MessageLevel::Log, exec, WTF::move(arguments), ArgumentRequired); |
81345200 A |
226 | } |
227 | ||
ed1e77d3 | 228 | void ConsoleClient::trace(ExecState* exec, RefPtr<ScriptArguments>&& arguments) |
81345200 | 229 | { |
ed1e77d3 | 230 | internalMessageWithTypeAndLevel(MessageType::Trace, MessageLevel::Log, exec, WTF::move(arguments), ArgumentNotRequired); |
81345200 A |
231 | } |
232 | ||
ed1e77d3 | 233 | void ConsoleClient::assertCondition(ExecState* exec, RefPtr<ScriptArguments>&& arguments, bool condition) |
81345200 A |
234 | { |
235 | if (condition) | |
236 | return; | |
237 | ||
ed1e77d3 | 238 | internalMessageWithTypeAndLevel(MessageType::Assert, MessageLevel::Error, exec, WTF::move(arguments), ArgumentNotRequired); |
81345200 A |
239 | } |
240 | ||
ed1e77d3 | 241 | void ConsoleClient::group(ExecState* exec, RefPtr<ScriptArguments>&& arguments) |
81345200 | 242 | { |
ed1e77d3 | 243 | internalMessageWithTypeAndLevel(MessageType::StartGroup, MessageLevel::Log, exec, WTF::move(arguments), ArgumentNotRequired); |
81345200 A |
244 | } |
245 | ||
ed1e77d3 | 246 | void ConsoleClient::groupCollapsed(ExecState* exec, RefPtr<ScriptArguments>&& arguments) |
81345200 | 247 | { |
ed1e77d3 | 248 | internalMessageWithTypeAndLevel(MessageType::StartGroupCollapsed, MessageLevel::Log, exec, WTF::move(arguments), ArgumentNotRequired); |
81345200 A |
249 | } |
250 | ||
ed1e77d3 | 251 | void ConsoleClient::groupEnd(ExecState* exec, RefPtr<ScriptArguments>&& arguments) |
81345200 | 252 | { |
ed1e77d3 | 253 | internalMessageWithTypeAndLevel(MessageType::EndGroup, MessageLevel::Log, exec, WTF::move(arguments), ArgumentNotRequired); |
81345200 A |
254 | } |
255 | ||
256 | } // namespace JSC |