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

Side by Side Diff: src/prettyprinter.cc

Issue 861623002: Add a pretty printer to improve the error message non-function calls (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Update test expectations Created 5 years, 11 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
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <stdarg.h> 5 #include <stdarg.h>
6 6
7 #include "src/v8.h" 7 #include "src/v8.h"
8 8
9 #include "src/ast-value-factory.h" 9 #include "src/ast-value-factory.h"
10 #include "src/base/platform/platform.h" 10 #include "src/base/platform/platform.h"
11 #include "src/prettyprinter.h" 11 #include "src/prettyprinter.h"
12 #include "src/scopes.h" 12 #include "src/scopes.h"
13 13
14 namespace v8 { 14 namespace v8 {
15 namespace internal { 15 namespace internal {
16 16
17 CallPrinter::CallPrinter(Zone* zone) {
18 output_ = NULL;
19 size_ = 0;
20 pos_ = 0;
21 position_ = 0;
22 found_ = false;
23 done_ = false;
24 InitializeAstVisitor(zone);
25 }
26
27
28 CallPrinter::~CallPrinter() { DeleteArray(output_); }
29
30
31 const char* CallPrinter::Print(FunctionLiteral* program, int position) {
32 Init();
33 position_ = position;
34 Find(program);
35 return output_;
36 }
37
38
39 void CallPrinter::Find(AstNode* node, bool print) {
40 if (done_) return;
41 if (found_) {
42 if (print) {
43 int start = pos_;
44 Visit(node);
45 if (start != pos_) return;
46 }
47 Print("(intermediate value)");
Yang 2015/01/20 08:19:07 I'd use square brackets like we do when we print s
48 } else {
49 Visit(node);
50 }
51 }
52
53
54 void CallPrinter::Init() {
55 if (size_ == 0) {
56 DCHECK(output_ == NULL);
57 const int initial_size = 256;
58 output_ = NewArray<char>(initial_size);
59 size_ = initial_size;
60 }
61 output_[0] = '\0';
62 pos_ = 0;
63 }
64
65
66 void CallPrinter::Print(const char* format, ...) {
67 if (!found_ || done_) return;
68 for (;;) {
69 va_list arguments;
70 va_start(arguments, format);
71 int n = VSNPrintF(Vector<char>(output_, size_) + pos_, format, arguments);
72 va_end(arguments);
73
74 if (n >= 0) {
75 // there was enough space - we are done
76 pos_ += n;
77 return;
78 } else {
79 // there was not enough space - allocate more and try again
80 const int slack = 32;
81 int new_size = size_ + (size_ >> 1) + slack;
82 char* new_output = NewArray<char>(new_size);
83 MemCopy(new_output, output_, pos_);
84 DeleteArray(output_);
85 output_ = new_output;
86 size_ = new_size;
87 }
88 }
89 }
90
91
92 void CallPrinter::VisitBlock(Block* node) {
93 FindStatements(node->statements());
94 }
95
96
97 void CallPrinter::VisitVariableDeclaration(VariableDeclaration* node) {}
98
99
100 void CallPrinter::VisitFunctionDeclaration(FunctionDeclaration* node) {
101 Find(node->fun());
102 }
103
104
105 void CallPrinter::VisitModuleDeclaration(ModuleDeclaration* node) {
106 Find(node->module());
107 }
108
109
110 void CallPrinter::VisitImportDeclaration(ImportDeclaration* node) {
111 Find(node->module());
112 }
113
114
115 void CallPrinter::VisitExportDeclaration(ExportDeclaration* node) {}
116
117
118 void CallPrinter::VisitModuleLiteral(ModuleLiteral* node) {
119 VisitBlock(node->body());
120 }
121
122
123 void CallPrinter::VisitModuleVariable(ModuleVariable* node) {
124 Find(node->proxy());
125 }
126
127
128 void CallPrinter::VisitModulePath(ModulePath* node) { Find(node->module()); }
129
130
131 void CallPrinter::VisitModuleUrl(ModuleUrl* node) {}
132
133
134 void CallPrinter::VisitModuleStatement(ModuleStatement* node) {
135 Find(node->body());
136 }
137
138
139 void CallPrinter::VisitExpressionStatement(ExpressionStatement* node) {
140 Find(node->expression());
141 }
142
143
144 void CallPrinter::VisitEmptyStatement(EmptyStatement* node) {}
145
146
147 void CallPrinter::VisitIfStatement(IfStatement* node) {
148 Find(node->condition());
149 Find(node->then_statement());
150 if (node->HasElseStatement()) {
151 Find(node->else_statement());
152 }
153 }
154
155
156 void CallPrinter::VisitContinueStatement(ContinueStatement* node) {}
157
158
159 void CallPrinter::VisitBreakStatement(BreakStatement* node) {}
160
161
162 void CallPrinter::VisitReturnStatement(ReturnStatement* node) {
163 Find(node->expression());
164 }
165
166
167 void CallPrinter::VisitWithStatement(WithStatement* node) {
168 Find(node->expression());
169 Find(node->statement());
170 }
171
172
173 void CallPrinter::VisitSwitchStatement(SwitchStatement* node) {
174 Find(node->tag());
175 ZoneList<CaseClause*>* cases = node->cases();
176 for (int i = 0; i < cases->length(); i++) Find(cases->at(i));
177 }
178
179
180 void CallPrinter::VisitCaseClause(CaseClause* clause) {
181 if (!clause->is_default()) {
182 Find(clause->label());
183 }
184 FindStatements(clause->statements());
185 }
186
187
188 void CallPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
189 Find(node->body());
190 Find(node->cond());
191 }
192
193
194 void CallPrinter::VisitWhileStatement(WhileStatement* node) {
195 Find(node->cond());
196 Find(node->body());
197 }
198
199
200 void CallPrinter::VisitForStatement(ForStatement* node) {
201 if (node->init() != NULL) {
Yang 2015/01/20 08:19:06 omitting curly brackets would look nicer :)
202 Find(node->init());
203 }
204 if (node->cond() != NULL) Find(node->cond());
205 if (node->next() != NULL) Find(node->next());
206 Find(node->body());
207 }
208
209
210 void CallPrinter::VisitForInStatement(ForInStatement* node) {
211 Find(node->each());
212 Find(node->enumerable());
213 Find(node->body());
214 }
215
216
217 void CallPrinter::VisitForOfStatement(ForOfStatement* node) {
218 Find(node->each());
219 Find(node->iterable());
220 Find(node->body());
221 }
222
223
224 void CallPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
225 Find(node->try_block());
226 Find(node->catch_block());
227 }
228
229
230 void CallPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
231 Find(node->try_block());
232 Find(node->finally_block());
233 }
234
235
236 void CallPrinter::VisitDebuggerStatement(DebuggerStatement* node) {}
237
238
239 void CallPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
240 FindStatements(node->body());
241 }
242
243
244 void CallPrinter::VisitClassLiteral(ClassLiteral* node) {
245 if (node->extends()) Find(node->extends());
246 for (int i = 0; i < node->properties()->length(); i++) {
247 Find(node->properties()->at(i)->value());
248 }
249 }
250
251
252 void CallPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {}
253
254
255 void CallPrinter::VisitConditional(Conditional* node) {
256 Find(node->condition());
257 Find(node->then_expression());
258 Find(node->else_expression());
259 }
260
261
262 void CallPrinter::VisitLiteral(Literal* node) {
263 PrintLiteral(node->value(), true);
264 }
265
266
267 void CallPrinter::VisitRegExpLiteral(RegExpLiteral* node) {}
268
269
270 void CallPrinter::VisitObjectLiteral(ObjectLiteral* node) {
271 for (int i = 0; i < node->properties()->length(); i++) {
272 Find(node->properties()->at(i)->value());
273 }
274 }
275
276
277 void CallPrinter::VisitArrayLiteral(ArrayLiteral* node) {
278 for (int i = 0; i < node->values()->length(); i++) {
279 Find(node->values()->at(i));
280 }
281 }
282
283
284 void CallPrinter::VisitVariableProxy(VariableProxy* node) {
285 PrintLiteral(node->name(), false);
286 }
287
288
289 void CallPrinter::VisitAssignment(Assignment* node) {
290 Find(node->target());
291 Find(node->value());
292 }
293
294
295 void CallPrinter::VisitYield(Yield* node) { Find(node->expression()); }
296
297
298 void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); }
299
300
301 void CallPrinter::VisitProperty(Property* node) {
302 Expression* key = node->key();
303 Literal* literal = key->AsLiteral();
304 if (literal != NULL && literal->value()->IsInternalizedString()) {
305 Find(node->obj(), true);
306 Print(".");
307 PrintLiteral(literal->value(), false);
308 } else {
309 Find(node->obj(), true);
310 Print("[");
311 Find(key, true);
312 Print("]");
313 }
314 }
315
316
317 void CallPrinter::VisitCall(Call* node) {
318 bool was_found = !found_ && node->position() == position_;
319 if (was_found) found_ = true;
320 Find(node->expression(), true);
321 if (!was_found) Print("(...)");
322 FindArguments(node->arguments());
323 if (was_found) done_ = true;
324 }
325
326
327 void CallPrinter::VisitCallNew(CallNew* node) {
328 bool was_found = !found_ && node->expression()->position() == position_;
329 if (was_found) found_ = true;
330 Find(node->expression(), was_found);
331 FindArguments(node->arguments());
332 if (was_found) done_ = true;
333 }
334
335
336 void CallPrinter::VisitCallRuntime(CallRuntime* node) {
337 FindArguments(node->arguments());
338 }
339
340
341 void CallPrinter::VisitUnaryOperation(UnaryOperation* node) {
342 Token::Value op = node->op();
343 bool needsSpace =
344 op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
345 Print("(%s%s", Token::String(op), needsSpace ? " " : "");
346 Find(node->expression(), true);
347 Print(")");
348 }
349
350
351 void CallPrinter::VisitCountOperation(CountOperation* node) {
352 Print("(");
353 if (node->is_prefix()) Print("%s", Token::String(node->op()));
354 Find(node->expression(), true);
355 if (node->is_postfix()) Print("%s", Token::String(node->op()));
356 Print(")");
357 }
358
359
360 void CallPrinter::VisitBinaryOperation(BinaryOperation* node) {
361 Print("(");
362 Find(node->left(), true);
363 Print(" %s ", Token::String(node->op()));
364 Find(node->right(), true);
365 Print(")");
366 }
367
368
369 void CallPrinter::VisitCompareOperation(CompareOperation* node) {
370 Print("(");
371 Find(node->left(), true);
372 Print(" %s ", Token::String(node->op()));
373 Find(node->right(), true);
374 Print(")");
375 }
376
377
378 void CallPrinter::VisitThisFunction(ThisFunction* node) {}
379
380
381 void CallPrinter::VisitSuperReference(SuperReference* node) {}
382
383
384 void CallPrinter::FindStatements(ZoneList<Statement*>* statements) {
385 if (statements == NULL) return;
386 for (int i = 0; i < statements->length(); i++) {
387 Find(statements->at(i));
388 }
389 }
390
391
392 void CallPrinter::FindArguments(ZoneList<Expression*>* arguments) {
393 if (found_) return;
394 for (int i = 0; i < arguments->length(); i++) {
395 Find(arguments->at(i));
396 }
397 }
398
399
400 void CallPrinter::PrintLiteral(Handle<Object> value, bool quote) {
401 Object* object = *value;
402 if (object->IsString()) {
403 String* string = String::cast(object);
404 if (quote) Print("\"");
405 for (int i = 0; i < string->length(); i++) {
406 Print("%c", string->Get(i));
407 }
408 if (quote) Print("\"");
409 } else if (object->IsNull()) {
410 Print("null");
411 } else if (object->IsTrue()) {
412 Print("true");
413 } else if (object->IsFalse()) {
414 Print("false");
415 } else if (object->IsUndefined()) {
416 Print("undefined");
417 } else if (object->IsNumber()) {
418 Print("%g", object->Number());
419 }
420 }
421
422
423 void CallPrinter::PrintLiteral(const AstRawString* value, bool quote) {
424 PrintLiteral(value->string(), quote);
425 }
426
427
428 //-----------------------------------------------------------------------------
429
430
17 #ifdef DEBUG 431 #ifdef DEBUG
18 432
19 PrettyPrinter::PrettyPrinter(Zone* zone) { 433 PrettyPrinter::PrettyPrinter(Zone* zone) {
20 output_ = NULL; 434 output_ = NULL;
21 size_ = 0; 435 size_ = 0;
22 pos_ = 0; 436 pos_ = 0;
23 InitializeAstVisitor(zone); 437 InitializeAstVisitor(zone);
24 } 438 }
25 439
26 440
(...skipping 1151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1178 } 1592 }
1179 1593
1180 1594
1181 void AstPrinter::VisitSuperReference(SuperReference* node) { 1595 void AstPrinter::VisitSuperReference(SuperReference* node) {
1182 IndentedScope indent(this, "SUPER-REFERENCE"); 1596 IndentedScope indent(this, "SUPER-REFERENCE");
1183 } 1597 }
1184 1598
1185 #endif // DEBUG 1599 #endif // DEBUG
1186 1600
1187 } } // namespace v8::internal 1601 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/prettyprinter.h ('k') | src/runtime.js » ('j') | src/runtime/runtime-debug.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698