| OLD | NEW |
| 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/parser.h" | 5 #include "vm/parser.h" |
| 6 | 6 |
| 7 #include "vm/bigint_operations.h" | 7 #include "vm/bigint_operations.h" |
| 8 #include "vm/class_finalizer.h" | 8 #include "vm/class_finalizer.h" |
| 9 #include "vm/compiler.h" | 9 #include "vm/compiler.h" |
| 10 #include "vm/compiler_stats.h" | 10 #include "vm/compiler_stats.h" |
| (...skipping 5116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5127 return statement; | 5127 return statement; |
| 5128 } | 5128 } |
| 5129 | 5129 |
| 5130 | 5130 |
| 5131 // Static | 5131 // Static |
| 5132 RawError* Parser::FormatError(const Script& script, | 5132 RawError* Parser::FormatError(const Script& script, |
| 5133 intptr_t token_index, | 5133 intptr_t token_index, |
| 5134 const char* message_header, | 5134 const char* message_header, |
| 5135 const char* format, | 5135 const char* format, |
| 5136 va_list args) { | 5136 va_list args) { |
| 5137 const String& msg = String::Handle( | 5137 const intptr_t kMessageBufferSize = 512; |
| 5138 FormatMessage(script, token_index, message_header, format, args)); | 5138 char message_buffer[kMessageBufferSize]; |
| 5139 FormatMessage(script, token_index, message_header, |
| 5140 message_buffer, kMessageBufferSize, |
| 5141 format, args); |
| 5142 const String& msg = String::Handle(String::New(message_buffer)); |
| 5139 return LanguageError::New(msg); | 5143 return LanguageError::New(msg); |
| 5140 } | 5144 } |
| 5141 | 5145 |
| 5142 | 5146 |
| 5143 static RawString* VFormatMessageHelper(const char* format, va_list args) { | |
| 5144 Zone* zone = Isolate::Current()->current_zone(); | |
| 5145 va_list args2; | |
| 5146 va_copy(args2, args); | |
| 5147 int msg_len = OS::VSNPrint(NULL, 0, format, args2) + 1; | |
| 5148 va_end(args2); | |
| 5149 char* chars = reinterpret_cast<char*>(zone->Allocate(msg_len)); | |
| 5150 OS::VSNPrint(chars, msg_len, format, args); | |
| 5151 return String::New(chars); | |
| 5152 } | |
| 5153 | |
| 5154 | |
| 5155 static RawString* FormatMessageHelper(const char* format, ...) { | |
| 5156 va_list args; | |
| 5157 va_start(args, format); | |
| 5158 const String& result = String::Handle(VFormatMessageHelper(format, args)); | |
| 5159 va_end(args); | |
| 5160 return result.raw(); | |
| 5161 } | |
| 5162 | |
| 5163 | |
| 5164 // Static. | 5147 // Static. |
| 5165 RawString* Parser::FormatMessage(const Script& script, | 5148 void Parser::FormatMessage(const Script& script, |
| 5166 intptr_t token_index, | 5149 intptr_t token_index, |
| 5167 const char* message_header, | 5150 const char* message_header, |
| 5168 const char* format, va_list args) { | 5151 char* message_buffer, |
| 5169 Zone* zone = Isolate::Current()->current_zone(); | 5152 intptr_t message_buffer_size, |
| 5170 String& message = String::Handle(); | 5153 const char* format, va_list args) { |
| 5171 | 5154 intptr_t msg_len = 0; |
| 5172 if (!script.IsNull()) { | 5155 if (!script.IsNull()) { |
| 5173 const String& script_url = String::CheckedHandle(script.url()); | 5156 const String& script_url = String::CheckedHandle(script.url()); |
| 5174 String& msg_part = String::Handle(); | |
| 5175 // Prepend the script to the message with the format "'%s'". | |
| 5176 msg_part = String::New("'"); | |
| 5177 message = String::Concat(msg_part, script_url); | |
| 5178 message = String::Concat(message, msg_part); | |
| 5179 | |
| 5180 if (token_index >= 0) { | 5157 if (token_index >= 0) { |
| 5181 intptr_t line, column; | 5158 intptr_t line, column; |
| 5182 script.GetTokenLocation(token_index, &line, &column); | 5159 script.GetTokenLocation(token_index, &line, &column); |
| 5183 msg_part = FormatMessageHelper(": %s: line %d pos %d: ", | 5160 msg_len += OS::SNPrint(message_buffer + msg_len, |
| 5184 message_header, line, column); | 5161 message_buffer_size - msg_len, |
| 5185 message = String::Concat(message, msg_part); | 5162 "'%s': %s: line %d pos %d: ", |
| 5186 | 5163 script_url.ToCString(), |
| 5187 // Append the formatted error or warning message. | 5164 message_header, |
| 5188 msg_part = VFormatMessageHelper(format, args); | 5165 line, |
| 5189 message = String::Concat(message, msg_part); | 5166 column); |
| 5190 | 5167 if (msg_len < message_buffer_size) { |
| 5191 // Append the source line. | 5168 // Append the formatted error or warning message. |
| 5192 const String& script_line = String::Handle(script.GetLine(line)); | 5169 msg_len += OS::VSNPrint(message_buffer + msg_len, |
| 5193 ASSERT(!script_line.IsNull()); | 5170 message_buffer_size - msg_len, |
| 5194 msg_part = String::New("\n"); | 5171 format, |
| 5195 message = String::Concat(message, msg_part); | 5172 args); |
| 5196 message = String::Concat(message, script_line); | 5173 if (msg_len < message_buffer_size) { |
| 5197 msg_part = FormatMessageHelper("\n%*s\n", column, "^"); | 5174 // Append the source line. |
| 5198 message = String::Concat(message, msg_part); | 5175 const String& script_line = String::Handle(script.GetLine(line)); |
| 5176 ASSERT(!script_line.IsNull()); |
| 5177 msg_len += OS::SNPrint(message_buffer + msg_len, |
| 5178 message_buffer_size - msg_len, |
| 5179 "\n%s\n%*s\n", |
| 5180 script_line.ToCString(), |
| 5181 column, |
| 5182 "^"); |
| 5183 } |
| 5184 } |
| 5199 } else { | 5185 } else { |
| 5200 // Token position is unknown. | 5186 // Token position is unknown. |
| 5201 msg_part = FormatMessageHelper(": %s: ", message_header); | 5187 msg_len += OS::SNPrint(message_buffer + msg_len, |
| 5202 message = String::Concat(message, msg_part); | 5188 message_buffer_size - msg_len, |
| 5203 | 5189 "'%s': %s: ", |
| 5204 // Append the formatted error or warning message. | 5190 script_url.ToCString(), |
| 5205 msg_part = VFormatMessageHelper(format, args); | 5191 message_header); |
| 5206 message = String::Concat(message, msg_part); | 5192 if (msg_len < message_buffer_size) { |
| 5193 // Append the formatted error or warning message. |
| 5194 msg_len += OS::VSNPrint(message_buffer + msg_len, |
| 5195 message_buffer_size - msg_len, |
| 5196 format, |
| 5197 args); |
| 5198 } |
| 5207 } | 5199 } |
| 5208 } else { | 5200 } else { |
| 5209 // Script is unknown. | 5201 // Script is unknown. |
| 5210 // Append the formatted error or warning message. | 5202 // Append the formatted error or warning message. |
| 5211 message = VFormatMessageHelper(format, args); | 5203 msg_len += OS::VSNPrint(message_buffer + msg_len, |
| 5204 message_buffer_size - msg_len, |
| 5205 format, |
| 5206 args); |
| 5212 } | 5207 } |
| 5213 return message.raw(); | |
| 5214 } | 5208 } |
| 5215 | 5209 |
| 5216 | 5210 |
| 5217 void Parser::ErrorMsg(intptr_t token_index, const char* format, ...) { | 5211 void Parser::ErrorMsg(intptr_t token_index, const char* format, ...) { |
| 5218 va_list args; | 5212 va_list args; |
| 5219 va_start(args, format); | 5213 va_start(args, format); |
| 5220 const Error& error = Error::Handle( | 5214 const Error& error = Error::Handle( |
| 5221 FormatError(script_, token_index, "Error", format, args)); | 5215 FormatError(script_, token_index, "Error", format, args)); |
| 5222 va_end(args); | 5216 va_end(args); |
| 5223 Isolate::Current()->long_jump_base()->Jump(1, error); | 5217 Isolate::Current()->long_jump_base()->Jump(1, error); |
| (...skipping 2538 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7762 void Parser::SkipQualIdent() { | 7756 void Parser::SkipQualIdent() { |
| 7763 ASSERT(IsIdentifier()); | 7757 ASSERT(IsIdentifier()); |
| 7764 ConsumeToken(); | 7758 ConsumeToken(); |
| 7765 if (CurrentToken() == Token::kPERIOD) { | 7759 if (CurrentToken() == Token::kPERIOD) { |
| 7766 ConsumeToken(); // Consume the kPERIOD token. | 7760 ConsumeToken(); // Consume the kPERIOD token. |
| 7767 ExpectIdentifier("identifier expected after '.'"); | 7761 ExpectIdentifier("identifier expected after '.'"); |
| 7768 } | 7762 } |
| 7769 } | 7763 } |
| 7770 | 7764 |
| 7771 } // namespace dart | 7765 } // namespace dart |
| OLD | NEW |