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

Side by Side Diff: runtime/vm/exceptions.cc

Issue 1778133002: Enumerate URIs of all types in type errors in order to help the user diagnose (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 9 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 (c) 2011, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/exceptions.h" 5 #include "vm/exceptions.h"
6 6
7 #include "platform/address_sanitizer.h" 7 #include "platform/address_sanitizer.h"
8 8
9 #include "vm/dart_api_impl.h" 9 #include "vm/dart_api_impl.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
11 #include "vm/debugger.h" 11 #include "vm/debugger.h"
12 #include "vm/flags.h" 12 #include "vm/flags.h"
13 #include "vm/object.h" 13 #include "vm/object.h"
14 #include "vm/object_store.h" 14 #include "vm/object_store.h"
15 #include "vm/stack_frame.h" 15 #include "vm/stack_frame.h"
16 #include "vm/stub_code.h" 16 #include "vm/stub_code.h"
17 #include "vm/symbols.h" 17 #include "vm/symbols.h"
18 #include "vm/tags.h" 18 #include "vm/tags.h"
19 19
20 namespace dart { 20 namespace dart {
21 21
22 DEFINE_FLAG(bool, print_stacktrace_at_throw, false, 22 DEFINE_FLAG(bool, print_stacktrace_at_throw, false,
23 "Prints a stack trace everytime a throw occurs."); 23 "Prints a stack trace everytime a throw occurs.");
24 24
25 25
26 const char* Exceptions::kCastErrorDstName = "type cast";
27
28
29 class StacktraceBuilder : public ValueObject { 26 class StacktraceBuilder : public ValueObject {
30 public: 27 public:
31 StacktraceBuilder() { } 28 StacktraceBuilder() { }
32 virtual ~StacktraceBuilder() { } 29 virtual ~StacktraceBuilder() { }
33 30
34 virtual void AddFrame(const Code& code, const Smi& offset) = 0; 31 virtual void AddFrame(const Code& code, const Smi& offset) = 0;
35 }; 32 };
36 33
37 34
38 class RegularStacktraceBuilder : public StacktraceBuilder { 35 class RegularStacktraceBuilder : public StacktraceBuilder {
(...skipping 388 matching lines...) Expand 10 before | Expand all | Expand 10 after
427 Class& cls = Class::Handle(core_lib.LookupClass(cls_name)); 424 Class& cls = Class::Handle(core_lib.LookupClass(cls_name));
428 ASSERT(!cls.IsNull()); 425 ASSERT(!cls.IsNull());
429 // There are no parameterized error types, so no need to set type arguments. 426 // There are no parameterized error types, so no need to set type arguments.
430 return Instance::New(cls); 427 return Instance::New(cls);
431 } 428 }
432 429
433 430
434 // Allocate, initialize, and throw a TypeError or CastError. 431 // Allocate, initialize, and throw a TypeError or CastError.
435 // If error_msg is not null, throw a TypeError, even for a type cast. 432 // If error_msg is not null, throw a TypeError, even for a type cast.
436 void Exceptions::CreateAndThrowTypeError(TokenPosition location, 433 void Exceptions::CreateAndThrowTypeError(TokenPosition location,
437 const String& src_type_name, 434 const AbstractType& src_type,
438 const String& dst_type_name, 435 const AbstractType& dst_type,
439 const String& dst_name, 436 const String& dst_name,
440 const String& error_msg) { 437 const String& bound_error_msg) {
441 const Array& args = Array::Handle(Array::New(7)); 438 ASSERT(!dst_name.IsNull()); // Pass Symbols::Empty() instead.
439 Zone* zone = Thread::Current()->zone();
440 const Array& args = Array::Handle(zone, Array::New(4));
442 441
443 ExceptionType exception_type = 442 ExceptionType exception_type =
444 (error_msg.IsNull() && dst_name.Equals(kCastErrorDstName)) ? 443 (bound_error_msg.IsNull() &&
445 kCast : kType; 444 (dst_name.raw() == Symbols::InTypeCast().raw())) ? kCast : kType;
446 445
447 DartFrameIterator iterator; 446 DartFrameIterator iterator;
448 const Script& script = Script::Handle(GetCallerScript(&iterator)); 447 const Script& script = Script::Handle(zone, GetCallerScript(&iterator));
449 intptr_t line; 448 intptr_t line;
450 intptr_t column = -1; 449 intptr_t column = -1;
451 if (script.HasSource()) { 450 if (script.HasSource()) {
452 script.GetTokenLocation(location, &line, &column); 451 script.GetTokenLocation(location, &line, &column);
453 } else { 452 } else {
454 script.GetTokenLocation(location, &line, NULL); 453 script.GetTokenLocation(location, &line, NULL);
455 } 454 }
456 // Initialize '_url', '_line', and '_column' arguments. 455 // Initialize '_url', '_line', and '_column' arguments.
457 args.SetAt(0, String::Handle(script.url())); 456 args.SetAt(0, String::Handle(zone, script.url()));
458 args.SetAt(1, Smi::Handle(Smi::New(line))); 457 args.SetAt(1, Smi::Handle(zone, Smi::New(line)));
459 args.SetAt(2, Smi::Handle(Smi::New(column))); 458 args.SetAt(2, Smi::Handle(zone, Smi::New(column)));
460 459
461 // Initialize '_srcType', '_dstType', '_dstName', and '_errorMsg'. 460 // Construct '_errorMsg'.
462 args.SetAt(3, src_type_name); 461 GrowableHandlePtrArray<const String> pieces(zone, 20);
463 args.SetAt(4, dst_type_name); 462
464 args.SetAt(5, dst_name); 463 // Print bound error first, if any.
465 args.SetAt(6, error_msg); 464 if (!bound_error_msg.IsNull() && (bound_error_msg.Length() > 0)) {
465 pieces.Add(bound_error_msg);
466 pieces.Add(Symbols::NewLine());
467 }
468
469 // If dst_type is malformed or malbounded, only print the embedded error.
470 if (!dst_type.IsNull()) {
471 const LanguageError& error = LanguageError::Handle(zone, dst_type.error());
472 if (!error.IsNull()) {
473 // Print the embedded error only.
474 pieces.Add(String::Handle(zone, Symbols::New(error.ToErrorCString())));
475 pieces.Add(Symbols::NewLine());
476 } else {
477 // Describe the type error.
478 if (!src_type.IsNull()) {
479 pieces.Add(Symbols::TypeQuote());
480 pieces.Add(String::Handle(zone, src_type.UserVisibleName()));
481 pieces.Add(Symbols::QuoteIsNotASubtypeOf());
482 }
483 pieces.Add(Symbols::TypeQuote());
484 pieces.Add(String::Handle(zone, dst_type.UserVisibleName()));
485 pieces.Add(Symbols::SingleQuote());
486 if (exception_type == kCast) {
487 pieces.Add(dst_name);
488 } else if (dst_name.Length() > 0) {
489 pieces.Add(Symbols::SpaceOfSpace());
490 pieces.Add(Symbols::SingleQuote());
491 pieces.Add(dst_name);
492 pieces.Add(Symbols::SingleQuote());
493 }
494 // Print URIs of src and dst types.
495 pieces.Add(Symbols::SpaceWhereNewLine());
496 if (!src_type.IsNull()) {
497 pieces.Add(String::Handle(zone, src_type.EnumerateURIs()));
498 }
499 if (!dst_type.IsDynamicType() && !dst_type.IsVoidType()) {
500 pieces.Add(String::Handle(zone, dst_type.EnumerateURIs()));
501 }
502 }
503 }
504 const String& error_msg =
505 String::Handle(zone, Symbols::FromConcatAll(pieces));
506 args.SetAt(3, error_msg);
466 507
467 // Type errors in the core library may be difficult to diagnose. 508 // Type errors in the core library may be difficult to diagnose.
468 // Print type error information before throwing the error when debugging. 509 // Print type error information before throwing the error when debugging.
469 if (FLAG_print_stacktrace_at_throw) { 510 if (FLAG_print_stacktrace_at_throw) {
470 if (!error_msg.IsNull()) {
471 OS::Print("%s\n", error_msg.ToCString());
472 }
473 OS::Print("'%s': Failed type check: line %" Pd " pos %" Pd ": ", 511 OS::Print("'%s': Failed type check: line %" Pd " pos %" Pd ": ",
474 String::Handle(script.url()).ToCString(), line, column); 512 String::Handle(zone, script.url()).ToCString(), line, column);
475 if (!dst_name.IsNull() && (dst_name.Length() > 0)) { 513 OS::Print("%s\n", error_msg.ToCString());
srdjan 2016/03/09 22:38:23 Replace OS::Print with THR_Print
regis 2016/03/09 23:15:40 Done.
476 OS::Print("type '%s' is not a subtype of type '%s' of '%s'.\n",
477 src_type_name.ToCString(),
478 dst_type_name.ToCString(),
479 dst_name.ToCString());
480 } else {
481 OS::Print("type error.\n");
482 }
483 } 514 }
484 515
485 // Throw TypeError or CastError instance. 516 // Throw TypeError or CastError instance.
486 Exceptions::ThrowByType(exception_type, args); 517 Exceptions::ThrowByType(exception_type, args);
487 UNREACHABLE(); 518 UNREACHABLE();
488 } 519 }
489 520
490 521
491 void Exceptions::Throw(Thread* thread, const Instance& exception) { 522 void Exceptions::Throw(Thread* thread, const Instance& exception) {
492 // Do not notify debugger on stack overflow and out of memory exceptions. 523 // Do not notify debugger on stack overflow and out of memory exceptions.
(...skipping 174 matching lines...) Expand 10 before | Expand all | Expand 10 after
667 } 698 }
668 699
669 return DartLibraryCalls::InstanceCreate(library, 700 return DartLibraryCalls::InstanceCreate(library,
670 *class_name, 701 *class_name,
671 *constructor_name, 702 *constructor_name,
672 arguments); 703 arguments);
673 } 704 }
674 705
675 706
676 } // namespace dart 707 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698