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

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

Issue 68113028: Lazily format LanguageError messages (fix issue 15069). (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 7 years, 1 month 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 | Annotate | Revision Log
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.h » ('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 (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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/object.h" 5 #include "vm/object.h"
6 6
7 #include "include/dart_api.h" 7 #include "include/dart_api.h"
8 #include "platform/assert.h" 8 #include "platform/assert.h"
9 #include "vm/assembler.h" 9 #include "vm/assembler.h"
10 #include "vm/cpu.h" 10 #include "vm/cpu.h"
(...skipping 1664 matching lines...) Expand 10 before | Expand all | Expand 10 after
1675 result.set_num_type_arguments(0); 1675 result.set_num_type_arguments(0);
1676 result.set_num_own_type_arguments(0); 1676 result.set_num_own_type_arguments(0);
1677 result.set_num_native_fields(0); 1677 result.set_num_native_fields(0);
1678 result.set_token_pos(Scanner::kDummyTokenIndex); 1678 result.set_token_pos(Scanner::kDummyTokenIndex);
1679 result.InitEmptyFields(); 1679 result.InitEmptyFields();
1680 Isolate::Current()->RegisterClass(result); 1680 Isolate::Current()->RegisterClass(result);
1681 return result.raw(); 1681 return result.raw();
1682 } 1682 }
1683 1683
1684 1684
1685 static RawError* FormatError(const Error& prev_error,
1686 const Script& script,
1687 intptr_t token_pos,
1688 const char* format, ...) {
1689 va_list args;
1690 va_start(args, format);
1691 if (prev_error.IsNull()) {
1692 return Parser::FormatError(script, token_pos, "Error", format, args);
1693 } else {
1694 return Parser::FormatErrorWithAppend(prev_error, script, token_pos,
1695 "Error", format, args);
1696 }
1697 }
1698
1699 1685
1700 static void ReportTooManyTypeArguments(const Class& cls) { 1686 static void ReportTooManyTypeArguments(const Class& cls) {
1701 const Error& error = Error::Handle( 1687 const Error& error = Error::Handle(
1702 FormatError(Error::Handle(), // No previous error. 1688 LanguageError::NewFormatted(
1703 Script::Handle(cls.script()), cls.token_pos(), 1689 Error::Handle(), // No previous error.
1704 "too many type parameters declared in class '%s' or in its " 1690 Script::Handle(cls.script()),
1705 "super classes", 1691 cls.token_pos(),
1706 String::Handle(cls.Name()).ToCString())); 1692 LanguageError::kError,
1693 Heap::kNew,
1694 "too many type parameters declared in class '%s' or in its "
1695 "super classes",
1696 String::Handle(cls.Name()).ToCString()));
1707 Isolate::Current()->long_jump_base()->Jump(1, error); 1697 Isolate::Current()->long_jump_base()->Jump(1, error);
1708 UNREACHABLE(); 1698 UNREACHABLE();
1709 } 1699 }
1710 1700
1711 1701
1712 void Class::set_num_type_arguments(intptr_t value) const { 1702 void Class::set_num_type_arguments(intptr_t value) const {
1713 if (!Utils::IsInt(16, value)) { 1703 if (!Utils::IsInt(16, value)) {
1714 ReportTooManyTypeArguments(*this); 1704 ReportTooManyTypeArguments(*this);
1715 } 1705 }
1716 raw_ptr()->num_type_arguments_ = value; 1706 raw_ptr()->num_type_arguments_ = value;
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
2233 // the loop below. 2223 // the loop below.
2234 // However, an implicitly created constructor should not be preserved if 2224 // However, an implicitly created constructor should not be preserved if
2235 // the patch provides a constructor or a factory. Wait for now. 2225 // the patch provides a constructor or a factory. Wait for now.
2236 if (orig_func.raw() != orig_implicit_ctor.raw()) { 2226 if (orig_func.raw() != orig_implicit_ctor.raw()) {
2237 new_functions.Add(orig_func); 2227 new_functions.Add(orig_func);
2238 } 2228 }
2239 } else if (func.UserVisibleSignature() != 2229 } else if (func.UserVisibleSignature() !=
2240 orig_func.UserVisibleSignature()) { 2230 orig_func.UserVisibleSignature()) {
2241 // Compare user visible signatures to ignore different implicit parameters 2231 // Compare user visible signatures to ignore different implicit parameters
2242 // when patching a constructor with a factory. 2232 // when patching a constructor with a factory.
2243 *error = FormatError(*error, // No previous error. 2233 *error = LanguageError::NewFormatted(
2244 Script::Handle(patch.script()), func.token_pos(), 2234 *error, // No previous error.
2245 "signature mismatch: '%s'", member_name.ToCString()); 2235 Script::Handle(patch.script()),
2236 func.token_pos(),
2237 LanguageError::kError,
2238 Heap::kNew,
2239 "signature mismatch: '%s'", member_name.ToCString());
2246 return false; 2240 return false;
2247 } 2241 }
2248 } 2242 }
2249 for (intptr_t i = 0; i < patch_len; i++) { 2243 for (intptr_t i = 0; i < patch_len; i++) {
2250 func ^= patch_list.At(i); 2244 func ^= patch_list.At(i);
2251 if (func.IsConstructor() || func.IsFactory()) { 2245 if (func.IsConstructor() || func.IsFactory()) {
2252 // Do not preserve the original implicit constructor, if any. 2246 // Do not preserve the original implicit constructor, if any.
2253 orig_implicit_ctor = Function::null(); 2247 orig_implicit_ctor = Function::null();
2254 } 2248 }
2255 func.set_owner(patch_class); 2249 func.set_owner(patch_class);
(...skipping 18 matching lines...) Expand all
2274 new_list = Array::New(patch_len + orig_len); 2268 new_list = Array::New(patch_len + orig_len);
2275 for (intptr_t i = 0; i < patch_len; i++) { 2269 for (intptr_t i = 0; i < patch_len; i++) {
2276 field ^= patch_list.At(i); 2270 field ^= patch_list.At(i);
2277 field.set_owner(*this); 2271 field.set_owner(*this);
2278 member_name = field.name(); 2272 member_name = field.name();
2279 // TODO(iposva): Verify non-public fields only. 2273 // TODO(iposva): Verify non-public fields only.
2280 2274
2281 // Verify no duplicate additions. 2275 // Verify no duplicate additions.
2282 orig_field ^= LookupField(member_name); 2276 orig_field ^= LookupField(member_name);
2283 if (!orig_field.IsNull()) { 2277 if (!orig_field.IsNull()) {
2284 *error = FormatError(*error, // No previous error. 2278 *error = LanguageError::NewFormatted(
2285 Script::Handle(patch.script()), field.token_pos(), 2279 *error, // No previous error.
2286 "duplicate field: %s", member_name.ToCString()); 2280 Script::Handle(patch.script()),
2281 field.token_pos(),
2282 LanguageError::kError,
2283 Heap::kNew,
2284 "duplicate field: %s", member_name.ToCString());
2287 return false; 2285 return false;
2288 } 2286 }
2289 new_list.SetAt(i, field); 2287 new_list.SetAt(i, field);
2290 } 2288 }
2291 for (intptr_t i = 0; i < orig_len; i++) { 2289 for (intptr_t i = 0; i < orig_len; i++) {
2292 field ^= orig_list.At(i); 2290 field ^= orig_list.At(i);
2293 new_list.SetAt(patch_len + i, field); 2291 new_list.SetAt(patch_len + i, field);
2294 } 2292 }
2295 SetFields(new_list); 2293 SetFields(new_list);
2296 2294
(...skipping 2548 matching lines...) Expand 10 before | Expand all | Expand 10 after
4845 bool Function::HasCompatibleParametersWith(const Function& other, 4843 bool Function::HasCompatibleParametersWith(const Function& other,
4846 Error* bound_error) const { 4844 Error* bound_error) const {
4847 ASSERT(FLAG_error_on_bad_override); 4845 ASSERT(FLAG_error_on_bad_override);
4848 ASSERT((bound_error != NULL) && bound_error->IsNull()); 4846 ASSERT((bound_error != NULL) && bound_error->IsNull());
4849 // Check that this function's signature type is a subtype of the other 4847 // Check that this function's signature type is a subtype of the other
4850 // function's signature type. 4848 // function's signature type.
4851 if (!TypeTest(kIsSubtypeOf, Object::null_abstract_type_arguments(), 4849 if (!TypeTest(kIsSubtypeOf, Object::null_abstract_type_arguments(),
4852 other, Object::null_abstract_type_arguments(), bound_error)) { 4850 other, Object::null_abstract_type_arguments(), bound_error)) {
4853 // For more informative error reporting, use the location of the other 4851 // For more informative error reporting, use the location of the other
4854 // function here, since the caller will use the location of this function. 4852 // function here, since the caller will use the location of this function.
4855 *bound_error = FormatError( 4853 *bound_error = LanguageError::NewFormatted(
4856 *bound_error, // A bound error if non null. 4854 *bound_error, // A bound error if non null.
4857 Script::Handle(other.script()), 4855 Script::Handle(other.script()),
4858 other.token_pos(), 4856 other.token_pos(),
4857 LanguageError::kError,
4858 Heap::kNew,
4859 "signature type '%s' of function '%s' is not a subtype of signature " 4859 "signature type '%s' of function '%s' is not a subtype of signature "
4860 "type '%s' of function '%s'", 4860 "type '%s' of function '%s'",
4861 String::Handle(UserVisibleSignature()).ToCString(), 4861 String::Handle(UserVisibleSignature()).ToCString(),
4862 String::Handle(UserVisibleName()).ToCString(), 4862 String::Handle(UserVisibleName()).ToCString(),
4863 String::Handle(other.UserVisibleSignature()).ToCString(), 4863 String::Handle(other.UserVisibleSignature()).ToCString(),
4864 String::Handle(other.UserVisibleName()).ToCString()); 4864 String::Handle(other.UserVisibleName()).ToCString());
4865 return false; 4865 return false;
4866 } 4866 }
4867 // We should also check that if the other function explicitly specifies a 4867 // We should also check that if the other function explicitly specifies a
4868 // default value for a formal parameter, this function does not specify a 4868 // default value for a formal parameter, this function does not specify a
(...skipping 5803 matching lines...) Expand 10 before | Expand all | Expand 10 after
10672 10672
10673 RawLanguageError* LanguageError::New() { 10673 RawLanguageError* LanguageError::New() {
10674 ASSERT(Object::language_error_class() != Class::null()); 10674 ASSERT(Object::language_error_class() != Class::null());
10675 RawObject* raw = Object::Allocate(LanguageError::kClassId, 10675 RawObject* raw = Object::Allocate(LanguageError::kClassId,
10676 LanguageError::InstanceSize(), 10676 LanguageError::InstanceSize(),
10677 Heap::kOld); 10677 Heap::kOld);
10678 return reinterpret_cast<RawLanguageError*>(raw); 10678 return reinterpret_cast<RawLanguageError*>(raw);
10679 } 10679 }
10680 10680
10681 10681
10682 RawLanguageError* LanguageError::New(const String& message, Heap::Space space) { 10682 RawLanguageError* LanguageError::NewFormattedV(const Error& prev_error,
10683 const Script& script,
10684 intptr_t token_pos,
10685 Kind kind,
10686 Heap::Space space,
10687 const char* format,
10688 va_list args) {
10683 ASSERT(Object::language_error_class() != Class::null()); 10689 ASSERT(Object::language_error_class() != Class::null());
10684 LanguageError& result = LanguageError::Handle(); 10690 LanguageError& result = LanguageError::Handle();
10685 { 10691 {
10686 RawObject* raw = Object::Allocate(LanguageError::kClassId, 10692 RawObject* raw = Object::Allocate(LanguageError::kClassId,
10687 LanguageError::InstanceSize(), 10693 LanguageError::InstanceSize(),
10688 space); 10694 space);
10689 NoGCScope no_gc; 10695 NoGCScope no_gc;
10690 result ^= raw; 10696 result ^= raw;
10691 } 10697 }
10692 result.set_message(message); 10698 result.set_previous_error(prev_error);
10699 result.set_script(script);
10700 result.set_token_pos(token_pos);
10701 result.set_kind(kind);
10702 result.set_message(String::Handle(String::NewFormattedV(format, args)));
10693 return result.raw(); 10703 return result.raw();
10694 } 10704 }
10695 10705
10696 10706
10697 void LanguageError::set_message(const String& message) const { 10707 RawLanguageError* LanguageError::NewFormatted(const Error& prev_error,
10698 StorePointer(&raw_ptr()->message_, message.raw()); 10708 const Script& script,
10709 intptr_t token_pos,
10710 Kind kind,
10711 Heap::Space space,
10712 const char* format, ...) {
10713 va_list args;
10714 va_start(args, format);
10715 RawLanguageError* result = LanguageError::NewFormattedV(
10716 prev_error, script, token_pos, kind, space, format, args);
10717 NoGCScope no_gc;
10718 va_end(args);
10719 return result;
10720 }
10721
10722
10723 RawLanguageError* LanguageError::New(const String& formatted_message,
10724 Heap::Space space) {
10725 ASSERT(Object::language_error_class() != Class::null());
10726 LanguageError& result = LanguageError::Handle();
10727 {
10728 RawObject* raw = Object::Allocate(LanguageError::kClassId,
10729 LanguageError::InstanceSize(),
10730 space);
10731 NoGCScope no_gc;
10732 result ^= raw;
10733 }
10734 result.set_formatted_message(formatted_message);
10735 return result.raw();
10736 }
10737
10738
10739 void LanguageError::set_previous_error(const Error& value) const {
10740 StorePointer(&raw_ptr()->previous_error_, value.raw());
10741 }
10742
10743
10744 void LanguageError::set_script(const Script& value) const {
10745 StorePointer(&raw_ptr()->script_, value.raw());
10746 }
10747
10748
10749 void LanguageError::set_token_pos(intptr_t value) const {
10750 ASSERT(value >= 0);
10751 raw_ptr()->token_pos_ = value;
10752 }
10753
10754
10755 void LanguageError::set_kind(uint8_t value) const {
10756 raw_ptr()->kind_ = value;
10757 }
10758
10759
10760 void LanguageError::set_message(const String& value) const {
10761 StorePointer(&raw_ptr()->message_, value.raw());
10762 }
10763
10764
10765 void LanguageError::set_formatted_message(const String& value) const {
10766 StorePointer(&raw_ptr()->formatted_message_, value.raw());
10767 }
10768
10769
10770 RawString* LanguageError::FormatMessage() const {
10771 if (formatted_message() != String::null()) {
10772 return formatted_message();
10773 }
10774 const char* message_header;
10775 switch (kind()) {
10776 case kWarning: message_header = "warning"; break;
10777 case kError: message_header = "error"; break;
10778 case kMalformedType: message_header = "malformed type"; break;
10779 case kMalboundedType: message_header = "malbounded type"; break;
10780 default: message_header = ""; UNREACHABLE();
10781 }
10782 String& result = String::Handle();
10783 String& msg = String::Handle(message());
10784 const Script& scr = Script::Handle(script());
10785 if (!scr.IsNull()) {
10786 const String& script_url = String::Handle(scr.url());
10787 if (token_pos() >= 0) {
10788 intptr_t line, column;
10789 scr.GetTokenLocation(token_pos(), &line, &column);
10790 // Only report the line position if we have the original source. We still
10791 // need to get a valid column so that we can report the ^ mark below the
10792 // snippet.
10793 if (scr.HasSource()) {
10794 result = String::NewFormatted("'%s': %s: line %" Pd " pos %" Pd ": ",
10795 script_url.ToCString(),
10796 message_header,
10797 line,
10798 column);
10799 } else {
10800 result = String::NewFormatted("'%s': %s: line %" Pd ": ",
10801 script_url.ToCString(),
10802 message_header,
10803 line);
10804 }
10805 // Append the formatted error or warning message.
10806 result = String::Concat(result, msg);
10807 // Append the source line.
10808 const String& script_line = String::Handle(scr.GetLine(line));
10809 ASSERT(!script_line.IsNull());
10810 result = String::Concat(result, Symbols::NewLine());
10811 result = String::Concat(result, script_line);
10812 result = String::Concat(result, Symbols::NewLine());
10813 // Append the column marker.
10814 const String& column_line = String::Handle(
10815 String::NewFormatted("%*s\n", static_cast<int>(column), "^"));
10816 result = String::Concat(result, column_line);
10817 } else {
10818 // Token position is unknown.
10819 result = String::NewFormatted("'%s': %s: ",
10820 script_url.ToCString(),
10821 message_header);
10822 result = String::Concat(result, msg);
10823 }
10824 } else {
10825 // Script is unknown.
10826 // Append the formatted error or warning message.
10827 result = String::NewFormatted("%s: ", message_header);
10828 result = String::Concat(result, msg);
10829 }
10830 // Prepend previous error message.
10831 const Error& prev_error = Error::Handle(previous_error());
10832 if (!prev_error.IsNull()) {
10833 msg = String::New(prev_error.ToErrorCString());
10834 result = String::Concat(msg, result);
10835 }
10836 set_formatted_message(result);
10837 return result.raw();
10699 } 10838 }
10700 10839
10701 10840
10702 const char* LanguageError::ToErrorCString() const { 10841 const char* LanguageError::ToErrorCString() const {
10703 const String& msg_str = String::Handle(message()); 10842 const String& msg_str = String::Handle(FormatMessage());
10704 return msg_str.ToCString(); 10843 return msg_str.ToCString();
10705 } 10844 }
10706 10845
10707 10846
10708 const char* LanguageError::ToCString() const { 10847 const char* LanguageError::ToCString() const {
10709 return "LanguageError"; 10848 return "LanguageError";
10710 } 10849 }
10711 10850
10712 10851
10713 void LanguageError::PrintToJSONStream(JSONStream* stream, bool ref) const { 10852 void LanguageError::PrintToJSONStream(JSONStream* stream, bool ref) const {
(...skipping 1413 matching lines...) Expand 10 before | Expand all | Expand 10 after
12127 upper_bound.UserVisibleName()); 12266 upper_bound.UserVisibleName());
12128 const AbstractType& declared_bound = AbstractType::Handle(bound()); 12267 const AbstractType& declared_bound = AbstractType::Handle(bound());
12129 const String& declared_bound_name = String::Handle( 12268 const String& declared_bound_name = String::Handle(
12130 declared_bound.UserVisibleName()); 12269 declared_bound.UserVisibleName());
12131 const String& type_param_name = String::Handle(UserVisibleName()); 12270 const String& type_param_name = String::Handle(UserVisibleName());
12132 const Class& cls = Class::Handle(parameterized_class()); 12271 const Class& cls = Class::Handle(parameterized_class());
12133 const String& class_name = String::Handle(cls.Name()); 12272 const String& class_name = String::Handle(cls.Name());
12134 const Script& script = Script::Handle(cls.script()); 12273 const Script& script = Script::Handle(cls.script());
12135 // Since the bound may have been canonicalized, its token index is 12274 // Since the bound may have been canonicalized, its token index is
12136 // meaningless, therefore use the token index of this type parameter. 12275 // meaningless, therefore use the token index of this type parameter.
12137 *bound_error = FormatError( 12276 *bound_error = LanguageError::NewFormatted(
12138 *bound_error, 12277 *bound_error,
12139 script, 12278 script,
12140 token_pos(), 12279 token_pos(),
12280 LanguageError::kMalboundedType,
12281 Heap::kNew,
12141 "type parameter '%s' of class '%s' must extend bound '%s', " 12282 "type parameter '%s' of class '%s' must extend bound '%s', "
12142 "but type argument '%s' is not a subtype of '%s'\n", 12283 "but type argument '%s' is not a subtype of '%s'\n",
12143 type_param_name.ToCString(), 12284 type_param_name.ToCString(),
12144 class_name.ToCString(), 12285 class_name.ToCString(),
12145 declared_bound_name.ToCString(), 12286 declared_bound_name.ToCString(),
12146 bounded_type_name.ToCString(), 12287 bounded_type_name.ToCString(),
12147 upper_bound_name.ToCString()); 12288 upper_bound_name.ToCString());
12148 } 12289 }
12149 } 12290 }
12150 return false; 12291 return false;
(...skipping 3632 matching lines...) Expand 10 before | Expand all | Expand 10 after
15783 return "_MirrorReference"; 15924 return "_MirrorReference";
15784 } 15925 }
15785 15926
15786 15927
15787 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const { 15928 void MirrorReference::PrintToJSONStream(JSONStream* stream, bool ref) const {
15788 JSONObject jsobj(stream); 15929 JSONObject jsobj(stream);
15789 } 15930 }
15790 15931
15791 15932
15792 } // namespace dart 15933 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/object.h ('k') | runtime/vm/parser.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698