]>
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; | |
108 | case MessageLevel::Warning: | |
109 | levelString = "WARN"; | |
110 | break; | |
111 | case MessageLevel::Error: | |
112 | levelString = "ERROR"; | |
113 | break; | |
114 | default: | |
115 | ASSERT_NOT_REACHED(); | |
116 | levelString = "UNKNOWN"; | |
117 | break; | |
118 | } | |
119 | ||
120 | if (type == MessageType::Trace) | |
121 | levelString = "TRACE"; | |
122 | ||
123 | builder.append(sourceString); | |
124 | builder.append(' '); | |
125 | builder.append(levelString); | |
126 | } | |
127 | ||
128 | void ConsoleClient::printConsoleMessage(MessageSource source, MessageType type, MessageLevel level, const String& message, const String& url, unsigned lineNumber, unsigned columnNumber) | |
129 | { | |
130 | StringBuilder builder; | |
131 | ||
132 | if (!url.isEmpty()) { | |
133 | appendURLAndPosition(builder, url, lineNumber, columnNumber); | |
134 | builder.appendLiteral(": "); | |
135 | } | |
136 | ||
137 | appendMessagePrefix(builder, source, type, level); | |
138 | builder.append(' '); | |
139 | builder.append(message); | |
140 | ||
141 | WTFLogAlways("%s", builder.toString().utf8().data()); | |
142 | } | |
143 | ||
144 | void ConsoleClient::printConsoleMessageWithArguments(MessageSource source, MessageType type, MessageLevel level, JSC::ExecState* exec, PassRefPtr<ScriptArguments> prpArguments) | |
145 | { | |
146 | RefPtr<ScriptArguments> arguments = prpArguments; | |
147 | ||
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); | |
152 | ||
153 | StringBuilder builder; | |
154 | ||
155 | if (!lastCaller.sourceURL().isEmpty()) { | |
156 | appendURLAndPosition(builder, lastCaller.sourceURL(), lastCaller.lineNumber(), lastCaller.columnNumber()); | |
157 | builder.appendLiteral(": "); | |
158 | } | |
159 | ||
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()); | |
163 | builder.append(' '); | |
164 | builder.append(argAsString.utf8().data()); | |
165 | } | |
166 | ||
167 | WTFLogAlways("%s", builder.toString().utf8().data()); | |
168 | ||
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)"); | |
175 | ||
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(')'); | |
183 | ||
184 | WTFLogAlways("%s", callFrameBuilder.toString().utf8().data()); | |
185 | } | |
186 | } | |
187 | } | |
188 | ||
189 | void ConsoleClient::internalMessageWithTypeAndLevel(MessageType type, MessageLevel level, JSC::ExecState* exec, PassRefPtr<ScriptArguments> prpArguments, ArgumentRequirement argumentRequirement) | |
190 | { | |
191 | RefPtr<ScriptArguments> arguments = prpArguments; | |
192 | if (argumentRequirement == ArgumentRequired && !arguments->argumentCount()) | |
193 | return; | |
194 | ||
195 | messageWithTypeAndLevel(type, level, exec, arguments.release()); | |
196 | } | |
197 | ||
198 | void ConsoleClient::logWithLevel(ExecState* exec, PassRefPtr<ScriptArguments> arguments, MessageLevel level) | |
199 | { | |
200 | internalMessageWithTypeAndLevel(MessageType::Log, level, exec, arguments, ArgumentRequired); | |
201 | } | |
202 | ||
203 | void ConsoleClient::clear(ExecState* exec, PassRefPtr<ScriptArguments> arguments) | |
204 | { | |
205 | internalMessageWithTypeAndLevel(MessageType::Clear, MessageLevel::Log, exec, arguments, ArgumentNotRequired); | |
206 | } | |
207 | ||
208 | void ConsoleClient::dir(ExecState* exec, PassRefPtr<ScriptArguments> arguments) | |
209 | { | |
210 | internalMessageWithTypeAndLevel(MessageType::Dir, MessageLevel::Log, exec, arguments, ArgumentRequired); | |
211 | } | |
212 | ||
213 | void ConsoleClient::dirXML(ExecState* exec, PassRefPtr<ScriptArguments> arguments) | |
214 | { | |
215 | internalMessageWithTypeAndLevel(MessageType::DirXML, MessageLevel::Log, exec, arguments, ArgumentRequired); | |
216 | } | |
217 | ||
218 | void ConsoleClient::table(ExecState* exec, PassRefPtr<ScriptArguments> arguments) | |
219 | { | |
220 | internalMessageWithTypeAndLevel(MessageType::Table, MessageLevel::Log, exec, arguments, ArgumentRequired); | |
221 | } | |
222 | ||
223 | void ConsoleClient::trace(ExecState* exec, PassRefPtr<ScriptArguments> arguments) | |
224 | { | |
225 | internalMessageWithTypeAndLevel(MessageType::Trace, MessageLevel::Log, exec, arguments, ArgumentNotRequired); | |
226 | } | |
227 | ||
228 | void ConsoleClient::assertCondition(ExecState* exec, PassRefPtr<ScriptArguments> arguments, bool condition) | |
229 | { | |
230 | if (condition) | |
231 | return; | |
232 | ||
233 | internalMessageWithTypeAndLevel(MessageType::Assert, MessageLevel::Error, exec, arguments, ArgumentNotRequired); | |
234 | } | |
235 | ||
236 | void ConsoleClient::group(ExecState* exec, PassRefPtr<ScriptArguments> arguments) | |
237 | { | |
238 | internalMessageWithTypeAndLevel(MessageType::StartGroup, MessageLevel::Log, exec, arguments, ArgumentNotRequired); | |
239 | } | |
240 | ||
241 | void ConsoleClient::groupCollapsed(ExecState* exec, PassRefPtr<ScriptArguments> arguments) | |
242 | { | |
243 | internalMessageWithTypeAndLevel(MessageType::StartGroupCollapsed, MessageLevel::Log, exec, arguments, ArgumentNotRequired); | |
244 | } | |
245 | ||
246 | void ConsoleClient::groupEnd(ExecState* exec, PassRefPtr<ScriptArguments> arguments) | |
247 | { | |
248 | internalMessageWithTypeAndLevel(MessageType::EndGroup, MessageLevel::Log, exec, arguments, ArgumentNotRequired); | |
249 | } | |
250 | ||
251 | } // namespace JSC |