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

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: Addressed comment 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
« no previous file with comments | « src/prettyprinter.h ('k') | src/runtime.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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)");
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
102
103 void CallPrinter::VisitModuleDeclaration(ModuleDeclaration* node) {
104 Find(node->module());
105 }
106
107
108 void CallPrinter::VisitImportDeclaration(ImportDeclaration* node) {
109 Find(node->module());
110 }
111
112
113 void CallPrinter::VisitExportDeclaration(ExportDeclaration* node) {}
114
115
116 void CallPrinter::VisitModuleLiteral(ModuleLiteral* node) {
117 VisitBlock(node->body());
118 }
119
120
121 void CallPrinter::VisitModuleVariable(ModuleVariable* node) {
122 Find(node->proxy());
123 }
124
125
126 void CallPrinter::VisitModulePath(ModulePath* node) { Find(node->module()); }
127
128
129 void CallPrinter::VisitModuleUrl(ModuleUrl* node) {}
130
131
132 void CallPrinter::VisitModuleStatement(ModuleStatement* node) {
133 Find(node->body());
134 }
135
136
137 void CallPrinter::VisitExpressionStatement(ExpressionStatement* node) {
138 Find(node->expression());
139 }
140
141
142 void CallPrinter::VisitEmptyStatement(EmptyStatement* node) {}
143
144
145 void CallPrinter::VisitIfStatement(IfStatement* node) {
146 Find(node->condition());
147 Find(node->then_statement());
148 if (node->HasElseStatement()) {
149 Find(node->else_statement());
150 }
151 }
152
153
154 void CallPrinter::VisitContinueStatement(ContinueStatement* node) {}
155
156
157 void CallPrinter::VisitBreakStatement(BreakStatement* node) {}
158
159
160 void CallPrinter::VisitReturnStatement(ReturnStatement* node) {
161 Find(node->expression());
162 }
163
164
165 void CallPrinter::VisitWithStatement(WithStatement* node) {
166 Find(node->expression());
167 Find(node->statement());
168 }
169
170
171 void CallPrinter::VisitSwitchStatement(SwitchStatement* node) {
172 Find(node->tag());
173 ZoneList<CaseClause*>* cases = node->cases();
174 for (int i = 0; i < cases->length(); i++) Find(cases->at(i));
175 }
176
177
178 void CallPrinter::VisitCaseClause(CaseClause* clause) {
179 if (!clause->is_default()) {
180 Find(clause->label());
181 }
182 FindStatements(clause->statements());
183 }
184
185
186 void CallPrinter::VisitDoWhileStatement(DoWhileStatement* node) {
187 Find(node->body());
188 Find(node->cond());
189 }
190
191
192 void CallPrinter::VisitWhileStatement(WhileStatement* node) {
193 Find(node->cond());
194 Find(node->body());
195 }
196
197
198 void CallPrinter::VisitForStatement(ForStatement* node) {
199 if (node->init() != NULL) {
200 Find(node->init());
201 }
202 if (node->cond() != NULL) Find(node->cond());
203 if (node->next() != NULL) Find(node->next());
204 Find(node->body());
205 }
206
207
208 void CallPrinter::VisitForInStatement(ForInStatement* node) {
209 Find(node->each());
210 Find(node->enumerable());
211 Find(node->body());
212 }
213
214
215 void CallPrinter::VisitForOfStatement(ForOfStatement* node) {
216 Find(node->each());
217 Find(node->iterable());
218 Find(node->body());
219 }
220
221
222 void CallPrinter::VisitTryCatchStatement(TryCatchStatement* node) {
223 Find(node->try_block());
224 Find(node->catch_block());
225 }
226
227
228 void CallPrinter::VisitTryFinallyStatement(TryFinallyStatement* node) {
229 Find(node->try_block());
230 Find(node->finally_block());
231 }
232
233
234 void CallPrinter::VisitDebuggerStatement(DebuggerStatement* node) {}
235
236
237 void CallPrinter::VisitFunctionLiteral(FunctionLiteral* node) {
238 FindStatements(node->body());
239 }
240
241
242 void CallPrinter::VisitClassLiteral(ClassLiteral* node) {
243 if (node->extends()) Find(node->extends());
244 for (int i = 0; i < node->properties()->length(); i++) {
245 Find(node->properties()->at(i)->value());
246 }
247 }
248
249
250 void CallPrinter::VisitNativeFunctionLiteral(NativeFunctionLiteral* node) {}
251
252
253 void CallPrinter::VisitConditional(Conditional* node) {
254 Find(node->condition());
255 Find(node->then_expression());
256 Find(node->else_expression());
257 }
258
259
260 void CallPrinter::VisitLiteral(Literal* node) {
261 PrintLiteral(node->value(), true);
262 }
263
264
265 void CallPrinter::VisitRegExpLiteral(RegExpLiteral* node) {
266 Print("/");
267 PrintLiteral(node->pattern(), false);
268 Print("/");
269 PrintLiteral(node->flags(), false);
270 }
271
272
273 void CallPrinter::VisitObjectLiteral(ObjectLiteral* node) {
274 for (int i = 0; i < node->properties()->length(); i++) {
275 Find(node->properties()->at(i)->value());
276 }
277 }
278
279
280 void CallPrinter::VisitArrayLiteral(ArrayLiteral* node) {
281 Print("[");
282 for (int i = 0; i < node->values()->length(); i++) {
283 if (i != 0) Print(",");
284 Find(node->values()->at(i), true);
285 }
286 Print("]");
287 }
288
289
290 void CallPrinter::VisitVariableProxy(VariableProxy* node) {
291 PrintLiteral(node->name(), false);
292 }
293
294
295 void CallPrinter::VisitAssignment(Assignment* node) {
296 Find(node->target());
297 Find(node->value());
298 }
299
300
301 void CallPrinter::VisitYield(Yield* node) { Find(node->expression()); }
302
303
304 void CallPrinter::VisitThrow(Throw* node) { Find(node->exception()); }
305
306
307 void CallPrinter::VisitProperty(Property* node) {
308 Expression* key = node->key();
309 Literal* literal = key->AsLiteral();
310 if (literal != NULL && literal->value()->IsInternalizedString()) {
311 Find(node->obj(), true);
312 Print(".");
313 PrintLiteral(literal->value(), false);
314 } else {
315 Find(node->obj(), true);
316 Print("[");
317 Find(key, true);
318 Print("]");
319 }
320 }
321
322
323 void CallPrinter::VisitCall(Call* node) {
324 bool was_found = !found_ && node->position() == position_;
325 if (was_found) found_ = true;
326 Find(node->expression(), true);
327 if (!was_found) Print("(...)");
328 FindArguments(node->arguments());
329 if (was_found) done_ = true;
330 }
331
332
333 void CallPrinter::VisitCallNew(CallNew* node) {
334 bool was_found = !found_ && node->expression()->position() == position_;
335 if (was_found) found_ = true;
336 Find(node->expression(), was_found);
337 FindArguments(node->arguments());
338 if (was_found) done_ = true;
339 }
340
341
342 void CallPrinter::VisitCallRuntime(CallRuntime* node) {
343 FindArguments(node->arguments());
344 }
345
346
347 void CallPrinter::VisitUnaryOperation(UnaryOperation* node) {
348 Token::Value op = node->op();
349 bool needsSpace =
350 op == Token::DELETE || op == Token::TYPEOF || op == Token::VOID;
351 Print("(%s%s", Token::String(op), needsSpace ? " " : "");
352 Find(node->expression(), true);
353 Print(")");
354 }
355
356
357 void CallPrinter::VisitCountOperation(CountOperation* node) {
358 Print("(");
359 if (node->is_prefix()) Print("%s", Token::String(node->op()));
360 Find(node->expression(), true);
361 if (node->is_postfix()) Print("%s", Token::String(node->op()));
362 Print(")");
363 }
364
365
366 void CallPrinter::VisitBinaryOperation(BinaryOperation* node) {
367 Print("(");
368 Find(node->left(), true);
369 Print(" %s ", Token::String(node->op()));
370 Find(node->right(), true);
371 Print(")");
372 }
373
374
375 void CallPrinter::VisitCompareOperation(CompareOperation* node) {
376 Print("(");
377 Find(node->left(), true);
378 Print(" %s ", Token::String(node->op()));
379 Find(node->right(), true);
380 Print(")");
381 }
382
383
384 void CallPrinter::VisitThisFunction(ThisFunction* node) {}
385
386
387 void CallPrinter::VisitSuperReference(SuperReference* node) {}
388
389
390 void CallPrinter::FindStatements(ZoneList<Statement*>* statements) {
391 if (statements == NULL) return;
392 for (int i = 0; i < statements->length(); i++) {
393 Find(statements->at(i));
394 }
395 }
396
397
398 void CallPrinter::FindArguments(ZoneList<Expression*>* arguments) {
399 if (found_) return;
400 for (int i = 0; i < arguments->length(); i++) {
401 Find(arguments->at(i));
402 }
403 }
404
405
406 void CallPrinter::PrintLiteral(Handle<Object> value, bool quote) {
407 Object* object = *value;
408 if (object->IsString()) {
409 String* string = String::cast(object);
410 if (quote) Print("\"");
411 for (int i = 0; i < string->length(); i++) {
412 Print("%c", string->Get(i));
413 }
414 if (quote) Print("\"");
415 } else if (object->IsNull()) {
416 Print("null");
417 } else if (object->IsTrue()) {
418 Print("true");
419 } else if (object->IsFalse()) {
420 Print("false");
421 } else if (object->IsUndefined()) {
422 Print("undefined");
423 } else if (object->IsNumber()) {
424 Print("%g", object->Number());
425 }
426 }
427
428
429 void CallPrinter::PrintLiteral(const AstRawString* value, bool quote) {
430 PrintLiteral(value->string(), quote);
431 }
432
433
434 //-----------------------------------------------------------------------------
435
436
17 #ifdef DEBUG 437 #ifdef DEBUG
18 438
19 PrettyPrinter::PrettyPrinter(Zone* zone) { 439 PrettyPrinter::PrettyPrinter(Zone* zone) {
20 output_ = NULL; 440 output_ = NULL;
21 size_ = 0; 441 size_ = 0;
22 pos_ = 0; 442 pos_ = 0;
23 InitializeAstVisitor(zone); 443 InitializeAstVisitor(zone);
24 } 444 }
25 445
26 446
(...skipping 1151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1178 } 1598 }
1179 1599
1180 1600
1181 void AstPrinter::VisitSuperReference(SuperReference* node) { 1601 void AstPrinter::VisitSuperReference(SuperReference* node) {
1182 IndentedScope indent(this, "SUPER-REFERENCE"); 1602 IndentedScope indent(this, "SUPER-REFERENCE");
1183 } 1603 }
1184 1604
1185 #endif // DEBUG 1605 #endif // DEBUG
1186 1606
1187 } } // namespace v8::internal 1607 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/prettyprinter.h ('k') | src/runtime.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698