Chromium Code Reviews| Index: runtime/vm/exceptions.cc |
| diff --git a/runtime/vm/exceptions.cc b/runtime/vm/exceptions.cc |
| index 84ca37720496f8442425588e4c5d245e21ce67ea..359ae5a5f39c76ccec2c9699779df02166d1973a 100644 |
| --- a/runtime/vm/exceptions.cc |
| +++ b/runtime/vm/exceptions.cc |
| @@ -23,9 +23,6 @@ DEFINE_FLAG(bool, print_stacktrace_at_throw, false, |
| "Prints a stack trace everytime a throw occurs."); |
| -const char* Exceptions::kCastErrorDstName = "type cast"; |
| - |
| - |
| class StacktraceBuilder : public ValueObject { |
| public: |
| StacktraceBuilder() { } |
| @@ -434,18 +431,20 @@ RawInstance* Exceptions::NewInstance(const char* class_name) { |
| // Allocate, initialize, and throw a TypeError or CastError. |
| // If error_msg is not null, throw a TypeError, even for a type cast. |
| void Exceptions::CreateAndThrowTypeError(TokenPosition location, |
| - const String& src_type_name, |
| - const String& dst_type_name, |
| + const AbstractType& src_type, |
| + const AbstractType& dst_type, |
| const String& dst_name, |
| - const String& error_msg) { |
| - const Array& args = Array::Handle(Array::New(7)); |
| + const String& bound_error_msg) { |
| + ASSERT(!dst_name.IsNull()); // Pass Symbols::Empty() instead. |
| + Zone* zone = Thread::Current()->zone(); |
| + const Array& args = Array::Handle(zone, Array::New(4)); |
| ExceptionType exception_type = |
| - (error_msg.IsNull() && dst_name.Equals(kCastErrorDstName)) ? |
| - kCast : kType; |
| + (bound_error_msg.IsNull() && |
| + (dst_name.raw() == Symbols::InTypeCast().raw())) ? kCast : kType; |
| DartFrameIterator iterator; |
| - const Script& script = Script::Handle(GetCallerScript(&iterator)); |
| + const Script& script = Script::Handle(zone, GetCallerScript(&iterator)); |
| intptr_t line; |
| intptr_t column = -1; |
| if (script.HasSource()) { |
| @@ -454,32 +453,64 @@ void Exceptions::CreateAndThrowTypeError(TokenPosition location, |
| script.GetTokenLocation(location, &line, NULL); |
| } |
| // Initialize '_url', '_line', and '_column' arguments. |
| - args.SetAt(0, String::Handle(script.url())); |
| - args.SetAt(1, Smi::Handle(Smi::New(line))); |
| - args.SetAt(2, Smi::Handle(Smi::New(column))); |
| + args.SetAt(0, String::Handle(zone, script.url())); |
| + args.SetAt(1, Smi::Handle(zone, Smi::New(line))); |
| + args.SetAt(2, Smi::Handle(zone, Smi::New(column))); |
| + |
| + // Construct '_errorMsg'. |
| + GrowableHandlePtrArray<const String> pieces(zone, 20); |
| - // Initialize '_srcType', '_dstType', '_dstName', and '_errorMsg'. |
| - args.SetAt(3, src_type_name); |
| - args.SetAt(4, dst_type_name); |
| - args.SetAt(5, dst_name); |
| - args.SetAt(6, error_msg); |
| + // Print bound error first, if any. |
| + if (!bound_error_msg.IsNull() && (bound_error_msg.Length() > 0)) { |
| + pieces.Add(bound_error_msg); |
| + pieces.Add(Symbols::NewLine()); |
| + } |
| + |
| + // If dst_type is malformed or malbounded, only print the embedded error. |
| + if (!dst_type.IsNull()) { |
| + const LanguageError& error = LanguageError::Handle(zone, dst_type.error()); |
| + if (!error.IsNull()) { |
| + // Print the embedded error only. |
| + pieces.Add(String::Handle(zone, Symbols::New(error.ToErrorCString()))); |
| + pieces.Add(Symbols::NewLine()); |
| + } else { |
| + // Describe the type error. |
| + if (!src_type.IsNull()) { |
| + pieces.Add(Symbols::TypeQuote()); |
| + pieces.Add(String::Handle(zone, src_type.UserVisibleName())); |
| + pieces.Add(Symbols::QuoteIsNotASubtypeOf()); |
| + } |
| + pieces.Add(Symbols::TypeQuote()); |
| + pieces.Add(String::Handle(zone, dst_type.UserVisibleName())); |
| + pieces.Add(Symbols::SingleQuote()); |
| + if (exception_type == kCast) { |
| + pieces.Add(dst_name); |
| + } else if (dst_name.Length() > 0) { |
| + pieces.Add(Symbols::SpaceOfSpace()); |
| + pieces.Add(Symbols::SingleQuote()); |
| + pieces.Add(dst_name); |
| + pieces.Add(Symbols::SingleQuote()); |
| + } |
| + // Print URIs of src and dst types. |
| + pieces.Add(Symbols::SpaceWhereNewLine()); |
| + if (!src_type.IsNull()) { |
| + pieces.Add(String::Handle(zone, src_type.EnumerateURIs())); |
| + } |
| + if (!dst_type.IsDynamicType() && !dst_type.IsVoidType()) { |
| + pieces.Add(String::Handle(zone, dst_type.EnumerateURIs())); |
| + } |
| + } |
| + } |
| + const String& error_msg = |
| + String::Handle(zone, Symbols::FromConcatAll(pieces)); |
| + args.SetAt(3, error_msg); |
| // Type errors in the core library may be difficult to diagnose. |
| // Print type error information before throwing the error when debugging. |
| if (FLAG_print_stacktrace_at_throw) { |
| - if (!error_msg.IsNull()) { |
| - OS::Print("%s\n", error_msg.ToCString()); |
| - } |
| OS::Print("'%s': Failed type check: line %" Pd " pos %" Pd ": ", |
| - String::Handle(script.url()).ToCString(), line, column); |
| - if (!dst_name.IsNull() && (dst_name.Length() > 0)) { |
| - OS::Print("type '%s' is not a subtype of type '%s' of '%s'.\n", |
| - src_type_name.ToCString(), |
| - dst_type_name.ToCString(), |
| - dst_name.ToCString()); |
| - } else { |
| - OS::Print("type error.\n"); |
| - } |
| + String::Handle(zone, script.url()).ToCString(), line, column); |
| + 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.
|
| } |
| // Throw TypeError or CastError instance. |